Java AES/GCM/NoPadding加密不会在doFinal之后增加IV的计数器



当我用默认的AES/GCM算法初始化一个Cipher对象时,它有一个reandom 12字节IV,但在调用doFinal并抛出java.lang.IllegalStateException后,前4个字节没有增加:不能对多个加密重复使用相同的密钥和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/随机数,其余用于计数器。前两个计数器值是保留的,因此您最多可以加密2^32-2个块,这就产生了2^39-256个比特,在单个(IV,密钥(对下产生了大约68-GB。

12字节的随机数是NIST 800-38d的标准。如果您提供的nonce不等于12字节,那么它将使用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))

不建议您按照NIST的建议使用基于计数器的IV生成,因为这会使其变得随机。此外,由于GHASH调用,它会使您的加密速度变慢。

当我用默认的AES/GCM算法初始化Cipher对象时,它有一个12字节IV的重随机数,但前4个字节没有增加

这就是预期。对应项再次设置为零。由于您的文件比计数器支持的文件大,您想继续保留它的位置吗?把文件分开做成链条。

  • 此外,请参阅正确使用AES-GCM的规则是什么
  • 无论何时标记不正确,都不要使用纯文本
  • 有一种AES-GCM-SIV模式可以消除(IV,密钥(对的误用。它只泄漏了在相同的IV和密钥下再次发送相同的消息
  • TLS实际上为每条记录使用一个新的(密钥,IV(对,该对最多有2^14字节,这可以防止内存填充攻击。假设你把内存花在68-GB的解密上,那么你就会发现标签是不正确的。不错的DOS服务器攻击点
  • 在可用的情况下,使用ChaCha20-Poly1305比AES-GCM容易得多。不过,它仍然存在(IV,关键(重用问题
  • 有一个XChaCha20使用192位随机数和64位计数器。它可以安全地处理非常大的数据大小和随机随机数

相关内容

最新更新