key
的UTF-8编码长度仅为31字节
e35417cb037f9911089ec4b94d2360b
网站implicitly通过将0x00
附加到末尾来填充到AES-256所需的32字节长度.
在JavaScript代码中,0x00
的值必须是explicitly:
key = key + "\0";
测试:
let riskLogicKeyTool = {
"vector": "HmK9U6Y8t8seuwI5",
"keySource": "risklogic@#!encrypt"
}
let iv = riskLogicKeyTool.vector;
let key = CryptoJS.SHA256(riskLogicKeyTool.keySource).toString().substring(0, 31);
key = key + "\0"; // Fix!
let newkey = CryptoJS.enc.Utf8.parse(key);
let value = CryptoJS.enc.Utf8.parse("nqsuper+cat@gmail.com");
let newIv = CryptoJS.enc.Utf8.parse(iv)
let newencrypted = CryptoJS.AES.encrypt(value, newkey,
{
iv: newIv,
mode: CryptoJS.mode.CBC, // default
padding: CryptoJS.pad.Pkcs7 // default
});
//console.log(newencrypted);
console.log(newencrypted.toString()); // RBmAWXyJm8d9zV4XaR9BJcLQxTVTM3XEHSHFhGcV75E=
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
Both the website and CryptoJS make it harder to identify the problem because they both accept invalid keys. Valid key lengths for AES are 16, 24 and 32 bytes. In case of invalid key lengths, as here with 31 bytes, an appropriate error message/exception should be generated.
In the case of CryptoJS this is a (known) bug, see issue #293. Care should be taken with crypto websites in general, most are not reliable.
这很奇怪(但当然可以满足您的要求),从十六进制编码的SHA-256散列只使用31个字节,而不是32个字节.因此,仅为完整起见:考虑32字节key
的值为:
e35417cb037f9911089ec4b94d2360bf
网站和JavaScript代码以密文形式返回:
YcJO+j3ID9eLbGkFR+TkVDsaO57y28IcHCLzuHOH4zA=
Security: It is a vulnerability if a fast hash like SHA256 is used as key derivation function. Instead, a reliable key derivation function like PBKDF2 or the more modern scrypt or Argon2 should be used (in combination with a random salt).
Similarly, the use of a static IV is a vulnerability.
In addition, deriving the key from a hex encoded string via UTF-8 encoding reduces security because the range of values per byte is reduced from 256 to 16 values. Also, there may be cross-platform compatibility issues (uppercase, lowercase hex digits).