ZBLOG

前后端使用base64的方式进行加密和解密

使用 Base64 编码进行数据的加密和解密并不是真正的加密方式,Base64 只是将二进制数据转换为文本格式以便于传输。若要真正实现加密,可以结合 Base64 和对称加密(例如 AES)来进行。

以下是一个示例,展示如何在前端使用 JavaScript 加密明文并生成 Base64 编码,然后在后端用 Java 解密该 Base64 字符串。

1. 前端 JavaScript 代码(使用 AES 加密和 Base64 编码)

async function encrypt(plainText, key) {
    const encoder = new TextEncoder();
    const data = encoder.encode(plainText);

    // 导入 AES 密钥
    const importedKey = await window.crypto.subtle.importKey(
        "raw",
        key,
        { name: "AES-GCM" },
        false,
        ["encrypt"]
    );

    // 使用 AES-GCM 模式进行加密
    const iv = window.crypto.getRandomValues(new Uint8Array(12)); // 随机生成IV
    const encryptedData = await window.crypto.subtle.encrypt(
        {
            name: "AES-GCM",
            iv: iv,
        },
        importedKey,
        data
    );

    // 将 IV 和加密后的数据组合并转为 Base64
    const combinedBuffer = new Uint8Array(iv.byteLength + encryptedData.byteLength);
    combinedBuffer.set(iv);
    combinedBuffer.set(new Uint8Array(encryptedData), iv.byteLength);

    return btoa(String.fromCharCode.apply(null, combinedBuffer)); // 返回 Base64 编码字符串
}

// 示例用法
(async () => {
  // 确保秘钥长度为16个字节(128位)
  const keyMaterial = crypto.getRandomValues(new Uint8Array(16));

  const encryptedText = await encrypt("Hello World", keyMaterial);
  
  console.log("Encrypted (Base64):", encryptedText);
})();

2. 后端 Java 解密代码

import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

public class AESDecryption {

    public static String decrypt(String base64CipherText, byte[] secretKey) throws Exception {
        byte[] decodedBytes = Base64.getDecoder().decode(base64CipherText);
        
        // 提取IV和加密数据,假设IV长度为12字节(96位)
        byte[] iv = new byte[12];
        System.arraycopy(decodedBytes, 0, iv, 0, iv.length); // 前12字节为IV
        
        byte[] cipherText = new byte[decodedBytes.length - iv.length];
        System.arraycopy(decodedBytes, iv.length, cipherText, 0, cipherText.length); 

        SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey, "AES");
        
        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
        
        GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128, iv); // tag length is set to 128 bits
        
        cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, gcmParameterSpec);
        
        byte[] decryptedBytes = cipher.doFinal(cipherText);
        
        return new String(decryptedBytes); 
    }

   public static void main(String[] args) {
      try {
          String base64CipherText = "..."; // 从前端获取的Base64字符串
          byte[] secretKey = ...; // 在此处填入相同的秘密key(16个字节)

          String decryptedText = decrypt(base64CipherText, secretKey);
          System.out.println("Decrypted text: " + decryptedText);
      } catch (Exception e) {
          e.printStackTrace();
      }
   }
}

注意事项:

  1. 安全性:确保选择适当的加密算法和模式,如 AES-GCM,且要随机生成 IV。

  2. 秘钥管理:确保妥善存储秘钥,不应在代码中硬编码。

  3. 字符编码:确认前后端都使用相同字符编码(通常为 UTF-8)。

  4. 异常处理:实际应用中需要添加适当的错误处理机制。

  5. 使用库:在真实项目中推荐使用成熟的库如 Bouncy Castle 来处理复杂的密码学操作,以避免潜在漏洞。

以上就是通过前后端结合使用 AES 加密和 Base64 的方式。如果您有任何进一步的问题,请随时询问!


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=20633

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?