MT3C Level2-AES key
题目
- AES 加密模式为 CBC,初始化矢量即 IV 为零,填充为 01-00。此外,相应的密钥在身份证件上的机器可读区域(MRZ)等表格中,它与欧洲的电子护照一起使用时并不十分完整。
- 目标是找到以下 base 64 编码消息的明文:
9MgYwmuPrjiecPMx61O6zIuy3MtIXQQ0E59T3xB6u0Gyf1gYs2i3K9Jxaa0zj4gTMazJuApwd6+jdyeI5iGHvhQyDHGVlAuYTgJrbFDrfB22Fpil2NfNnWFBTXyf7SDI
- 对于加密,已生成并应用基于基本访问控制(BAC)协议的密钥 KENC。对于解密,已经发送了以下字符,从中可以导出 KENC(这些字符的编码类型在[1]中描述):
12345678 <8 <<< 1110182 <111116?<<<<<<<<<<<<<<< 4
- 在传输过程中丢失了并且突出显示了一个’’?’’。可以在[2]的帮助下恢复它。为了能够在之后计算密钥 KENC,可以找到应用编码的概述[3],[4]中的协议和[5]中的一个例子。
- 在解密之前解码base64代码。
解析
解题步骤
- 求未知数
- 计算 key
- 根据 key 和 base 64 解码后的密文解密
分析
- 求未知数
12345678 <8 <<< 1110182 <111116?<<<<<<<<<<<<<<< 4
中的?可以根据参考求解转换成代码,由此,可以计算出“?”
1 2 3 4 5 6
a = [1,1,1,1,1,6] b = [7,3,1,7,3,1] for i in range(0,6): c = c + a[i]*b[i] res = c % 10 print (res) #res = 7
所以,完成的护照信息为:
1
12345678<8<<<1110182<1111167<<<<<<<<<<<<<<<4
- 计算 Key
1 2 3 4 5 6 7 8
def cal_Kseed() -> str: # 护照信息 MRZ_information = "12345678<811101821111167" # 使用SHA1进行哈希 H_information = sha1(MRZ_information.encode()).hexdigest() # 取哈希值的前32位作为K_seed K_seed = H_information[0:32] return K_seed
- 求 Ka 和 Kb
这段话的主要意思就是,把之前生成的 Kseed 和 c 级联,然后再进行一次 sha 1 散列生成了 d,然后 ka 是 d 的前十六位,kb 是 d 的后十六位。
1 2 3 4 5 6 7 8
def cal_Ka_Kb(K_seed): c = "00000001" d = K_seed + c # 对K_seed进行哈希 H_d = sha1(codecs.decode(d, "hex")).hexdigest() ka = H_d[0:16] # 取前16位作为ka kb = H_d[16:32] # 取后16位作为kb return ka, kb
- 对 Ka 和 Kb 奇偶校验生成 key
1 2 3 4 5 6 7 8 9 10 11 12 13
def Parity_Check(x): k_list = [] a = bin(int(x, 16))[2:] # 将16进制转为2进制 for i in range(0, len(a), 8): # 7位一组分块,计算一个校验位,使1的个数为偶数 if (a[i:i + 7].count("1")) % 2 == 0: k_list.append(a[i:i + 7]) k_list.append('1') else: k_list.append(a[i:i + 7]) k_list.append('0') k = hex(int(''.join(k_list), 2)) # 将2进制转为16进制 return k
代码
完整代码:
```python from hashlib import sha1
import codecs
import base64
from Cryptodome.Cipher import AES
import binascii
- 求 Ka 和 Kb
求未知数,是到期日的校验位,根据校验规则计算
def Unknown_Number() -> int:
Unknown_Number = 0
number = “111116” # 预设的数字
weight = “731” # 权重
for i in range(0, len(number)):
Unknown_Number += int(number[i]) * int(weight[i % 3])
return Unknown_Number % 10 # 返回校验位
计算k_seed
def cal_Kseed() -> str:
MRZ_information = “12345678<811101821111167” # 护照信息
H_information = sha1(MRZ_information.encode()).hexdigest() # 使用SHA1进行哈希
K_seed = H_information[0:32] # 取哈希值的前32位作为K_seed
return K_seed
def cal_Ka_Kb(K_seed):
c = “00000001”
d = K_seed + c
H_d = sha1(codecs.decode(d, “hex”)).hexdigest() # 对K_seed进行哈希
ka = H_d[0:16] # 取前16位作为ka
kb = H_d[16:32] # 取后16位作为kb
return ka, kb
对Ka和Kb分别进行奇偶校验,得到新的k1和k2
def Parity_Check(x):
k_list = []
a = bin(int(x, 16))[2:] # 将16进制转为2进制
for i in range(0, len(a), 8):
# 7位一组分块,计算一个校验位,使1的个数为偶数
if (a[i:i + 7].count(“1”)) % 2 == 0:
k_list.append(a[i:i + 7])
k_list.append(‘1’)
else:
k_list.append(a[i:i + 7])
k_list.append(‘0’)
k = hex(int(‘‘.join(k_list), 2)) # 将2进制转为16进制
return k
def main():
K_seed = cal_Kseed() # 计算K_seed
ka, kb = cal_Ka_Kb(K_seed) # 计算ka和kb
k_1 = Parity_Check(ka) # 对ka进行奇偶校验
k_2 = Parity_Check(kb) # 对kb进行奇偶校验
key = k_1[2:] + k_2[2:] # 合并k_1和k_2作为最终的密钥
print(“The key is:”, key) # 输出密钥
1
2
3
4
5
6
7
8
# 待解密的密文
ciphertext = base64.b64decode(
"9MgYwmuPrjiecPMx61O6zIuy3MtIXQQ0E59T3xB6u0Gyf1gYs2i3K9Jxaa0zj4gTMazJuApwd6+jdyeI5iGHvhQyDHGVlAuYTgJrbFDrfB22Fpil2NfNnWFBTXyf7SDI")
IV = '0' * 32 # 初始化向量
# 使用AES进行解密
m = AES.new(binascii.unhexlify(key), AES.MODE_CBC, binascii.unhexlify(IV)).decrypt(ciphertext)
print(m.decode()) # 输出解密后的明文
if name == “main”:
main()
1
### 结果:
The key is: ea8645d97ff725a898942aa280c43179 Herzlichen Glueckwunsch. Sie haben die Nuss geknackt. Das Codewort lautet: Kryptographie! ```
参考
[mysterytwisterc3-challenge-AES key — encoded in the machine readable zone of a European ePassport | 码农家园](https://www.codenong.com/cs109540921/) |