Raj*_*r D 3 javascript encryption cryptography node.js cryptojs
我们正在尝试匹配 crypto 和 crypto-js 输出。我们的要求是在浏览器中加密字符串,但加密不支持浏览器端加密。因此,我们尝试使用 crypto-js 来匹配输出。每次 crypto-js 都会产生不同的输出。
const crypto = require('crypto');
const CryptoJS = require('crypto-js');
const payload = {
name: 'John Doe'
}
// Node Package
function encryptNode(text) {
const cipher = crypto.createCipher('aes-256-cbc', 'devOps');
return cipher.update(Buffer.from(JSON.stringify(text)), 'utf8', 'hex') + cipher.final('hex');
}
console.log(encryptNode(payload));
// Browser Package
function encryptBrowser(text) {
const ciphertext = CryptoJS.AES.encrypt(JSON.stringify(text), 'devOps', { mode: CryptoJS.mode.CBC });
return ciphertext.toString(CryptoJS.format.Hex);
}
console.log(encryptBrowser(payload));
Run Code Online (Sandbox Code Playgroud)
输出:
加密(预期):dfe03c7e825e9943aa6ec61deb4a8a73fdba0016a13c59c628ce025f39d44c7c
加密js:4e5453abe7bd53d67d88aa4f040356c649fe0101366d05ce4c7d625cfd052cdc
crypto.createCipher并CryptoJS.AES.encrypt利用 OpenSSL-function 的功能EVP_BytesToKey,它需要密码、可选的8 字节盐、摘要和迭代计数,并从这些数据生成密钥和 IV。这两个函数都使用 MD5 摘要和迭代计数 1 作为固定参数。
crypto.createCipher不使用盐,因此每次都会生成相同的密钥和 IV,从而生成相同的密文(假设相同的明文)。
相反,CryptoJS.AES.encrypt每次生成随机盐(此处和此处),以便每次生成不同的密钥和 IV,从而生成不同的密文(即使对于相同的明文)。为了解密(除了密码之外),需要盐,它不是秘密的,可以与密文一起传递(例如在 -object CipherParamsto中CryptoJS.AES.decrypt)。
因此,发布的代码片段的行为符合预期:使用创建的密文crypto.createCipher不会更改,使用创建的密文CryptoJS.AES.encrypt每次都会更改。
EVP_BytesToKey很弱,出于安全原因不应使用(至少在使用 MD5 且迭代计数为 1 时)。这同样适用于crypto.createCipher(由于缺少盐而更是如此),它无论如何都已被弃用,以及 的重载变体CryptoJS.AES.encrypt,它使用EVP_BytesToKey. 这两个库都提供了可以直接传递密钥和 IV 的附加或重载方法(如果需要,可以使用安全过程预先从密码派生)。
| 归档时间: |
|
| 查看次数: |
1571 次 |
| 最近记录: |