AES 您所在的位置:网站首页 aes算法安全吗 AES

AES

2024-07-08 10:07| 来源: 网络整理| 查看: 265

文章目录 CTR(Counter mode,CTR)计数器模式题目一题目描述:题目分析: 浅记一下

CTR(Counter mode,CTR)计数器模式

原理: CTR将块密码变为流密码。它通过递增一个加密计数器以产生连续的密钥流,其中,计数器可以是任意保证长时间不产生重复输出的函数。AES是一种分组加密模式,其中CTR(计数模式)是其中一种工作模式。

加密原理:用密钥对输入的计数器加密,然后同明文异或得到密文。 解密原理:用密钥对输入计数器加密,然后同密文异或得到明文。 ⋆ ⋆ ⋆ 从图中可以看出对计数器的加密 ( 即从 C o u n t e r ⇒ K 1 的过程 ) 采用的是 A E S − E C B 加密模式 \star\star\star 从图中可以看出对计数器的加密(即从Counter\Rightarrow K1的过程)采用的是AES-ECB加密模式 ⋆⋆⋆从图中可以看出对计数器的加密(即从Counter⇒K1的过程)采用的是AES−ECB加密模式

♠ C T R 模式不需要 p a d d i n g ,故其加密后的密文长度是可知的 \spadesuit CTR模式不需要padding,故其加密后的密文长度是可知的 ♠CTR模式不需要padding,故其加密后的密文长度是可知的 ♠ 从图中可以看出对计数器的加密 ( 即从 C o u n t e r ⇒ K 1 的过程 ) 采用的是 A E S − E C B 加密模式 \spadesuit 从图中可以看出对计数器的加密(即从Counter\Rightarrow K1的过程)采用的是AES-ECB加密模式 ♠从图中可以看出对计数器的加密(即从Counter⇒K1的过程)采用的是AES−ECB加密模式 在这里插入图片描述 举个生成的例子来理解

ctr = Counter.new(AES.block_size * 8, initial_value=initial_value) aes = AES.new(key, counter=ctr, mode=AES.MODE_CTR) enc = aes.encrypt(msg) AES.block_size 用于表示 AES 算法的分组大小(以字节为单位)的常量值。AES 算法支持三种分组大小:16 字节(128 bits)、24 字节(192 bits)和 32 字节(bits 位)。分组大小的选择取决于所使用的 AES 密钥长度无指定情况下AES.block_size 的值为 16,表示使用 128 bits的分组大小initial_value用于表示计数器的初始值,每使用一次,计数器值加1,确保每次不一样,从而不易被攻击,例如:

initial_value:b’\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08’ Counter value1: b’\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08’ Counter value2: b’\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\t’ Counter value3: b’\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\n’ Counter value4: b’\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x0b’ Counter value5: b’\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x0c’ … 以此类推,每次加1(转为long型加1,再转为bytes型)

题目一 题目描述: from Crypto.Util.number import * from Crypto.Cipher import AES from Crypto.Util import Counter from hashlib import sha256 from secret import flag import os def padding(msg): return msg + os.urandom(16 - len(msg) % 16) msg = b"where is the flag? Key in my Heart/Counter!!!!" key = b"I w0nder how????" assert len(msg) == 46 assert len(key) == 16 enc_key = os.urandom(16) initial_value = bytes_to_long(enc_key) hash = sha256(str(initial_value).encode()).hexdigest() aes = AES.new(enc_key, AES.MODE_ECB) enc_flag = aes.encrypt(padding(flag)) ctr = Counter.new(AES.block_size * 8, initial_value=initial_value) aes = AES.new(key, counter=ctr, mode=AES.MODE_CTR) enc = aes.encrypt(msg) print("enc = {}".format(enc[-16:])) print("enc_flag = {}".format(enc_flag)) print("hash = {}".format(hash)) ''' enc = b'\xbe\x9bd\xc6\xd4=\x8c\xe4\x95bi\xbc\xe01\x0e\xb8' enc_flag = b'\xb2\x97\x83\x1dB\x13\x9b\xc2\x97\x9a\xa6+M\x19\xd74\xd2-\xc0\xb6\xba\xe8ZE\x0b:\x14\xed\xec!\xa1\x92\xdfZ\xb0\xbd\xb4M\xb1\x14\xea\xd8\xee\xbf\x83\x16g\xfa' hash = efb07225b3f1993113e104757210261083c79de50f577b3f0564368ee7b25eeb ''' 题目分析:

在这里插入图片描述 由流程可知,明文msg和密文enc_flag已知,那么两者异或就能得到K3(分三组:16 16 14,不需填充) 但此K3非彼K3,此K3是14字节,实际上K3是16字节,所以要得到真正的K3得进行填充 注意这里是往后填充,不是往前填充 (从流程图确实很容易想到是往前填充。但此处是CRT库里面的自己实现的,类似于规定一样,测试出来的数据确实也表明是往后填充,我想这应该也就是所说的 C T R 模式不需要 p a d d i n g CTR模式不需要padding CTR模式不需要padding的原因吧) 在末尾爆破两字节得到真正的K3,然后-2即可得到初始Counter,即initial_value initial_value出来了,那么flag差不多也就出来了

from Crypto.Util.number import * from Crypto.Cipher import AES from Crypto.Util import Counter from hashlib import sha256 msg = b"where is the flag? Key in my Heart/Counter!!!!" key = b"I w0nder how????" enc = b'\xbe\x9bd\xc6\xd4=\x8c\xe4\x95bi\xbc\xe01\x0e\xb8' enc_flag = b'\xb2\x97\x83\x1dB\x13\x9b\xc2\x97\x9a\xa6+M\x19\xd74\xd2-\xc0\xb6\xba\xe8ZE\x0b:\x14\xed\xec!\xa1\x92\xdfZ\xb0\xbd\xb4M\xb1\x14\xea\xd8\xee\xbf\x83\x16g\xfa' hash = 'efb07225b3f1993113e104757210261083c79de50f577b3f0564368ee7b25eeb' a = msg[32:] b = enc[2:] enc_Counter1 = bytes(a[i] ^ b[i] for i in range(14)) for i in range(256): for j in range(256): enc_Counter2 = enc_Counter1 + bytes([i]) + bytes([j]) aes = AES.new(key,AES.MODE_ECB) Counter = aes.decrypt(enc_Counter2) initial_value = bytes_to_long(Counter) - 2 if hash == sha256(str(initial_value).encode()).hexdigest(): enc_key = long_to_bytes(initial_value) aes = AES.new(enc_key,AES.MODE_ECB) flag = aes.decrypt(enc_flag) print(flag) break # flag{9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d} 浅记一下

学到了AES-CTR加密模式,往后填充哪里确实需要我们记住 还有,当时看了很多资料,发现大家都是这样说的(引用一下):

计数器的生成方法

每次加密时都会生成一个不同的值(nonce)来作为计数器的初始值。当分组长度为128比特(16字节)时,计数器的初始值可能是像下面这样的形式 在这里插入图片描述 其中前8个字节为nonce(随机数),这个值在每次加密时必须都是不同的,后8个字节为分组序号,这个部分是会逐次累加的。在加密的过程中,计数器的值会产生如下变化:在这里插入图片描述

这应该是初始值只有8字节的时候吧 如果初始值就是16字节,那Counter value1的值就是初始值,之后的Counter value便是每次在初始值后加1,也就没有所谓的后8字节为分组序号组这一说法,就像上面讲原理是所介绍的那个例子。我理解的大致是这样,因为遇到的题目确实是按这个想法才能解。 学艺不精,还有待提升,继续加油!



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有