Skip to content

前后端加密传输数据

作者:江月迟迟
发表于: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),并将哈希值与加密数据一起发送到后端。后端在解密后重新计算哈希值,验证数据的完整性。

总结

  1. 后端生成RSA密钥对,并将公钥发送给前端。
  2. 前端获取公钥,动态生成AES密钥,并使用公钥加密AES密钥。
  3. 前端使用AES密钥加密数据,并将加密后的AES密钥和数据发送到后端。
  4. 后端使用私钥解密AES密钥,然后使用AES密钥解密数据。
  5. 可选步骤:验证数据的完整性。

通过这种方式,可以有效保护AES密钥的安全性,同时确保数据在传输过程中的加密和完整性。