mysterytwisterc3-challenge-AES key — encoded in the machine readable zone of a European ePassport


一、写在前面

密码学老师布置的作业,虽然题不是很难,但是这个进制转换晕了好久。

先给一下原题目的链接:
https://www.mysterytwisterc3.org/en/challenges/level-2/aes-key–encoded-in-the-machine-readable-zone-of-a-european-epassport

二、题目概述

因为题目是英文的,这里简单机翻加一点点渣渣自翻。

1、AES加密模式为CBC,初始化矢量即IV为零,填充为01-00。此外,相应的密钥在身份证件上的机器可读区域(MRZ)等表格中,它与欧洲的电子护照一起使用时并不十分完整。
在这里插入图片描述

2、目标是找到以下base64编码消息的明文:
9MgYwmuPrjiecPMx61O6zIuy3MtIXQQ0E59T3xB6u0Gyf1gYs2i3K9Jxaa0zj4gTMazJuApwd6+jdyeI5iGHvhQyDHGVlAuYTgJrbFDrfB22Fpil2NfNnWFBTXyf7SDI
3、对于加密,已生成并应用基于基本访问控制(BAC)协议的密钥KENC。对于解密,已经发送了以下字符,从中可以导出KENC(这些字符的编码类型在[1]中描述):
12345678 <8 <<< 1110182 <111116?<<<<<<<<<<<<<<< 4
(就是图里面给的那个)
4、在传输过程中丢失了并且突出显示了一个’’?’’。可以在[2]的帮助下恢复它。为了能够在之后计算密钥KENC,可以找到应用编码的概述[3],[4]中的协议和[5]中的一个例子。
5、在解密之前解码base64代码。

总而言之,就是根据它给的那一串数字,然后按照它参考文章里面用到的方法去还原加密的明文。

二、解题步骤

我把这道题分为三步:
1、求未知数字
2、根据得到的数字计算出key
3、拿key和base64解码后的密文解密

1.求未知数字

按照提示,他说在参考文章2中可以找到恢复的方法,我在最后把这两个用到的参考文章还有题目的pdf文件放在最后的百度云链接。
这个是参考文章中给的
在这里插入图片描述
可以得到那个问号,是一个校验到期日期的校验位。而且校验位的方法也给出了。所以我们只需要按照他给的方法,就能很方便的求出那个问号是7。
下面展示实现代码

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

这样就得到了最终的护照信息是
‘12345678<8<<<1110182<1111167<<<<<<<<<<<<<<<4’

2.求key

这个就是此题的关键部分,也是我搞得最久的部分。
大体上分为
1、求Kseed
2、求Ka和Kb
3、对Ka和Kb奇偶校验生成key

2.1求Kseed

这部分也是按照参考文章,就可以轻松的得到Kseed了。
在这里插入图片描述
简单来说,就是把-证件的那些数字和校验位,直接sha1散列,然后取前16位即可。

H_information = sha1(information.encode()).hexdigest()
#十进制先变为二进制散列再换成十六进制
K_seed = H_information[:32]# 取前16位
	

2.2求Ka和Kb

在这里插入图片描述
这段话的主要意思就是,把之前生成的Kseed和c级联,然后再进行一次sha1散列生成了d,然后ka是d的前十六位,kb是d的后十六位。

c = '00000001'
#0x00000001
d = K_seed + c
#print(d)
H_d = sha1(codecs.decode(d,"hex")).hexdigest()
#十六进制先变为二进制散列再换成十六进制
#print(H_d)
ka = sha1(codecs.decode(d,"hex")).hexdigest()[:16]
kb = sha1(codecs.decode(d,"hex")).hexdigest()[16:32]
	

2.3对Ka和Kb奇偶校验生成key

根据上段话,其实学过计算机网络的话其实非常好理解,就是算1的个数并且把第八位当作奇偶校验位。
这里就不多说什么了,直接上代码了,如果有什么不懂的可以在评论里面问我或者去百度或者google一下,网上的教程有很多。

k_1 = jiaoyan(ka)
k_2 = jiaoyan(kb)  
key = k_1 + k_2
print(key)
#ea8645d97ff725a898942aa280c43179
m=AES.new(binascii.unhexlify(key),AES.MODE_CBC,binascii.unhexlify(IV))
print(m.decrypt(cipher))
#b'Herzlichen Glueckwunsch. Sie haben die Nuss geknackt. Das Codewort lautet: Kryptographie!\x01\x00\x00\x00\x00\x00\x00'

#奇偶校验位的判断
def jiaoyan(x):
    k = []
    a = bin(int(x,16))[2:]
    for i in range(0,len(a),8):
        if (a[i:i+7].count("1"))%2 == 0:
            k.append(a[i:i+7])
            k.append('1') 
        else :
            k.append(a[i:i+7])
            k.append('0')      
    a1 = hex(int(''.join(k),2))
    #print("this is " + x + "---" +a1)
    return a1[2:] 
	

三、总结

因为找到了题目中参考文章的中文版本,所以阅读和理解起来其实还算挺轻松的。
这里面主要的难点就是里面的几个进制转换问题,这个我没有过多的去介绍,因为我也没特别明白,而且这几天也没有时间去投入精力,所以如果有问题评论私信都可以,我会尽量的去解答。
我也没有写sha1散列和AES的相关知识,我觉得做这种题的人应该对这几个密码都很熟悉的(笑)。
还有里面用到的校验位和奇偶校验问题,这个知识其实计算机网络里面讲的特别详细易懂,网上的教程应该也挺多的,我就不多讲了。
有任何问题都可以在评论区里面问我。
最后附上相关文件的百度云网盘地址:
链接:https://pan.baidu.com/s/1sI-gBIMsEidYtNvgbGiIAw
提取码:4k74

  • 11
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值