JS之对密文进行AES加解密

需求:用户ID和用户名不能在传输时同时明文出现

解决方式:后端对用户ID和用户名进行加密,传输后前端解密显示

 

后端的加密方式为:

1.密码转换为字节,先通过PBKDF2WithHmacSHA256,盐值salt123(转换为字节),迭代次数2048次,密钥长度128位,将密码处理成密钥。

2.用AES/GCM/NoPadding的方式对载荷(转换为字节)进行加密,然后IV(字节)会拼在密文的前面,最后对整段字节进行Base64。

 

前端解密JS如下:

一、通过PBKDF2WithHmacSHA256获得密钥

1.导入crypto

import CryptoJS from "crypto-js";

2.对密码进行PBKDF2(Password-Based Key Derivation Function 2)加密,通过加盐、迭代次数、密钥位数,设置哈希算法为SHA256(用于验证),获得密钥。(此password为假)

export const getKeyStr = () => {
  const password = "ii2eezin6Aagh8duboht7zoh7pai";
  const salt = "user-dep";
  const keylen = 128;
  const iterations = 2048;

  const keyStr = CryptoJS.PBKDF2(password, salt, {
    keySize: keylen / 32,
    iterations: iterations,
  });

  sessionStorage.setItem("keyStr", keyStr);
  return keyStr;
}

以上示例代码PBKDF2的默认配置参数为设置哈希算法为SHA256。

 

二、

1.导入node-forge(生成)

import forge from "node-forge";

2.定义十六进制字符串转换为普通字符串的函数

export const hexToString = (hex) => {
  let result = "";
  for (let i = 0; i < hex.length; i += 2) {
    const decimal = parseInt(hex.substr(i, 2), 16);
    result += String.fromCharCode(decimal);
  }
  return result;
};

3.用AES的GCM模式解密密文,密文字符串即someBytes。

export const decryptAESGCM = (someBytes) => {
  someBytes = atob(someBytes);
  const iv = someBytes.slice(0, 12);
  const tag = someBytes.slice(-16);
  const data = someBytes.slice(12, someBytes.length - 16);
  const decipher = forge.cipher.createDecipher(
    "AES-GCM",
    hexToString(sessionStorage.getItem("keyStr") ?? getKeyStr().toString())
  );
  decipher.start({
    iv: iv,
    tag: tag,
  });
  decipher.update(forge.util.createBuffer(data));
  const pass = decipher.finish();
  if (pass) {
    return decipher.output.toString();
  }
};

atob函数是JavaScript中的一个内置函数,用于将base64编码的字符串解码为原始字符串。

在 JavaScript 中,有两个函数被分别用来处理解码和编码 base64 字符串:

atob() //ASCII to Base64
btoa() //Base64 to ASCII

IV是初始化向量的意思。

 

前端加密JS如下:

export const encryptAESGCM = (word) => {
  var iv = forge.random.getBytesSync(12); // 生成随机iv 12字节
  const cipher = forge.cipher.createCipher('AES-GCM', hexToString(sessionStorage.getItem("keyStr") ?? getKeyStr().toString())) // 生成AES-GCM模式的cipher对象 并传入密钥
  cipher.start({
    iv: iv,
  });
  cipher.update(forge.util.createBuffer(forge.util.encodeUtf8(word)));
  cipher.finish();
  var encrypted = cipher.output;
  var tag = cipher.mode.tag;
  return window.btoa(iv + encrypted.data + tag.data);
};

 

posted @ 2024-04-24 09:19  罗毅豪  阅读(81)  评论(0编辑  收藏  举报