前后端加密传输数据
作者:江月迟迟
发表于:2025-10-29
字数统计:1055 字
预计阅读4分钟
使用非对称加密保护AES密钥的前后端流程可以分为以下几个步骤:
1. 后端生成密钥对
后端生成RSA密钥对(公钥和私钥),并将公钥发送给前端。私钥则由后端安全存储,用于后续解密操作。
示例代码(Java后端):
java
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
public class RSAKeyPairGenerator {
public static KeyPair generateKeyPair() throws Exception {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048); // 使用2048位密钥长度
return keyPairGenerator.generateKeyPair();
}
public static void main(String[] args) throws Exception {
KeyPair keyPair = generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
// 将公钥发送给前端,私钥安全存储
System.out.println("Public Key: " + publicKey);
System.out.println("Private Key: " + privateKey);
}
}2. 前端获取公钥并生成AES密钥
前端通过API从后端获取公钥,然后使用Web Crypto API动态生成AES密钥。
示例代码(前端):
javascript
// 获取公钥
fetch('/api/public-key')
.then(response => response.json())
.then(data => {
const publicKey = data.publicKey;
// 使用Web Crypto API生成AES密钥
crypto.subtle.generateKey(
{ name: "AES-GCM", length: 256 },
true,
["encrypt", "decrypt"]
).then(aesKey => {
// 使用RSA公钥加密AES密钥
return crypto.subtle.importKey(
"spki",
publicKey,
{ name: "RSA-OAEP" },
false,
["encrypt"]
).then(publicKey => {
return crypto.subtle.encrypt(
{ name: "RSA-OAEP" },
publicKey,
aesKey
);
});
}).then(encryptedAesKey => {
// 将加密后的AES密钥发送到后端
fetch('/api/encrypted-key', {
method: 'POST',
body: encryptedAesKey
});
});
});3. 前端使用AES密钥加密数据
前端使用生成的AES密钥对敏感数据进行加密。
示例代码(前端):
javascript
async function encryptData(aesKey, data) {
const iv = crypto.getRandomValues(new Uint8Array(12)); // 生成IV
const encodedData = new TextEncoder().encode(data);
const encryptedData = await crypto.subtle.encrypt(
{ name: "AES-GCM", iv: iv },
aesKey,
encodedData
);
return { encryptedData, iv };
}
// 加密数据并发送到后端
const data = "Sensitive Data";
const encryptedData = await encryptData(aesKey, data);
fetch('/api/encrypted-data', {
method: 'POST',
body: JSON.stringify({
encryptedData: Array.from(new Uint8Array(encryptedData)),
iv: Array.from(iv)
})
});4. 后端解密AES密钥并解密数据
后端使用私钥解密AES密钥,然后使用解密后的AES密钥解密数据。
示例代码(Java后端):
java
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import javax.crypto.Cipher;
public class RSADecryptor {
public static byte[] decrypt(byte[] encryptedData, PrivateKey privateKey) throws Exception {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(encryptedData);
}
public static void main(String[] args) throws Exception {
// 假设从数据库或文件中加载私钥
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
PrivateKey privateKey = KeyFactory.getInstance("RSA").generatePrivate(keySpec);
// 解密AES密钥
byte[] encryptedAesKey = ...; // 从请求中获取加密的AES密钥
byte[] aesKeyBytes = decrypt(encryptedAesKey, privateKey);
// 使用解密后的AES密钥解密数据
// ...
}
}5. 数据完整性验证(可选)
为了确保数据在传输过程中未被篡改,可以在加密数据时生成一个哈希值(如SHA-256),并将哈希值与加密数据一起发送到后端。后端在解密后重新计算哈希值,验证数据的完整性。
总结
- 后端生成RSA密钥对,并将公钥发送给前端。
- 前端获取公钥,动态生成AES密钥,并使用公钥加密AES密钥。
- 前端使用AES密钥加密数据,并将加密后的AES密钥和数据发送到后端。
- 后端使用私钥解密AES密钥,然后使用AES密钥解密数据。
- 可选步骤:验证数据的完整性。
通过这种方式,可以有效保护AES密钥的安全性,同时确保数据在传输过程中的加密和完整性。
