如何解决在doFinal之后,Java AES / GCM / NoPadding加密不会增加IV的计数器
当我使用默认的AES / GCM算法初始化一个Cipher对象时,它具有一个随机的12字节IV,但在调用doFinal时前4个字节没有递增,并抛出 java.lang.IllegalStateException:无法重复使用相同的密钥和IV进行多次加密。
SecretKey secretKey = ...
final Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE,secretKey);
byte[] iv1 = encCipher.getIV();
byte[] ctext = encCipher.doFinal("a".getBytes());
cipher.update("b".getBytes());
byte[] iv2 = encCipher.getIV();
ctext = encCipher.doFinal();
解决方法
java.lang.IllegalStateException:无法为多个加密异常重复使用相同的密钥和IV。
这是为了保护您,希望该库至少在同一个Cipher对象下使用时保持这种行为。
AES-GCM内部在CTR模式下使用AES进行加密,对于CTR模式,(密钥,IV)对的重用是婴儿床拖曳导致机密性的灾难性失败。
AES-GCM使用12字节的IV / nonce,其余的用于计数器。前两个计数器值是保留值,因此您最多可以加密2 ^ 32-2个块,这样就可以形成2 ^ 39-256位,并且在单个(IV,密钥)对下可以达到68 GB。
NIST 800-38d标准使用12字节的随机数。如果您提供不等于12字节的随机数,那么它将是processed和GHASH
,之后的大小将是12字节。
if len(IV) = 96 then
J_0 = IV || 0^{31}1
else
J_0=GHASH_H(IV||0^{s+64}||len(IV_64))
不建议您使用counter-based IV generation as suggested by NIST,因为它将使其随机。另外,由于进行了GHASH调用,它会使加密速度变慢。
当我使用默认的AES / GCM算法初始化一个Cipher对象时,它具有一个随机的12字节IV,但是前4个字节没有递增
这是预期的结果。对方再次设置为零。由于文件大于计数器支持,您是否要继续保留它的位置? Divide the file and make chain。
- 此外,请参见What are the rules for using AES-GCM correctly?
- 只要标签不正确,就不要使用纯文本。
- 存在AES-GCM-SIV模式,可以消除对(IV,key)对的滥用。只会泄漏使用相同的IV和密钥再次发送相同的消息。
- TLS实际上为每个记录使用一个新的(密钥,IV)对,该对最多具有2 ^ 14字节,这可以防止内存填充攻击。考虑到您将内存花费在解密68 GB上,那么您已经看到该标签不正确。服务器的不错的DOS攻击点。
- 在可用的情况下,使用ChaCha20-Poly1305比AES-GCM容易得多。但是,它仍然存在(IV,密钥)重用问题。
- 有一个XChaCha20,它使用192位随机数和64位计数器。这样可以安全地处理非常大的数据量和随机数。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。