没有填充的Java AES

时间:2011-09-30 20:28:39

标签: java encryption aes padding

在没有自动填充的情况下,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数据始终是固定长度,并包含自己的填充。如何在不使plain成为32字节的情况下允许encrypted为16个字节?

3 个答案:

答案 0 :(得分:15)

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

    <击>
  1. "AES"更改为"AES/CBC/NoPadding"
  2. decryptor.init(Cipher.DECRYPT_MODE, skeySpec);更改为decryptor.init(Cipher.DECRYPT_MODE, skeySpec, encryptor.gerParameters());
  3. 使用不需要保存初始化向量的方法仅加密16字节数据(固定长度),将"AES"更改为"AES/ECB/NoPadding"

    我选择了ECB,因为that is the default

    如果您需要加密超过16个字节,请考虑使用ECB, which suffers a certain repetition detection flaw

    以外的其他内容

    在这个位图示例中,此图像具有重复的白色块,因此您可以通过查找块变为不同的位置来推断图像的轮廓。

    before encryption encrypted

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

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

答案 1 :(得分:6)

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

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

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

以上非常非常重要,因为使用相同的密钥/ IV组合加密多条消息会破坏安全性。请参阅此Wikipedia文章中的初始化向量(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); 

答案 2 :(得分:2)

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