参考:https://blog.csdn.net/qq_25623257/article/details/109775531
一、生成秘钥对(公私钥)在线生成地址:http://web.chacuo.net/netrsakeypair
public static void genKeyPair() throws NoSuchAlgorithmException {
// KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
// 初始化密钥对生成器,密钥大小为96-1024位
keyPairGen.initialize(1024,new SecureRandom());
// 生成一个密钥对,保存在keyPair中
KeyPair keyPair = keyPairGen.generateKeyPair();
// 得到私钥
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
// 得到公钥
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
String publicKeyString = new String(base64.encodebase64(publicKey.getEncoded()));
// 得到私钥字符串
String privateKeyString = new String(base64.encodebase64((privateKey.getEncoded())));
// 将公钥和私钥保存到Map
//0表示公钥
keyMap.put(0,publicKeyString);
//1表示私钥
keyMap.put(1,privateKeyString);
}
二、后端加解密
前言:这里使用到base64转码,这里使用 import org.apache.tomcat.util.codec.binary.base64;包下面的,也可以使用阿里支付宝下的 import com.alipay.api.internal.util.codec.base64;。阿里这个需要引入一下jar。
2.1、加密com.alipay.sdk alipay-sdk-java 4.8.10.ALL
public static String encrypt( String str, String publicKey ) throws Exception{
//base64编码的公钥
byte[] decoded = base64.decodebase64(publicKey.getBytes());
RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
//RSA加密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
String outStr = base64.encodebase64String(cipher.doFinal(str.getBytes("gbk")));
return outStr;
}
2.2、解密
public static String decrypt(String str, String privateKey) throws Exception{
//64位解码加密后的字符串
byte[] inputByte = base64.decodebase64(str.getBytes("gbk"));
//base64编码的私钥
byte[] decoded = base64.decodebase64(privateKey.getBytes());
RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
//RSA解密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, priKey);
String outStr = new String(cipher.doFinal(inputByte));
return outStr;
}
2.3、完整代码
package com.rsa;
import org.apache.tomcat.util.codec.binary.base64;
import javax.crypto.Cipher;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
public class RSAEncrypt {
private static Map keyMap = new HashMap();
public static void main(String[] args) throws Exception {
//生成公钥和私钥
// genKeyPair();
keyMap.put(0,"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCeKObHDgyYpbI3W/xpXsFjYkelsnYPL8m5YFUGf7/4VJaPCYYTqbv87UNuXytN1qZKD51g20ECxj+4fYtYCABfUzLcPiJmSVVAFuwjPREtSYN3bxLf/pnThWFj159RcCJCGXGjUVkbJximOaLbfI+e8gHVvQWj7N5FiMM7D7UV9QIDAQAB");
keyMap.put(1,"MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJ4o5scODJilsjdb/GlewWNiR6Wydg8vyblgVQZ/v/hUlo8JhhOpu/ztQ25fK03WpkoPnWDbQQLGP7h9i1gIAF9TMtw+ImZJVUAW7CM9ES1Jg3dvEt/+mdOFYWPXn1FwIkIZcaNRWRsnGKY5ott8j57yAdW9BaPs3kWIwzsPtRX1AgMBAAECgYEAmTekghfhKgvzP2AUgfuyu1XddO8TIhk4giaJmBcwYSGJDZ67Tdcz743mskjuCaU1STAhVVByhX6LAm5VDH4L5McNoW3J/McY3xQ8vTbdtncIMBIORfx4rp599J+8/pWBYe+yfgm6e/48hux6LcvDu8QkrWEmrARsd4mf9d8WLkECQQDPAzwvI2UjAxsOQj5wFJvdX58uW0ZNbax2Z4SMBBGSCox0iIYThXCpD4BwJFEY6HLJQq1MNH90RTnh7aJZWGkRAkEAw5YskRfbTZyrxvnUh0QmeDCKrSprxDOk3s4eUdymfzow646UluyS7/eimHhwU0zir10gCc1gLvfPcEXRjdN+pQJAC2ZZNRtU4XW1UraxK4jnAGzYnjvmhjMI8UhIE1HSCeHM1EoEYCTUDGtPHl3RnXaHg6/JTU4CystZIajtbNAikQJAOlCIMSp/xIA15zmN2FbFcYhnkIHZZ8JOIfAqshWrvrtG4rS8MNOQa+PVosgmFXATFl4Zs1J8nwRb4QmwFS090QJBAMvHjIyv/Dksi7Lk/vD853Y0E8HmBFasj1OrOVaYd002ltyPXle+LI95gqPVHRoWNiLwriRt3IlLolmgQddL4oY=");
//加密字符串
String message = "df723820";
System.out.println("随机生成的公钥为:" + keyMap.get(0));
System.out.println("随机生成的私钥为:" + keyMap.get(1));
String messageEn = encrypt(message,keyMap.get(0));
System.out.println("加密前的字符串为:"+message);
System.out.println("加密后的字符串为:" + messageEn);
String messageDe = decrypt(messageEn,keyMap.get(1));
System.out.println("还原后的字符串为:" + messageDe);
}
public static void genKeyPair() throws NoSuchAlgorithmException {
// KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
// 初始化密钥对生成器,密钥大小为96-1024位
keyPairGen.initialize(1024,new SecureRandom());
// 生成一个密钥对,保存在keyPair中
KeyPair keyPair = keyPairGen.generateKeyPair();
// 得到私钥
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
// 得到公钥
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
String publicKeyString = new String(base64.encodebase64(publicKey.getEncoded()));
// 得到私钥字符串
String privateKeyString = new String(base64.encodebase64((privateKey.getEncoded())));
// 将公钥和私钥保存到Map
//0表示公钥
keyMap.put(0,publicKeyString);
//1表示私钥
keyMap.put(1,privateKeyString);
}
public static String encrypt( String str, String publicKey ) throws Exception{
//base64编码的公钥
byte[] decoded = base64.decodebase64(publicKey.getBytes());
RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
//RSA加密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
String outStr = base64.encodebase64String(cipher.doFinal(str.getBytes("gbk")));
return outStr;
}
public static String decrypt(String str, String privateKey) throws Exception{
//64位解码加密后的字符串
byte[] inputByte = base64.decodebase64(str.getBytes("gbk"));
//base64编码的私钥
byte[] decoded = base64.decodebase64(privateKey.getBytes());
RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
//RSA解密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, priKey);
String outStr = new String(cipher.doFinal(inputByte));
return outStr;
}
}
三、前端加密
3.1、安装依赖并引入方法官网
jsencrypt :http://travistidwell.com/jsencrypt/
encryptlong:https://www.npmjs.com/package/encryptlong
- 安装依赖
npm install jsencrypt --save-dev npm i encryptlong -S
- 引入方法
import JSEncrypt from 'jsencrypt'; // 处理长文本数据时报错 jsencrypt.js Message too long for RSA import Encrypt from 'encryptlong'; // encryptlong是基于jsencrypt扩展的长文本分段加解密功能。3.2、加密
- JSEncrypt加密
rsaPublicData(data) {
var jsencrypt = new JSEncrypt();
jsencrypt.setPublicKey(publicKey);
// 如果是对象/数组的话,需要先JSON.stringify转换成字符串
var result = jsencrypt.encrypt(data);
return result;
},
- 加密
encrypt(data) {
const PUBLIC_KEY = publicKey;
var encryptor = new Encrypt();
encryptor.setPublicKey(PUBLIC_KEY);
// 如果是对象/数组的话,需要先JSON.stringify转换成字符串
const result = encryptor.encryptLong(data);
return result;
},
3.3、解密
- JSEncrypt解密
rsaPrivateData(data) {
var jsencrypt = new JSEncrypt();
jsencrypt.setPrivateKey(privateKey);
// 如果是对象/数组的话,需要先JSON.stringify转换成字符串
var result = jsencrypt.encrypt(data);
return result;
},
- 解密
decrypt(data) {
const PRIVATE_KEY = privateKey;
var encryptor = new Encrypt();
encryptor.setPrivateKey(PRIVATE_KEY);
// 如果是对象/数组的话,需要先JSON.stringify转换成字符串
var result = encryptor.decryptLong(data);
return result;
}
3.4、两种加解密说明
rsaPublicData和 encrypt加密,使用 decrypt都可以解密,但是 JSEncrypt解密目前不能使用。
这两种加密的秘钥不一样。
3.5、完整代码四、解决解密后中文乱码问题加密练习
机密时将加密前的数据转码了,再将转码后的数据加密。加密的时候解密出来了再转码。
4.1、js转码var en = encodeURIComponent("需要转码的数据");
encodeURIComponent:js自带的方法。
- 案例
let pwd = '这是加密的内容2021年12月2日09:28:44';
var en = encodeURIComponent(pwd);
let encoded = this.encrypt(en); // 加密
// 加密后的密文
console.log(encoded);
let decode = this.decrypt(encoded); // 解密
console.log('解密后内容:', decode);
4.2、后端
String result = java.net.URLDecoder.decode("需要转码的数据" ,"UTF-8");



