如何转换以下Node的内置加密模块加密 to CryptoJS?
const crypto = require('crypto');
const pass = 'some,password:)with>spec(chars*'
const cipher1 = crypto.createCipher('aes-256-cbc', pass)
const c1 = cipher1.update(input, 'utf8', 'hex') + cipher1.final('hex')
我尝试了类似的方法,但结果并不相同:
const CryptoJS = require('crypto-js');
const pass = 'some,password:)with>spec(chars*'
const cipher2 = CryptoJS.AES.encrypt(input, pass, {
mode: CryptoJS.mode.CBC,
});
const c2 = cipher2.ciphertext.toString(CryptoJS.enc.Hex);
我需要将此用作 Postman 预请求脚本,因为它不支持 Nodecrypto
, but crypto-js
.
两个代码都使用 OpenSSL 专有密钥派生函数EVP_BytesToKey()
迭代计数为 1,MD5 作为摘要。
NodeJS 不使用盐,而 CryptoJS 使用盐random盐。因此,每次加密时 NodeJS 结果都不会改变,而 CryptoJS 结果总是会改变(假设明文和密码相同)。
因此,要使用 CryptoJS 代码获取 NodeJS 代码的结果,您不能使用盐。但是,默认情况下,始终应用盐。这只能通过使用密钥派生函数显式确定密钥和 IV 来规避EvpKDF然后在加密中使用两者:
var input = "The quick brown fox jumps over the lazy dog";
var pass = 'some,password:)with>spec(chars*'
var keySize = 32/4;
var ivSize = 16/4;
var kdf = CryptoJS.algo.EvpKDF.create({ keySize: keySize + ivSize, hasher: CryptoJS.algo.MD5 }).compute(pass, ''); // no salt!
var key = CryptoJS.lib.WordArray.create(kdf.words.slice(0, keySize), keySize * 4);
var iv = CryptoJS.lib.WordArray.create(kdf.words.slice(keySize), ivSize * 4);
var ciphertextCP = CryptoJS.AES.encrypt(input, key, {iv: iv}); // default: CBC, PKCS#7 padding
var ciphertext = ciphertextCP.ciphertext.toString(CryptoJS.enc.Hex);
document.getElementById("ct").innerHTML = ciphertext; // d98cf2d285bf0c1d796226190bf54d9c5540300ee1c6f35618f8bb3564b5053920ec958d31b41bbe4e4880e23543d709
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>
<p style="font-family:'Courier New', monospace;" id="ct"></p>
此 CryptoJS 代码使用与 NodeJS 代码相同的明文和密码短语生成相同的密文。
请注意,密钥推导为EVP_BytesToKey()
并且所选参数已被弃用并被认为是不安全的。由于缺少盐,NodeJS 比 CryptoJS 更是如此。
避免内置密钥导出函数并直接指定密钥会更安全。
为此,请使用createCipheriv()
在 NodeJS 中并将密钥传递为WordArray
在 CryptoJS 代码中。这样,必须为每次加密显式生成随机 IV。
或者,可以使用两个库都支持的可靠密钥派生函数,例如 PBKDF2。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)