ePassport BAC 密钥派生与 AES 解密
这篇文章复现 MysteryTwister C3 的一道 ePassport BAC 题。
题目给出:
一段不完整 MRZ |
目标是:
1. 恢复 MRZ 中缺失的字符 |
1. 题目中的 MRZ
题目给出的不完整 MRZ 是:
12345678<8<<<1110182<111116?<<<<<<<<<<<<<<<4 |
其中 ? 是缺失字符。
MRZ 是 Machine Readable Zone,护照和旅行证件中常见。BAC 会从 MRZ 信息里派生密钥,所以缺失一个字符也会导致最终密钥完全不同。
2. MRZ 字符取值
MRZ 校验位计算时,不同字符有不同数值:
0-9 -> 0-9 |
代码:
def mrz_char_value(ch: str) -> int: |
校验位使用循环权重:
7, 3, 1 |
计算函数:
def mrz_check_digit(field: str) -> str: |
3. 恢复缺失字符
已知 MRZ 有多个字段自带校验位,例如:
passport number |
所以可以枚举 ? 的候选字符,检查三个字段的校验位是否同时正确。
MRZ_ALPHABET = "0123456789<ABCDEFGHIJKLMNOPQRSTUVWXYZ" |
运行结果恢复:
Recovered missing character: 7 |
完整 MRZ:
12345678<8<<<1110182<1111167<<<<<<<<<<<<<<<4 |
4. 生成 MRZ information
BAC 不是直接对整行 MRZ 做 SHA1,而是取几个字段拼接。
本题中的 MRZ information:
12345678<811101821111167 |
代码:
mrz_info = mrz_line[0:10] + mrz_line[13:20] + mrz_line[21:28] |
也就是:
passport number + check digit |
5. BAC 密钥派生
第一步:
K_seed = SHA1(MRZ_information)[0:16] |
代码:
k_seed = hashlib.sha1(mrz_info.encode("ascii")).digest()[:16] |
第二步,生成加密密钥材料:
SHA1(K_seed || 00000001)[0:16] |
第三步,调整 DES 奇校验位。本题最终使用的是 16 字节密钥材料,但每个字节仍要调整奇校验位:
def adjust_des_parity(data: bytes) -> bytes: |
最终结果:
K_seed : a095f0fdfe51e6ab3bf5c777302c473e |
6. AES-CBC 解密
题目说明:
mode = AES-CBC |
所以解密:
ciphertext = base64.b64decode(CIPHERTEXT_B64) |
注意本题 padding 不是 PKCS#7,而是 01-00 padding。
去 padding:
def zero_one_unpad(data: bytes) -> bytes: |
7. 真实运行结果
运行脚本:
python work\experiment_02_aes_modes\09_recover_mtc3_epassport_message.py |
真实 VSCode 截图:

输出:
Recovered missing character: 7 |
code word 是:
Kryptographie |
8. 代码截图与测试
代码运行截图:

单元测试里也检查了:
missing_char == "7" |
测试截图:

9. 常见错误
9.1 MRZ 字段切片错误
MRZ 的位置非常重要。切片错一位,K_seed 就完全不同。建议先打印:
MRZ information string |
确认后再派生密钥。
9.2 忘记校验位
缺失字符不是随便猜。它必须让护照号、出生日期、有效期等字段校验位同时成立。
9.3 忘记奇校验位调整
如果直接拿 SHA1 的前 16 字节当 K_ENC,可能会解密失败。题目流程要求做 parity adjustment。
9.4 用错 padding
本题是 01-00 padding,不是 PKCS#7。去填充逻辑不同。
9.5 IV 写错
题目明确 IV 是全 0。如果 IV 不对,第一块明文会错,后续结果也无法正常解释。
10. 小结
这道 ePassport BAC 题串起了几个点:
MRZ 校验位 |
做这种题时,不要急着上 AES。先把 MRZ 恢复和密钥派生每一步打印出来,确认中间值正确,最后再解密。
参考资料
- MysteryTwister C3 ePassport BAC challenge
- ICAO Doc 9303, Machine Readable Travel Documents
- Basic Access Control 相关资料
- NIST SP 800-38A, CBC mode