前言
RSA加密非对称加密,简单理解为就是有一个私钥一个公钥,我们在前台用私钥进行加密,到后台以后再使用对应的公钥进行解密。(这一对公钥和私钥可以由后台实时生成,每次生成的公钥和私钥都不一样,然后后台把私钥传给前段;也可以前后端商量好固定的公钥和私钥自己单独保存。)
公钥和私钥的获取
在本文后端这块的RSAUtils
工具里可以自动生成,这里提供一对,可用的公钥和私钥例子:
也可以用在线网站直接生成
一、前端Vue加密
1、组件模式
1.1安装jsencrypt
npm install jsencrypt
1.2 在src文件夹中的utils中创建jsencrypt.js
1.3 JSEncrypt
/** ***
* RSA加密解密工具类
* **/
import { JSEncrypt } from 'jsencrypt' // 导入
// 公钥和私钥需前后端一致
// 公钥
const publicKey = '获取的公钥'
// 私钥
const privateKey = '获取的私钥'
// 加密
export function encrypt(data) {
const encryptor = new JSEncrypt()
encryptor.setPublicKey(publicKey) // 设置公钥
return encryptor.encrypt(data) // 对需要加密的数据进行加密
}
// 解密
export function decrypt(data) {
const encryptor = new JSEncrypt()
encryptor.setPrivateKey(privateKey)
return encryptor.decrypt(data)
}
1.4 使用方法
import { encrypt } from '../../utils/jsencrypt'
函数中使用
methods: {
rr: function () {
var userId = sessionStorage.getItem('userId')
console.log('加密前:' + userId)
let tt = encrypt(userId)
console.log('加密后:' + tt)
},
2、 直接使用
2.1 安装好后,直接在文件里引用
import { JSEncrypt } from 'jsencrypt';
2.2 使用私钥加密
// 加密
export const encryptedData = function(data) {
//公钥和私钥和后端沟通是固定的
let publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDpZVuOnmdJ8BtR2MknFU4k3LFonjJnub8N1vzERm5l4nFT2dRcQLQoM6NowEgAA3MuTZNJ9ocIhgBGNmmoHCmcTTUe4CPo4SAU+E4pVyzqQEeIydfIhFxb2n7uisgdsaqlQzKzM7NuwAWCCRX+jz2BIBghaGJxgC6LgdYTO3ir8QIDAQAB";
// 新建JSEncrypt对象
let encryptor = new JSEncrypt();
// 设置公钥
encryptor.setPublicKey(publicKey);
var jm_data = encryptor.encrypt(data);
// 加密数据
return jm_data;
}
二、后端解密
2.1 RSAUtils工具类
import lombok.Data;
import org.apache.commons.codec.binary.Base64;
import org.jetbrains.annotations.NotNull;
import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
@Data
public class RSAUtils {
private static final String ALGORITHM = "RSA";
private static final String PUBLIC_KEY = "PUBLIC_kEY";
private static final String PRIVATE_KEY = "PRIVATE_KEY";
// 私钥
public static final String privateKey = "";
// 公钥
public static final String publicKey = "";
/**
* 加密算法
*/
private static final String CIPHER_DE = "RSA";
/**
* 解密算法
*/
private static final String CIPHER_EN = "RSA";
/**
* 密钥长度
*/
private static final Integer KEY_LENGTH = 1024;
/**
* RSA最大加密明文大小
*/
private static final int MAX_ENCRYPT_BLOCK = 117;
/**
* RSA最大解密密文大小
*/
private static final int MAX_DECRYPT_BLOCK = 128;
/**
* 生成秘钥对,公钥和私钥
*
* @return
* @throws NoSuchAlgorithmException
*/
public static Map<String, Object> genKeyPair() throws NoSuchAlgorithmException {
Map<String, Object> keyMap = new HashMap<String, Object>();
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM);
keyPairGenerator.initialize(KEY_LENGTH); // 秘钥字节数
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
keyMap.put(PUBLIC_KEY, publicKey);
keyMap.put(PRIVATE_KEY, privateKey);
return keyMap;
}
/**
* 公钥加密
*
* @param data
* @param publicKey
* @return
* @throws InvalidKeySpecException
*/
public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception {
// 得到公钥
byte[] keyBytes = Base64.decodeBase64(publicKey.getBytes());
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
Key key = keyFactory.generatePublic(x509EncodedKeySpec);
// 加密数据,分段加密
Cipher cipher = Cipher.getInstance(CIPHER_EN);
cipher.init(Cipher.ENCRYPT_MODE, key);
int inputLength = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offset = 0;
byte[] cache;
int i = 0;
while (inputLength - offset > 0) {
if (inputLength - offset > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(data, offset, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offset, inputLength - offset);
}
out.write(cache, 0, cache.length);
i++;
offset = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = out.toByteArray();
out.close();
return encryptedData;
}
/**
* 私钥解密
*
* @param data
* @param privateKey
* @return
* @throws Exception
*/
public static byte[] decryptByPrivateKey(byte[] data, String privateKey) throws Exception {
// 得到私钥
byte[] keyBytes = Base64.decodeBase64(privateKey.getBytes());
PKCS8EncodedKeySpec pKCS8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
Key key = keyFactory.generatePrivate(pKCS8EncodedKeySpec);
// 解密数据,分段解密
Cipher cipher = Cipher.getInstance(CIPHER_DE);
cipher.init(Cipher.DECRYPT_MODE, key);
int inputLength = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offset = 0;
byte[] cache;
int i = 0;
byte[] tmp;
while (inputLength - offset > 0) {
if (inputLength - offset > MAX_DECRYPT_BLOCK) {
cache = cipher.doFinal(data, offset, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offset, inputLength - offset);
}
// out.write(cache, 0, cache.length);
out.write(cache);
i++;
offset = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedData = out.toByteArray();
out.close();
return decryptedData;
}
/**
* 获取公钥
*
* @param keyMap
* @return
*/
public static String getPublicKey(Map<String, Object> keyMap) {
Key key = (Key) keyMap.get(PUBLIC_KEY);
String str = new String(Base64.encodeBase64(key.getEncoded()));
return str;
}
/**
* 获取私钥
*
* @param keyMap
* @return
*/
public static String getPrivateKey(Map<String, Object> keyMap) {
Key key = (Key) keyMap.get(PRIVATE_KEY);
String str = new String(Base64.encodeBase64(key.getEncoded()));
return str;
}
public static void main(String[] args) throws Exception {
Map<String, Object> keyMap = RSAUtils.genKeyPair();
String publicKey = RSAUtils.getPublicKey(keyMap);
String privateKey = RSAUtils.getPrivateKey(keyMap);
System.out.println("公钥:" + publicKey);
System.out.println("私钥:" + privateKey);
// 公钥加密
String sourceStr = "111";
System.out.println("加密前:" + sourceStr);
byte[] encryptStrByte = RSAUtils.encryptByPublicKey(sourceStr.getBytes(), publicKey);
byte[] btt = Base64.encodeBase64(encryptStrByte);
String encryptStr = new String(btt);
System.out.println("加密后:" + encryptStr);
System.out.println("长度:" + encryptStr.length());
// 私钥解密
byte[] decryptStrByte = RSAUtils.decryptByPrivateKey(Base64.decodeBase64(encryptStr), privateKey);
String sourceStr_1 = new String(decryptStrByte);
System.out.println("解密后:" + sourceStr_1);
}
@NotNull
// 传入前端加密的密码,解密后输出
public static String decrypt(String ciphertext) throws Exception {
byte[] bytes = ciphertext.getBytes(StandardCharsets.UTF_8);
byte[] passwordBytes = decryptByPrivateKey(Base64.decodeBase64(bytes), privateKey);
String password = new String(passwordBytes);
return password;
}
}
2.2 调用
String RpaPassword = RSAUtils.decrypt(password);
2.3 RSAUtils运行结果
公钥:MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC0yOa2YFKD9bln6ZFyMk46k6maIFreQQT0p6nS+wEtcF+8yGRUdY6Sdkz40bAudA245mKaNVSjkASN/ZzsQ7VLtG+0MywZ7qP8ownRz0ISLnTjuDpx0PtFcDQX35i7q02NJj0lwm5Z0gHha1StU6weCzaCXhI8B6Ze2Cs1Vn9zFQIDAQAB
私钥:MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALTI5rZgUoP1uWfpkXIyTjqTqZogWt5BBPSnqdL7AS1wX7zIZFR1jpJ2TPjRsC50DbjmYpo1VKOQBI39nOxDtUu0b7QzLBnuo/yjCdHPQhIudOO4OnHQ+0VwNBffmLurTY0mPSXCblnSAeFrVK1TrB4LNoJeEjwHpl7YKzVWf3MVAgMBAAECgYEAikl/CZSmqeBF4bGtmy/V3ULkokwLliUgOFEkO4nbPbnO0eZrsJt34prxiAdGAFKvyHcah6ExzCe3BDIyXhvwyd1rjfICjPG5R3rG/iziwRpwdpxScDKboA8oQEMA85PJKaVFtoG5sPUP+MMmNxmFD0lFQZ8ot3jY+ED3rwTPxSUCQQDja6yOUdrDm7/Wb5moVsOgeQ2NYH0AzcVBb9gyLVb6ii8gnE+Vn92Zklwg8UH7w1cmr6OMCA3JZPuKC9z01+a3AkEAy4DpEAhpLHs3lcfKg3TjtTMe4GWIbMiLZd7cwCuAXVZuPlXgrqWBmAgsfF9AQ+qCUb1G4Y1M1DbU/oKzIPHIkwJAI0GeDrJB5/FNXEEQ4TgSO96Ia1J6DpXX7r0YFy9QPKcPh060R83w3M4D2leMkytFZ4nzINJe0MoG9O/B4XNXIQJBAJHcvjBttuTZFIhZAcCjgasZDyKL4/ME81V7HgLnq0Q7dR1c9IR5wJ+2DBzBMRD8/5eS8UEtxEm/W39pMveEFd0CQC6oEFZvbgddQ8IJYyOpAMx4Wj6JrM2sdjXzHq/UxkaaPnBWIwQpI+9iqtgKcQ5Qjdp5rpLI1+dFYCi+G8f0pH0=
加密前:111
加密后:EDj5Sfl3YrOoimFSD30mIv2j4cLZOyDZOzGvnfH5ulg/s4Hgvtl3g4wzYGyJdlRgDDYE8VGCM7jWTNb4EHLR2KO95fSwOBs7wpULfsYgkNvvbVLEvSnBuM8S7XOVKIg0WB1YqiPyKFqcjf3r1ZlxpU4BahjqYKAFTC6Z0jU3VUU=
长度:172
解密后:111