引言:
加密算法
加密算法是一种用于保护数据安全的数学函数或一组规则,通过特定的加密密钥将明文(原始数据)转换为密文(加密后的数据),以防止未经授权的访问和篡改。加密算法可以分为两大类:对称加密算法和非对称加密算法。
- 对称加密算法:对称加密算法使用相同的密钥进行加密和解密。常见的对称加密算法包括AES(高级加密标准)、DES(数据加密标准)和3DES(三重数据加密标准)。储。
- 非对称加密算法:非对称加密算法使用一对密钥,即公钥和私钥。公钥用于加密,私钥用于解密。常见的非对称加密算法包括RSA、ECC(椭圆曲线加密)和DSA(数字签名算法)。
一、方案一(对称加密AES)
1、特点
安全性高
:AES算法经过了严格的审查和测试,至今未被公开破解。效率高
:AES算法的加密和解密速度较快,适用于各种硬件和软件平台。灵活性强
:AES支持多种密钥长度,包括128位、192位和256位,满足不同安全需求。对称密钥加密
:AES采用对称密钥算法,这意味着加密和解密使用相同的密钥。这简化了加密过程并加快了速度,特别适用于保护大量数据。分组密码方法
:AES使用分组密码方法,将数据分成块(通常为128位)并分别加密每个块。这种结构通过确保每个数据块独立加密来增强安全性。
2、应用场景
通信加密
:广泛应用于通信加密领域,如HTTPS、VPN等,保障通信过程的安全性。数据存储加密
:可应用于数据存储加密,如硬盘加密、数据库加密等,保护存储数据的安全性。数字签名
:可用于数字签名,保障数字证书的安全性。
3、方案实现(spring+vue)
import CryptoJS from "crypto-js"
/**
* AES工具类
* @returns {{encrypt: (function(*): string), decrypt: (function(*): string)}}
* @constructor
*/
const AESUtil = () => {
const SECRET_KEY_ = "xxxxxxxx"
// 解密
const decrypt = (value) => {
// 过滤双引号
const filter = value.replace(/^"|"$/g, '');
let decrypt = CryptoJS.AES.decrypt({ciphertext: CryptoJS.enc.Base64.parse(filter)}, CryptoJS.enc.Base64.parse(SECRET_KEY_), {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7,
});
return decrypt.toString(CryptoJS.enc.Utf8)
};
// 加密
const encrypt = (value) => {
let encrypt = CryptoJS.AES.encrypt(value, CryptoJS.enc.Utf8.parse(SECRET_KEY_), {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
return encrypt.toString()
};
// 测试函数
const asyncTest = async (parameters) => {
// 异步操作
try {
const response = await fetch("/api/encrypted-data");
const value = await response.text();
// 解密数据
const decryptedData = decrypt(value)
console.log("解密后的数据:", JSON.parse(decryptedData))
} catch (error) {
console.error("解密失败:", error)
}
};
return {
decrypt,
encrypt,
};
}
const AES = AESUtil();
export {AES}
/**
* @return {@code String }
* @description: 加密
* @param: [data, key]
* @author: BrownSugar
* @date: 2025-01-10 06:31:59
**/
public static String encrypt(String data, String key) throws Exception {
Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
SecretKeySpec secretKey = new SecretKeySpec(Base64.getDecoder().decode(key), AES_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] encryptedBytes = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(encryptedBytes);
}
/**
* @return {@code String }
* @description: 解密
* @param: [encryptedData, key]
* @author: BrownSugar
* @date: 2025-01-10 06:32:05
**/
public static String decrypt(String encryptedData, String key) throws Exception {
Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
SecretKeySpec secretKey = new SecretKeySpec(Base64.getDecoder().decode(key), AES_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedData));
return new String(decryptedBytes, StandardCharsets.UTF_8);
}
/**
* @return {@code String }
* @description: 生成密钥
* @param: []
* @author: BrownSugar
* @date: 2025-01-10 06:32:09
**/
public static String generateKey() throws Exception {
KeyGenerator keyGen = KeyGenerator.getInstance(AES_ALGORITHM);
keyGen.init(256); // AES 128位密钥
SecretKey secretKey = keyGen.generateKey();
return Base64.getEncoder().encodeToString(secretKey.getEncoded());
}
二、方案二(非对称加密RSA)
1、特点
非对称加密
:RSA是一种非对称加密算法,使用一对密钥(公钥和私钥)进行加密和解密。公钥可以公开,私钥必须保密。安全性高
:RSA通常需要更长的密钥长度(如2048或4096位)才能达到与AES相当的安全性。由于其较短的密钥,AES通常更快,但RSA在安全的密钥交换和数字签名方面非常有用。效率较低
:RSA在加密大量数据时效率较低,通常用于加密小数据传输,例如在SSL/TLS握手中建立安全连接
2、应用场景
密钥交换
:RSA常用于加密对称加密算法(如AES)的密钥,然后将加密后的密钥传输给接收方,接收方使用私钥解密得到对称密钥,后续使用对称密钥进行高效的加密通信。数字签名
:RSA用于数字签名,验证发送者的身份和数据的完整性。
3、方案实现(spring+vue)
import Encrypt from 'encryptlong/bin/jsencrypt.min'
import { Base64 } from 'js-base64';
/**
* RSA工具类
* @returns {{test: test, encrypt: (function(*): string), decrypt: (function(*): string)}}
* @constructor
*/
const RSAUtil = () => {
//公钥
const PUBLIC_KEY = 'xxxx'
//私钥
const PRIVATE_KEY = 'xxxx'
// 加密函数
const encrypt = (value) => {
const enc = new Encrypt();
enc.setPublicKey(PUBLIC_KEY);
value = Base64.encode(value)
return enc.encryptLong(value)
}
// 解密函数
const decrypt = (value) => {
const enc = new Encrypt();
enc.setPrivateKey(PRIVATE_KEY);
let decrypt = enc.decryptLong(value);
return Base64.decode(decrypt)
}
// 测试函数
const test = () => {
let startTime = new Date();
// 使用设置公私钥
const enc = new Encrypt();
enc.setPublicKey(PUBLIC_KEY);
enc.setPrivateKey(PRIVATE_KEY);
// 一段长文本json
let data = {
"code": 200,
"result": [
{"id": 1, "name": "张三", "age": 20 },
{"id": 2, "name": "李四", "age": 21 },
]
};
data = JSON.stringify(data);
let encrypted = enc.encryptLong(data);
let endTime = new Date();
console.log("加密后数据:%o", encrypted);
console.log("加密时间" + (endTime - startTime) + "ms");
//使用私钥解密
let uncrypted = enc.decryptLong(encrypted);
console.log("解密后数据:%o", uncrypted);
}
return {
decrypt,
encrypt,
test,
};
};
const RSA = RSAUtil();
export {RSA}
/** RSA最大加密明文大小 */
private static final int MAX_ENCRYPT_BLOCK = 117;
/** RSA最大解密密文大小 */
private static final int MAX_DECRYPT_BLOCK = 128;
/**
* @return {@code byte[] }
* @description: 加密
* @param: [data, publicKey]
* @author: BrownSugar
* @date: 2025-01-10 06:30:57
**/
public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception {
byte[] keyBytes = Base64.decodeBase64(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
Key publicK = keyFactory.generatePublic(x509KeySpec);
// 对数据加密
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicK);
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段加密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = out.toByteArray();
out.close();
return encryptedData;
}
/**
* @return {@code byte[] }
* @description: 解密
* @param: [data, privateKey]
* @author: BrownSugar
* @date: 2025-01-10 06:31:04
**/
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("RSA");
Key key = keyFactory.generatePrivate(pKCS8EncodedKeySpec);
// 解密数据
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, key);
// SealedObject obj = new SealedObject(data, cipher);
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段解�?
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
cache = cipher.doFinal(data, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedData = out.toByteArray();
out.close();
//byte[] messageBytes = (byte[]) obj.getObject(cipher);
return decryptedData;
}
/**
* @Description: 构建RSA密钥对
* @Param: []
* @Return: RsaKeyPair
* @Author: BrownSugar
* @Date: 2023-03-03 10:55:07
**/
public static RsaKeyPair generateKeyPair() throws NoSuchAlgorithmException {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(1024);
// keyPairGenerator.initialize(2048);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
String publicKeyString = Base64.encodeBase64String(rsaPublicKey.getEncoded());
String privateKeyString = Base64.encodeBase64String(rsaPrivateKey.getEncoded());
return new RsaKeyPair(publicKeyString, privateKeyString);
}
三、总结
特点 | AES | RSA |
---|---|---|
加密类型 | 对称加密 | 非对称加密 |
密钥长度 | 128位、192位、256位 | 2048位、4096位 |
安全性 | 高,难以破解 | 高,但需要更长的密钥 |
效率 | 高,适合大量数据 | 低,适合小数据传输 |
应用场景 | 数据加密、通信加密、数据存储加密 | 密钥交换、数字签名 |
总结:
AES和RSA是目前最为常用的两种加密算法。AES适用于大规模数据的加密和解密,而RSA适用于数字签名和密钥协商等场景。在实际应用中,通常将两者结合使用,利用RSA的安全性进行密钥交换,利用AES的高效性进行数据加密。