密码:IllegalBlockSizeException的原因是什么?

sha*_*ltc 17 java encryption aes

当我使用Cipher时,我观察到以下内容.

加密代码:

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

解密代码:

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

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

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

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());
Run Code Online (Sandbox Code Playgroud)

它工作正常.我明白这是在模式中algorithm/mode/padding.所以我认为这是因为我没有提到填充.所以我尝试在加密过程中给出模式和填充,

加密代码:

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

解密代码:

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

但它失败了IllegalBlockSizeException.

是什么原因,为什么例外以及究竟发生了什么.如果有人可以帮忙吗?提前致谢

UPDATE

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

加密String的长度为64,可被16整除.是的,我在同一台机器上运行它.

密钥生成方法:

    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");
}
Run Code Online (Sandbox Code Playgroud)

Dun*_*nes 9

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

如果密钥或数据无效(但长度正确),你会得到一个,BadPaddingException因为明文中的PKCS#5填充是错误的.偶尔填充看起来是正确的,你也不会有任何例外.


NB我建议你总是指定填充和模式.如果不这样做,如果提供商更改默认值,您可能会感到惊讶.Sun提供商AFAIK转换"AES""AES/ECB/PKCS5Padding".

  • 请注意未来Android开发人员:在API 25(编写本文时),你_can_得到`javax.crypto.IllegalBlockSizeException ...堆栈跟踪...引起:android.security.KeyStoreException:关键用户未经过身份验证当直接使用`SecretKey`从密钥库加载而不是通过验证密钥使用的`CryptoObject`包装器来引用它时. (6认同)

sha*_*ltc 5

虽然我还没有完全理解内部,但我发现了问题所在.

我将加密的字符串作为GET请求参数获取.由于字符串包含不安全的字符,因此请求字符串会被破坏.解决方案是进行URL编码和解码.

我能够使用URLEncoderURLDecoder成功地完成它.

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

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