javascript AES-128-CTR解密在使用crypto和Crypto-JS模块时在节点中给出空字符串输出

06odsfpq  于 2023-09-29  发布在  Java
关注(0)|答案(1)|浏览(137)

我尝试使用crypto-js JavaScript库解密数据,并尝试使用node crypto库在nodejs端加密相同的加密文本。我使用AES 128加密算法与CTR模式。我能够正确加密,但crypto-js模块上的描述不产生相同的纯文本。它给出一个空字符串。
请查看下面的代码示例。

// Encryption using built-in node-js (crypto module)
const crypto = require('crypto');

const encrypt = (plaintext, key, iv) => {
  const cipher = crypto.createCipheriv('aes-128-ctr', key, iv);
  const ciphertext =
    cipher.update(plaintext, 'utf-8', 'hex') + cipher.final('hex');
  return ciphertext;
};
// Decryption using node Crypto-JS module (https://www.npmjs.com/package/crypto-js)

const CryptoJS = require('crypto-js');

const decrypt = (ciphertext, key, iv) => {
  const decipher = CryptoJS.AES.decrypt(
    { ciphertext: CryptoJS.lib.WordArray.create(ciphertext) },
    { key: CryptoJS.lib.WordArray.create(key) },
    { iv: CryptoJS.lib.WordArray.create(iv),
      mode: CryptoJS.mode.CTR,
      padding: CryptoJS.pad.NoPadding, 
    }

  );
  const plaintext = decipher.toString(CryptoJS.enc.Utf8);
  return plaintext;
};

const key = 'b0aad3da3cab2622';
const iv = 'ZGZjMGQ2NjNhYQ==';
const plaintext = 'Hello World';
const ciphertext = encrypt(plaintext, key, iv);
const decryptedText = decrypt(ciphertext, key, iv);
console.log(ciphertext);
console.log(decryptedText);
1sbrub3j

1sbrub3j1#

在CryptoJS代码中,key和IV必须作为WordArray传递,密文作为CipherParams对象传递,例如:

var key = 'b0aad3da3cab2622';
var iv = 'ZGZjMGQ2NjNhYQ==';
var ciphertextHex = '9c494d260c23bb9caa2162';

var keyWA = CryptoJS.enc.Utf8.parse(key);
var ivWA = CryptoJS.enc.Utf8.parse(iv);
var ciphertextWA = CryptoJS.enc.Hex.parse(ciphertextHex);
var ciphertextCP = {ciphertext: ciphertextWA};

const decrypt = (ciphertext, key, iv) => {
    const decipher = CryptoJS.AES.decrypt(
        ciphertext,
        key,
        { 
            iv: iv,
            mode: CryptoJS.mode.CTR,
            padding: CryptoJS.pad.NoPadding, 
        }
    );
    const plaintext = decipher.toString(CryptoJS.enc.Utf8);
    return plaintext;
};

var decrypted = decrypt(ciphertextCP, keyWA, ivWA);
console.log(decrypted); // Hello World
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>

在上面的例子中,ciphertextHex是十六进制编码的密文,它是由NodeJS代码的输入数据产生的。
安全性:
注意,key和IV应对应于值在0x 00和0xFF之间的随机字节序列,并且不应使用字符串(即,没有Base64或十六进制字符串而没有预先解码)。
如果要将字符串用作密钥材料,则必须将密钥导出函数(至少PBKDF 2)与随机盐一起应用于每次加密。
此外,不得使用静态静脉注射。相反,为每个加密生成随机IV。
请注意,CTR和基于CTR的算法的密钥/IV对的重用是一个严重的漏洞。
Salt和IV不是秘密的,并且与密文沿着被传递到解密端(通常是级联的)。
考虑使用GCM模式(基于CTR),因为GCM额外进行身份验证,因此比CTR更安全(不幸的是,CryptoJS不支持GCM,因此必须使用另一个库)。

相关问题