Dra*_*ian 2 javascript encryption
我正在尝试使用 CryptoJS 加密 32 个字符的字符串:
var string = '12345678901234567890123456789012'.
Run Code Online (Sandbox Code Playgroud)
我使用 AES256 的 32 个字符的密钥:
var key = '12345678901234567890123456789012':
var _key = CryptoJS.enc.Utf8.parse(key);
var encryptedECB = CryptoJS.AES.encrypt(string.trim(), _key, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
}).toString();
Run Code Online (Sandbox Code Playgroud)
我预计加密的 ECB 字符串长度为 44 个字符。相反,它是 64 个字符。我做错了什么?
正如我的评论中已经解释的那样,密文已正确加密:发布的明文长度为 32 字节,是块大小的整数倍(AES 为 16 字节)。本例中使用的PKCS7填充将整个块(16 字节)填充到48字节,从而产生相同长度的密文。CryptoJS.AES.encrypt返回一个CipherParams封装了包括密文在内的各种参数的对象。默认情况下,该toString()方法将密文返回为 Base64 编码字符串,长度为 64 字节 ( 4*ceil(n/3), n=48)。
ECB 模式下的 AES 等分组密码需要长度为块大小整数倍的明文。否则必须使用 PKCS7 等填充。然而,由于发布的 32 字节明文的长度已经对应于块大小的整数倍(32 = 2 * 16 字节),因此也可以省略填充(padding: CryptoJS.pad.NoPadding),从而节省整个块(16 字节)。因此密文与明文的长度相同(32 字节),并变成 Base64 编码的 44 字节(4*ceil(n/3), n=32),这可能是您期望的结果:
var string = '12345678901234567890123456789012';
var key = '12345678901234567890123456789012';
var _key = CryptoJS.enc.Utf8.parse(key);
var encryptedECB = CryptoJS.AES.encrypt(string.trim(), _key, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.NoPadding
}).toString();
console.log(encryptedECB);Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>Run Code Online (Sandbox Code Playgroud)
但请注意,填充对于分组密码来说通常是必需的,并且仅当明文的长度是块大小的整数倍时才可以省略。为了完整起见,应该提到的是,除了效率为 75% 的 Base64 之外,还有其他二进制到文本的编码。还有其他填充(参见此处),但 PKCS7 是可靠的(与零填充相比)。关于安全性:ECB是一种不安全的模式。