gpt4 book ai didi

python-3.x - AES-CTR 和 AES-GCM 生成的不同密文

转载 作者:行者123 更新时间:2023-12-04 02:30:26 25 4
gpt4 key购买 nike

为了验证我对 AES-GCM 和 AES-CTR 模式的理解,我正在使用 python Crpyto.Cipher 库创建一个简单示例。我期望从两种模式生成相同的密文,这两种模式都使用 CTR 方法。

由于我的目的只是比较来自加密引擎的加密结果,因此,我将 GCM 和 CTR 的消息都设置为全 0(十六进制格式)。任何与 0 的 XOR 都将保留为原始密文。

在 AES-CTR 方面,我将随机数设置为“00”。这意味着不会使用随机数,默认情况下计数器编号将从值 0 开始。

在 AES-GCM 端,我将随机数 (IV) 设置为 16 字节“00”。我假设这相当于计数器的 0 起始值。

看下面的 AES-GCM 框图,我应该从 AES-GCM 得到的第一个密文应该只是计数器值 1 的加密结果。

但是,我无法从 AES-CTR 和 AES-GCM 获得相同的加密结果。请赐教我哪一部分出错了?最后,我对两种加密模式使用相同的 256-AES-key。

enter image description here

代码如下:

key  = bytes.fromhex('0123456789ABCDEF11113333555577770123456789ABCDEF1111333355557777')
msg = bytes.fromhex('00000000000000000000000000000000')
msg1 = bytes.fromhex('00000000000000000000000000000001')

###### AES-256 ECB Mode ######
aes1 = AES.new(key,AES.MODE_ECB)
print("AES-ECB Result, Counter 1: "+str(binascii.hexlify(aes1.encrypt(msg1)))+"\n")

###### AES-256 CTR Mode ######
aes1 = AES.new(key,AES.MODE_CTR,nonce=bytes.fromhex('00'))
print("AES-CTR Result, Counter 0: "+str(binascii.hexlify(aes1.encrypt(msg))))
print("AES-CTR Result, Counter 1: "+str(binascii.hexlify(aes1.encrypt(msg)))+"\n")

###### AES-256 GCM Mode ######
aes1 = AES.new(key, AES.MODE_GCM, nonce=bytes.fromhex('00000000000000000000000000000000'))
ciphertext, authTag = aes1.encrypt_and_digest(msg)
print("AES-GCM Result, Counter 0: "+str(binascii.hexlify(ciphertext)))
print("AES-GCM Initialization Vector: "+str(binascii.hexlify(aes1.nonce)))

Python 结果:

AES-ECB Result, Counter 1: b'24c82c75b5546a77d20c9868503767b4'

AES-CTR Result, Counter 0: b'4a85984511e5ca3f03297d84c69584c4'
AES-CTR Result, Counter 1: b'24c82c75b5546a77d20c9868503767b4'

AES-GCM Result: b'dfff0d463d8254d7eb23887729b22a85'
AES-GCM Initialization Vector: b'00000000000000000000000000000000'

最佳答案

问题是维基百科对 GCM 的工作原理有点误导。 “计数器 0”不像 CTR 中那样是一串零。它是“预计数器” block (J0)。如 NIST 800-38d 中所述:

In Step 2, the pre-counter block (J0) is generated from the IV. In particular, when the length of the IV is 96 bits, then the padding string 0³¹||1 is appended to the IV to form the pre-counter block. Otherwise, the IV is padded with the minimum number of ‘0’ bits, possibly none, so that the length of the resulting string is a multiple of 128 bits (the block size); this string in turn is appended with 64 additional ‘0’ bits, followed by the 64-bit representation of the length of the IV, and the GHASH function is applied to the resulting string to form the pre- counter block.

在您的示例中,您传递了一个 128 位 block ,因此:

  • 不附加填充(它已经是 128 位)
  • 追加8个字节的0
  • 附加 IV 的长度 (16):0x0000000000000010

然后通过 GHASH 函数运行所有这些。这给你 J0,在图形上称为“计数器 0”。

获取计数器 1:

In Step 3, the 32-bit incrementing function is applied to the pre-counter block to produce the initial counter block for an invocation of the GCTR function on the plaintext.

32 位递增函数基本上意味着“递增最右边的 32 位”。

这就是输入 AES 的内容。这将是非常随机的,当然不像您的点击率案例中的“1”。这样做允许任意长度的随机数。

但还有另一种特殊情况:GCM 的 96 位随机数,这是推荐的配置。在那种情况下,J0 就简单多了。它只是附加了 32 位 01 的随机数。这是通过增量函数传递的,这意味着“第一个” block 将是 02。

如果您对 GCM 使用 96 位随机数,并将其与 CTR 的第三个 block 进行比较,它们将匹配。

aes1 = AES.new(key,AES.MODE_CTR,nonce=bytes.fromhex('000000000000000000000000000000'))
print("AES-CTR Result, Counter 0: "+str(binascii.hexlify(aes1.encrypt(msg))))
print("AES-CTR Result, Counter 1: "+str(binascii.hexlify(aes1.encrypt(msg))))
print("AES-CTR Result, Counter 2: "+str(binascii.hexlify(aes1.encrypt(msg)))+"\n")

aes1 = AES.new(key, AES.MODE_GCM, nonce=bytes.fromhex('000000000000000000000000'))
print("AES-GCM Result, Counter 0: "+str(binascii.hexlify(aes1.encrypt(msg))))

==>

AES-CTR Result, Counter 0: b'4a85984511e5ca3f03297d84c69584c4'
AES-CTR Result, Counter 1: b'24c82c75b5546a77d20c9868503767b4'
AES-CTR Result, Counter 2: b'c8f656193e3bb5b6117d49e3c6799864' <===

AES-GCM Result, Counter 0: b'c8f656193e3bb5b6117d49e3c6799864' <===

关于python-3.x - AES-CTR 和 AES-GCM 生成的不同密文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64565666/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com