Javascript CryptoJS AES加密输出长度

Javascript CryptoJS AES加密输出长度,javascript,encryption,Javascript,Encryption,我正在尝试使用CryptoJS加密包含32个字符的字符串: var string = '12345678901234567890123456789012'. 对于AES256,我使用32个字符的键: var key = '12345678901234567890123456789012': var _key = CryptoJS.enc.Utf8.parse(key); var encryptedECB = CryptoJS.AES.encrypt(string.trim(), _key,

我正在尝试使用CryptoJS加密包含32个字符的字符串:

var string = '12345678901234567890123456789012'.
对于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();
我希望encryptedECB字符串长度为44个字符。而是64个字符。
我做错了什么?

正如我在评论中已经解释的那样,密文加密正确:发布的明文长度为32字节,是块大小的整数倍(AES为16字节)。本例中使用的填充将整个块(16个字节)填充到48个字节,从而生成相同长度的密文
CryptoJS.AES.encrypt
返回封装各种参数(包括密文)的对象。默认情况下,
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字符串='1234567890012345678901234567890123456789012';
变量键='1234567890121345678901234567890123456789012';
var\u key=CryptoJS.enc.Utf8.parse(key);
var encryptedcb=CryptoJS.AES.encrypt(string.trim(),_key{
模式:CryptoJS.mode.ECB,
填充:CryptoJS.pad.NoPadding
}).toString();
console.log(encryptedcb)

正如我在评论中所解释的,密文加密正确:发布的明文长度为32字节,是块大小的整数倍(AES为16字节)。本例中使用的填充将整个块(16个字节)填充到48个字节,从而生成相同长度的密文
CryptoJS.AES.encrypt
返回封装各种参数(包括密文)的对象。默认情况下,
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字符串='1234567890012345678901234567890123456789012';
变量键='1234567890121345678901234567890123456789012';
var\u key=CryptoJS.enc.Utf8.parse(key);
var encryptedcb=CryptoJS.AES.encrypt(string.trim(),_key{
模式:CryptoJS.mode.ECB,
填充:CryptoJS.pad.NoPadding
}).toString();
console.log(encryptedcb)

我希望encryptedECB字符串长度为44个字符。为什么?我做错了什么?没有什么。您的明文长度为32字节。使用PKCS7填充,填充一个完整的块(16字节),即48字节
.toString()
对密文进行Base64编码,产生一个64字节的字符串(
4*ceil(n/3)
n=48
)。@Topaco感谢您的回答。是否有其他填充或其他解决方案来最小化输出长度?是的,请参阅我的答案。我希望encryptedECB字符串长度为44个字符。为什么?我做错了什么?没有什么。您的明文长度为32字节。使用PKCS7填充,填充一个完整的块(16字节),即48字节
.toString()
对密文进行Base64编码,产生一个64字节的字符串(
4*ceil(n/3)
n=48
)。@Topaco感谢您的回答。是否有其他填充或其他解决方案来最小化输出长度?是的,请参阅我的答案。非常感谢,添加正是我想要的。另外,你给了我另一个有价值的想法,使用其他二进制文本编码。搜索你的链接时,我注意到有一个Base85,它将一个32个字符的字符串编码为一个40个字符的输出字符串。但是CryptoJS不支持Base85……还有其他解决方案吗?CryptoJS支持二进制到文本的十六进制编码和Base64编码(),但不支持不太常见的编码。如果你想使用这种编码,你需要找到一个合适的JavaScript库(也许是这个,但我还没有测试过!)。还请记住,CryptoJS使用
WordArray
类型,因此通常需要转换为库使用的数据类型(例如typed arraya、
ArrayBuffer
等)。非常感谢,我不想添加。另外,你给了我另一个有价值的想法,使用其他二进制文本编码。搜索你的链接时,我注意到有一个Base85,它将一个32个字符的字符串编码为一个40个字符的输出字符串。但是CryptoJS不支持Base85……还有其他解决方案吗?CryptoJS支持二进制到文本的十六进制编码和Base64编码(),但不支持不太常见的编码。如果你想使用这种编码,你需要找到一个合适的JavaScript库(也许是这个,但我还没有测试过!)。还请记住,CryptoJS使用
WordArray
类型,因此通常需要转换为库使用的数据类型(例如typed arraya、
ArrayBuffer
等)。