为什么在AES/CBC/ZeroBytePadding中使用Android和JavaScript进行加密会对某些字符串返回不同的结果?

为什么在AES/CBC/ZeroBytePadding中使用Android和JavaScript进行加密会对某些字符串返回不同的结果?,javascript,android,encryption,aes,Javascript,Android,Encryption,Aes,以下是JavaScript中的代码: <html> <head> <script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js"></script> <script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/components/pad-zeropadding-min.j

以下是JavaScript中的代码:

<html>
<head>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js"></script>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/components/pad-zeropadding-min.js"></script>
<!-- jquery -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
</head>
<body>
<div id="0"></div>
<div id="1"></div>
<div id="2"></div>
<script>

var key = CryptoJS.enc.Utf8.parse('32_length_String');
var iv  = CryptoJS.enc.Utf8.parse('32_length_String');
var message = '{"login":[{"username":"25697","passwd":"asdf"}]}';
$('#0').text("Message: "+message);

var encrypted = CryptoJS.AES.encrypt(message, key, { iv: iv, padding: CryptoJS.pad.ZeroPadding, mode: CryptoJS.mode.CBC});
$('#1').text("Encrypted BASE64: "+encrypted);
$('#2').text("Encrypted HEX: "+encrypted.ciphertext);
</script>
</body>
</html>
Android代码返回十六进制:

c88928b4542a8faa774f27670c563fdfcb8dcc8ae554d3dd05a86ac7869d91d36a170a4e093b75e2702e8374f206e7f4
C88928B4542A8FAA774F27670C563FDFCB8DCC8AE554D3DD05A86AC7869D91D36A170A4E093B75E2702E8374F206E7F4DF33A2FBEE7FD2DBC1ED0430F3E45DCF
这两个十六进制是相似的,但在android代码的末尾添加了更多字符,加密了其他字符串,如:
{“登录”:[{“用户名”:“25697”,“密码”:“asd”}}

{“login”:[{“username”:“25697”,“passwd”:“asdfg”}]}
返回相同的十六进制。我找不到Android代码中有什么错误,为什么会发生这种情况。

问题是,Android基于BouncyCastle的ZeroBytePadding将始终添加填充,但CryptoJS不会

AES是一种分组密码,因此只能对16字节的完整块进行操作。CryptoJS的零填充将只添加如此多的0x00字节,直到达到块大小的倍数。另一方面,Android的ZerBytePadding也会这样做,但是如果明文已经是块大小的倍数,那么它将添加一个0x00字节的完整块

在您的例子中,第一个明文是48字节,这意味着ZeroBytePadding将添加一个额外的块

安卓的密码是基于BouncyCastle的,它是,为什么BouncyCastle这样做。它不会被“修复”

我建议您使用PKCS#5/PKCS#7填充(它们是相同的),这使您能够在纯文本的末尾使用have 0x00字节,这在零填充中是不可能的



不要忘记,您应该通过使用消息身份验证代码来防止对密文的操纵。例如,使用HMAC-SHA256对具有不同密钥的密文进行加密。

I仅使用前16个字节的字节[]iv=Arrays.copyOf(iv.getBytes(“UTF-8”),16;有没有什么方法可以像android中的Javascript那样使用零填充?您可以检查
url.getBytes(“UTF-8”).length%16==0
在这种情况下,您只需扔掉最后一个块:
encryptedText=Arrays.copyOf(encryptedText,encryptedText.length-16)。但是如果你以后想在安卓系统中解密,你可能无法做到。你为什么这么喜欢零填充?PKCS5Padding更好。我的客户正在使用ZeroPadding。不,我的决定,谢谢你的建议
C88928B4542A8FAA774F27670C563FDFCB8DCC8AE554D3DD05A86AC7869D91D36A170A4E093B75E2702E8374F206E7F4DF33A2FBEE7FD2DBC1ED0430F3E45DCF