密码学大作业
mysterytwisterc3-challenge-AES key — encoded in the machine readable zone of a European ePassport
题目
题目地址:Level II Challenges | MysteryTwister — The Cipher Contest
An AES encrypted message has been forwarded to you (CBC mode with zero initialization vector and 01-00 padding). Additionally, you have received the corresponding key - unfortunately not quite complete in a form like a machine readable zone (MRZ) on an identity document as it is used e.g. with ePassports in Europe.
It is the objective to find the plaintext of the followingbase64-encoded message.
9MgYwmuPrjiecPMx61O6zIuy3MtIXQQ0E59T3xB6u0Gyf1gYs2i3K9Jxaa0zj4gTMazJuApwd6+jdyeI5iGHvhQyDHGVlAuYTgJrbFDrfB22Fpil2NfNnWFBTXyf7SDI
For encryption a key KENC based on the Basic Access Control(BAC) protocol has been generated and applied. For decryption thefollowing characters have been transmitted from which KENC canbe derived (The kind of coding of these characters is described in[1]):
12345678<8<<<1110182<111116?<<<<<<<<<<<<<<<4
Unfortunately, during transmission a character was lost and hasbeen highlighted with a "?". Nevertheless, you can make it visibleagain with the help of [2]. To be able to compute the key KENCafterwards you can find an overview of the applied encodingprotocols in [3], [4] and an example in [5].
The AES-encrypted message contains a code word that is to beentered as the solution.
思路
1.恢复完整的MRZ信息获取密钥
根据附件中的文件可以知道,MRZ信息由以下几部分构成。
相应的校验位计算算法为
那么便可以简单的对密钥进行恢复
# step 1
a = [1,1,1,1,1,6]
b = [7,3,1,7,3,1]
c = 0
for i in range(len(a)):
c += a[i]*b[i]
c %= 10
# print(c)
# 7
2.获取对应的MRZ_INFORMATION以及\(K_{seed}\)
参考文件可知。高十六字节即为对应的前32位
# step 2
passport = '12345678<8<<<1110182<1111167<<<<<<<<<<<<<<<4'
no = passport[:10]
birth = passport[13:20]
arrive = passport[21:28]
mrz = no+birth+arrive
h_mrz = sha1(mrz.encode()).hexdigest()
# print(h_mrz)
# a095f0fdfe51e6ab3bf5c777302c473e7a59be65
获取KA和KB
因为这里使用加密模式,所以c='00000001'
,计算SHA-1散列后,前一半为\(K_a\),后一半为\(K_b\),最后对密钥进行奇偶校验得到最重的DES密钥。
# step 3
k_seed = h_mrz[:32]
c = '00000001'
d = k_seed + c
h_d = sha1(bytes.fromhex(d)).hexdigest()
# print(h_d)
# eb8645d97ff725a998952aa381c5307909962536
#step 4
ka = jiou(h_d[:16])
kb = jiou(h_d[16:32])
key = ka+kb
解密
# step 5
cipher = '9MgYwmuPrjiecPMx61O6zIuy3MtIXQQ0E59T3xB6u0Gyf1gYs2i3K9Jxaa0zj4gTMazJuApwd6+jdyeI5iGHvhQyDHGVlAuYTgJrbFDrfB22Fpil2NfNnWFBTXyf7SDI'
cipher = base64.b64decode(cipher)
aes = AES.new(bytes.fromhex(key),AES.MODE_CBC,bytes.fromhex('0'*32))
result = aes.decrypt(cipher).decode()
print(result)
# Herzlichen Glueckwunsch. Sie haben die Nuss geknackt. Das Codewort lautet: Kryptographie!
完整代码
from Crypto.Cipher import AES
import base64
import binascii
from hashlib import sha1
def jiou(ka):
k=[]
a=bin(int(ka,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]+'1')
else:
k.append(a[i:i+7]+'0')
knew=hex(int(''.join(k),2))
return knew[2:]
# step 1
a = [1,1,1,1,1,6]
b = [7,3,1,7,3,1]
c = 0
for i in range(len(a)):
c += a[i]*b[i]
c %= 10
# print(c)
# 7
# step 2
passport = '12345678<8<<<1110182<1111167<<<<<<<<<<<<<<<4'
no = passport[:10]
birth = passport[13:20]
arrive = passport[21:28]
mrz = no+birth+arrive
h_mrz = sha1(mrz.encode()).hexdigest()
# print(h_mrz)
# a095f0fdfe51e6ab3bf5c777302c473e7a59be65
# step 3
k_seed = h_mrz[:32]
c = '00000001'
d = k_seed + c
h_d = sha1(bytes.fromhex(d)).hexdigest()
# print(h_d)
# eb8645d97ff725a998952aa381c5307909962536
#step 4
ka = jiou(h_d[:16])
kb = jiou(h_d[16:32])
key = ka+kb
# step 5
cipher = '9MgYwmuPrjiecPMx61O6zIuy3MtIXQQ0E59T3xB6u0Gyf1gYs2i3K9Jxaa0zj4gTMazJuApwd6+jdyeI5iGHvhQyDHGVlAuYTgJrbFDrfB22Fpil2NfNnWFBTXyf7SDI'
cipher = base64.b64decode(cipher)
aes = AES.new(bytes.fromhex(key),AES.MODE_CBC,bytes.fromhex('0'*32))
result = aes.decrypt(cipher).decode()
print(result)
# Herzlichen Glueckwunsch. Sie haben die Nuss geknackt. Das Codewort lautet: Kryptographie!
感悟
这次的作业和以往的内容不同,以往的内容大多数都是针对一段密文或者是简单的数据进行破解攻击。但这次的攻击是基于真实场景欧洲护照上的信息进行攻击的,可以说是体会到了密码攻击的最真实应用,爱了爱了。