java 密码:IllegalBlockSizeException 的原因是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16192140/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 22:10:34  来源:igfitidea点击:

Cipher: What is the reason for IllegalBlockSizeException?

javaaesencryption

提问by shazinltc

I have observed the following when I worked with Cipher.

我在使用Cipher时观察到以下内容。

Encryption code:

加密代码:

Cipher aes = Cipher.getInstance("AES");
aes.init(Cipher.ENCRYPT_MODE, generateKey());
byte[] ciphertext = aes.doFinal(rawPassword.getBytes());

Decryption code :

解密代码:

Cipher aes = Cipher.getInstance("AES");
aes.init(Cipher.DECRYPT_MODE, generateKey());
byte[] ciphertext = aes.doFinal(rawPassword.getBytes());

I get IllegalBlockSizeException ( Input length must be multiple of 16 when ...) on running the Decrypt code.

在运行解密代码时,我收到 IllegalBlockSizeException (输入长度​​必须是 16 的倍数...)。

But If I change the decrypt code to

但是如果我将解密代码更改为

Cipher aes = Cipher.getInstance("AES/ECB/PKCS5Padding"); //I am passing the padding too
aes.init(Cipher.DECRYPT_MODE, generateKey());
byte[] ciphertext = aes.doFinal(rawPassword.getBytes());

It works fine. I understand that it is in the pattern algorithm/mode/padding. So I thought it is because I didn't mention the padding. So I tried giving mode and padding during encryption,

它工作正常。我知道它在模式中algorithm/mode/padding。所以我认为是因为我没有提到填充。所以我尝试在加密期间提供模式和填充,

Encryption code:

加密代码:

Cipher aes = Cipher.getInstance("AES/ECB/PKCS5Padding");//Gave padding during encryption too
aes.init(Cipher.ENCRYPT_MODE, generateKey());
byte[] ciphertext = aes.doFinal(rawPassword.getBytes());

Decryption code :

解密代码:

Cipher aes = Cipher.getInstance("AES/ECB/PKCS5Padding");
aes.init(Cipher.DECRYPT_MODE, generateKey());
byte[] ciphertext = aes.doFinal(rawPassword.getBytes());

But it fails with IllegalBlockSizeException.

但它因 IllegalBlockSizeException 而失败。

What is the reason, why the exception and what is exactly happening underneath. If anyone can help? Thanks in advance

原因是什么,为什么会出现异常以及到底发生了什么。如果有人可以帮忙吗?提前致谢

UPDATE

更新

Looks like the issue is with the string I am encrypting and decrypting. Because, even the code that I said works, doesn't always work. I am basically encrypting UUIDs (eg : 8e7307a2-ef01-4d7d-b854-e81ce152bbf6). It works with certain strings and doesn't with certain others.

看起来问题出在我正在加密和解密的字符串上。因为,即使我说的代码有效,也并不总是有效。我基本上是在加密 UUID(例如:8e7307a2-ef01-4d7d-b854-e81ce152bbf6)。它适用于某些字符串,不适用于某些其他字符串。

The length of encrypted String is 64 which is divisible by 16. Yes, I am running it on the same machine.

加密字符串的长度是 64,可以被 16 整除。是的,我在同一台机器上运行它。

Method for secret key generation:

秘钥生成方法:

    private Key generateKey() throws NoSuchAlgorithmException {
    MessageDigest digest = MessageDigest.getInstance("SHA");
            String passphrase = "blahbl blahbla blah";
    digest.update(passphrase.getBytes());
    return new SecretKeySpec(digest.digest(), 0, 16, "AES");
}

采纳答案by Duncan Jones

During decryption, one can onlyget an IllegalBlockSizeExceptionif the input data is not a multiple of the block-size (16 bytes for AES).

在解密期间,如果输入数据不是块大小的倍数(AES 为 16 字节),则只能得到一个IllegalBlockSizeException

If the key or the data was invalid (but correct in length), you would get a BadPaddingExceptionbecause the PKCS #5 padding would be wrong in the plaintext. Very occasionally the padding would appear correct by chance and you would have no exception at all.

如果密钥或数据无效(但长度正确),您会得到 a,BadPaddingException因为明文中的 PKCS #5 填充是错误的。偶尔填充会偶然出现正确,您根本不会有任何例外。



N.B. I would recommend you always specify the padding and mode. If you don't, you are liable to be surprised if the provider changes the defaults. AFAIK, the Sun provider converts "AES"to "AES/ECB/PKCS5Padding".

注意,我建议您始终指定填充和模式。如果不这样做,如果提供者更改默认值,您可能会感到惊讶。AFAIK,Sun 提供程序转换"AES""AES/ECB/PKCS5Padding".

回答by shazinltc

Though I haven't fully understood the internals, I have found what the issue is.

虽然我还没有完全理解内部结构,但我已经找到了问题所在。

I fetch the encrypted string as a GET request parameter. As the string contains unsafe characters, over the request the string gets corrupted. The solution is, to do URL encoding and decoding.

我获取加密的字符串作为 GET 请求参数。由于字符串包含不安全的字符,因此在请求时字符串会损坏。解决办法是,做URL的编解码。

I am able to do it successfully using the URLEncoderand URLDecoder.

我能够使用URLEncoderURLDecoder成功地做到这一点。

Now the results are consistent. Thanks :)

现在结果是一致的。谢谢 :)

I would be grateful if anyone can contribute more to this.

如果有人能为此做出更多贡献,我将不胜感激。