当前位置: 首页 > 知识库问答 >
问题:

不同于AES-CTR和AES-GCM生成的密文

翟曦
2023-03-14

为了验证我对AES-GCM和AES-CTR模式的理解,我使用python crpyto.cipher库创建了一个简单的示例。我期待相同的密文从两种模式产生,其中都使用CTR方法。

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

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

代码如下:

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'

共有1个答案

卫博
2023-03-14

问题是维基百科对GCM是如何工作的有点误导。“计数器0”不像CTR中那样是一堆零。它是“前置计数器”块(J0)。如NIST 800-38D所述:

在步骤2中,从IV生成预计数器块(J0)。特别地,当IV的长度为96位时,填充字符串0Ω1被附加到IV上,以形成前置计数器块。否则,用最小数量的“0”位填充IV(可能没有),以便结果字符串的长度是128位的倍数(块大小);这个字符串依次附加了64个额外的'0'位,然后是IV长度的64位表示,并将GHASH函数应用于结果字符串以形成前置计数器块。

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

    null

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

要得到1号柜台:

在步骤3中,32位递增函数被应用于前置计数器块,以产生用于在明文上调用GCTR函数的初始计数器块。

如果对GCM使用一个96位的nonce,并将其与CTR的第三个块进行比较,它们将匹配。

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'  <===
 类似资料:
  • 我有这段代码,它基本上对两条纯文本消息进行加密,然后尝试解密,然后打印。问题是第一条消息恢复得很好,但第二条消息是垃圾。我从本教程下载了这段代码,然后将其修改为使用字符串而不是文件,因为我需要它通过套接字发送加密文本。所以其他endpoint不知道明文的长度,有没有办法找到长度,或者我必须以某种方式将明文的长度与密码一起发送? 现在,我认为解密的中断条件有问题。 另外,main()代码在概念上是否

  • 我不是openssl的专家。我把下面的代码放在一起,使用AES-CTR加密和解密消息。输出不是我期望看到的。 我得到的结果是这样的:“简单:、u∩U└■我的 知道是什么导致的吗?我想做的就是使用AES使用CTR来加密和解密消息。我想得到与纯文本相同的加密长度(或1字节)。我用DES做过这个,但是DES不安全。然后,我将使用AES-CTR加密和解密我的流量(流)。

  • 问题内容: 我在使用CryptoJS解密在Go lang中加密的文本时遇到问题。 这是Go代码:https : //play.golang.org/p/xCbl48T_iN 这是JS代码:http: //jsfiddle.net/Ltkxm64n/ 两者都可以很好地进行加密和解密,但是当我将base64密文从GO复制到JS(反之亦然)时,它不起作用。我还注意到js输出的第一部分与Go输出相同,但是

  • 我正在尝试用Java编写一个简单的密码管理器。我想用AES 256位加密用存储的密码加密文件。此外,我希望用户能够解密的文件与密码。当阅读其他在线帖子时,他们几乎都强调简单地使用密码作为密钥是不安全的,他们提到使用随机盐来增加安全性。但我不明白如何在生成密钥时使用随机盐。如果我从用户的密码和随机的salt创建密钥,那么当他们试图解密他们的文件时,我怎么知道salt是什么呢?这让我完全糊涂了。 目前

  • 我不知道我做错了什么,在这里试图用给定的密钥解密一串十六进制值,使用ruby的OpenSSL密码AES-128-CTR。 我正在使用gem hex_字符串将我的十六进制转换为字节 我知道我遗漏了一些小东西,因为我有类似的代码实现AES-128-CBC。我是否需要一个计数器,为密文中128字节的每一块递增IV?

  • 这是一个错误: 1.JS