没有填充的Java AES

在没有自动填充的情况下,AES加密和解密16字节数组有哪些最简单的方法? 我找到了使用外部库的解决方案,但我希望尽可能避免这种情况。

我目前的代码是

SecretKeySpec skeySpec = new SecretKeySpec(getCryptoKeyByteArray(length=16)); // 128 bits Cipher encryptor = Cipher.getInstance("AES"); encryptor.init(Cipher.ENCRYPT_MODE, skeySpec); byte[] encrypted = encryptor.doFinal(plain); 

如何防止填充? plain数据总是固定长度并包含自己的填充。 如何在不使encrypted成为32字节的情况下允许plain为16字节?

看我的评论。 对不起,我可能应该第一次仔细看看。

  1. "AES"更改为"AES/CBC/NoPadding"
  2. 更改decryptor.init(Cipher.DECRYPT_MODE, skeySpec); to decryptor.init(Cipher.DECRYPT_MODE, skeySpec, encryptor.gerParameters());

要使用不需要保存初始化向量的方法仅加密16字节数据(固定长度), "AES/ECB/NoPadding" "AES"更改为"AES/ECB/NoPadding"

我选择ECB是因为这是默认值 。

如果您需要加密超过16个字节,请考虑使用ECB之外的其他东西,这会遇到一定的重复检测缺陷

在此位图示例中,此图像具有重复的白色块,因此您只需查找块变为不同的位置即可推断出图像的轮廓。

在加密之前加密

如果您只加密一个块,那么它并不重要,只有当您加密多个块时,ECB才能显示出来。

相关: https : //security.stackexchange.com/questions/15740/what-are-the-variables-of-aes

同意@rossum,但还有更多内容:

CTR模式需要初始化矢量(IV)。 这是一个“计数器”(这是“CTR”所指的)。 如果您可以单独存储IV(它不需要保护)可以工作。 解密数据时,您需要相同的IV值。

如果您不想存储IV,并且可以保证不会使用相同的密钥加密任何两个值 ,则可以使用固定的IV(甚至是0的数组)。

上述内容非常重要,因为使用相同的密钥/ IV组合加密多个消息会破坏安全性。 请参阅此维基百科文章中的初始化向量(IV)部分: http : //en.wikipedia.org/wiki/Block_cipher_modes_of_operation

您的代码的AES CTR实现可能是:

 SecretKeySpec skeySpec = new SecretKeySpec(getCryptoKeyByteArray(length=16)); Cipher encryptor = Cipher.getInstance("AES/CTR/NoPadding"); // Initialisation vector: byte[] iv = new byte[encryptor.getBlockSize()]; SecureRandom.getInstance("SHA1PRNG").nextBytes(iv); // If storing separately IvParameterSpec ivParameterSpec = new IvParameterSpec(iv); encryptor.init(Cipher.ENCRYPT_MODE, skeySpec, ivParameterSpec); byte[] encrypted = encryptor.doFinal(plain); 

CTR模式不需要填充: "AES/CTR/NoPadding"