
如图所示,这里就不写 Redis 了,只展示 React 前端及 Springboot 后端加密代码
一、首先是 React 组件
AES 对称加密
import CryptoJS from 'crypto-js';
function validateKey(key) {
const keyBytes = CryptoJS.enc.Base64.parse(key);
const keyLength = keyBytes.sigBytes;
if (keyLength !== 32) {
throw new Error('Invalid key length. Key must be 32 bytes long.');
}
console.log(keyBytes)
return keyBytes;
}
/**
* 加密
* @param {string} message - 需要加密的消息
* @param {string} key - 加密密钥 (Base64 编码)
*/
function AESEncrypt(message, key) {
const keyBytes = validateKey(key);
const encrypted = CryptoJS.AES.encrypt(message, keyBytes, {
mode: CryptoJS.mode.ECB1,
padding: CryptoJS.pad.Pkcs7
});
console.log('Encrypted:', encrypted.toString());
return encrypted.toString();
}
/**
* 解密
* @param {string} encryptedMessage - 加密后的消息
* @param {string} key - 解密密钥 (Base64 编码)
*/
function AESDecrypt(encryptedMessage, key) {
try {
const wordArrayKey = validateKey(key);
const decrypted = CryptoJS.AES.decrypt(encryptedMessage, wordArrayKey,{
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
return decrypted.toString(CryptoJS.enc.Utf8);
} catch (error) {
console.error('Decryption error:', error);
return null;
}
}
export { AESEncrypt, AESDecrypt };
RSA 非对称加密
import JSEncrypt from 'jsencrypt';
//生成 RSA 密钥对
function generateRSAKeyPair() {
const encrypt = new JSEncrypt();
encrypt.getKey();
const privateKey = encrypt.getprivateKey();
const publicKey = encrypt.getpublicKey();
return { publicKey: publicKey, privateKey: privateKey };
}
// 公钥加密
function RSAEncrypt(text, publicKey) {
const encrypt = new JSEncrypt();
encrypt.setpublicKey(publicKey);
const encrypted = encrypt.encrypt(text);
return encrypted;
}
// 私钥解密
function RSADecrypt(text, privateKey) {
const decrypt = new JSEncrypt();
decrypt.setprivateKey(privateKey);
const decrypted = decrypt.decrypt(text);
return decrypted;
}
export { generateRSAKeyPair, RSAEncrypt, RSADecrypt }
二、接着是 Springboot 后端
AES 对称加密
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
/**
* 对称加密
*/
public class AESUtils {
/**
* 生成 AES 密钥
*
* @return 生成的 AES 密钥
* @throws NoSuchAlgorithmException 如果没有提供 AES 算法实现
*/
public static SecretKey generateAESKey() throws NoSuchAlgorithmException {
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(256); // 生成 256 位的密钥
return keyGen.generateKey();
}
/**
* 将 SecretKey 转换为 Base64 编码的字符串
*
* @param secretKey 要转换的 SecretKey
* @return 转换后的 Base64 编码字符串
*/
public static String getSecretKeyString(SecretKey secretKey) {
return Base64.getEncoder().encodeToString(secretKey.getEncoded());
}
/**
* 使用 AES 算法加密文本
*
* @param text 要加密的文本
* @param secretKeyStr Base64 编码的 AES 密钥字符串
* @return 加密后的字符串
* @throws Exception 如果加密过程中发生错误
*/
public static String aesEncrypt(String text, String secretKeyStr) throws Exception {
byte[] decodedKey = Base64.getDecoder().decode(secretKeyStr.getBytes());
SecretKeySpec secretKeySpec = new SecretKeySpec(decodedKey, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
byte[] encryptedBytes = cipher.doFinal(text.getBytes());
return Base64.getEncoder().encodeToString(encryptedBytes);
}
/**
* 使用 AES 算法解密文本
*
* @param encryptedText Base64 编码的加密文本
* @param secretKeyStr Base64 编码的 AES 密钥字符串
* @return 解密后的字符串
* @throws Exception 如果解密过程中发生错误
*/
public static String aesDecrypt(String encryptedText, String secretKeyStr) throws Exception {
byte[] decodedKey = Base64.getDecoder().decode(secretKeyStr);
SecretKeySpec secretKeySpec = new SecretKeySpec(decodedKey, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
byte[] encryptedBytes = Base64.getDecoder().decode(encryptedText);
byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
return new String(decryptedBytes,StandardCharsets.UTF_8);
}
}
RSA 非对称加密
package com.example.SuperChain.util;
import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
public class RSAUtils {
public static String rsaEncrypt(String text, String publicKeyStr) throws Exception {
// 去掉 PEM 格式的头尾注释行和换行符
String cleanedPublicKeyStr = publicKeyStr
.replace("-----BEGIN PUBLIC KEY-----", "")
.replace("-----END PUBLIC KEY-----", "")
.replaceAll("\\s+", ""); // 移除所有空格和换行符2
byte[] encodedKey = Base64.getDecoder().decode(cleanedPublicKeyStr);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encodedKey);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(keySpec);
// 加密操作
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encryptedBytes = cipher.doFinal(text.getBytes());
return Base64.getEncoder().encodeToString(encryptedBytes);
}
}
三、注意
在进行加解密前,数据必须转换为 String 字符串形式
- 这里与其他的高亮文本对应,这些前后端加解密设置无论怎样改,都必须保证一致 ↩︎
- 这是由于前端生成的公钥为-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDIOtoV7nNGe6acqP3KySw/mNZG\nx77j5Q9fD102aVifcag5SMv8JW7V/8t+5tNrmeFuP4fRu3WC+/pJBGCjpI7KDAnO\nKfIrHfK6tKTzmlweiwDcnCY9UWVXz43b186NMn8r1aw/m1TrLzrwegGbtOR8oJ+g\n5U6jO6LnRhEVKYs83wIDAQAB\n-----END PUBLIC KEY-----的格式,所以需要去除头尾信息和换行符 ↩︎
Comments NOTHING