使用 PN532 读取电子护照,继续获取 SW1 SW2 = 0x69 0x88(不正确的安全消息传递数据对象)

Posted

技术标签:

【中文标题】使用 PN532 读取电子护照,继续获取 SW1 SW2 = 0x69 0x88(不正确的安全消息传递数据对象)【英文标题】:ePassport reading with PN532, Keep Getting SW1 SW2 = 0x69 0x88 (Incorrect Secure Messaging Data Objects) 【发布时间】:2014-03-18 17:23:37 【问题描述】:

我正在尝试从电子护照(又名机读旅行证件)中读取 EF.COM 文件。

我成功完成了什么:

-使用 AID 0xA0,0x00,0x00,0x02,0x47,0x10,0x01 选择电子护照应用程序 - 向电子护照芯片请求挑战随机数 -通过根据 doc9303 附录 5 响应该挑战成功地进行身份验证。 Doc 9303 可以在这里查看:http://www.icao.int/publications/Documents/9303_p1_v2_cons_en.pdf

它起作用了,现在我尝试使用符合 ISO 7816-4 的安全消息协议读取 EF.COM 文件,并使用 doc9303 附录 6 示例作为指南。

根据 doc9303 中的示例,我的安全消息传递代码正确执行的操作:

-它生成与 doc9303 示例中相同输入的完全相同的安全 APDU,一个字节一个字节。 - 我已经验证我的加密(3DES w/CBC)正在工作,我的 MAC 算法也是如此

我尝试过的:

于是我搜索并找到了 ePassport/MRTD/doc9303 的两个开源实现。一个使用 Python (pyPassport-1.0),另一个使用 Java (JMRTD)。我订购了 ACR122 阅读器(使用相同的 NFC 芯片组 - PN532)试用它,它确实有效。因此,我查看了 JMRTD 和 pyPassport 用于生成安全消息 APDU 的代码,看起来好像我在做同样的事情。值得庆幸的是,JMRTD 带有一个选项,可以将 APDU 转储/跟踪到日志文件。果然,我正在创建与 JMRTD 完全相同的安全消息 APDU,我什至对会话进行了反向工程(解密了 RND.IFD、RND.ICC、K.ICC、会话密钥等),创建了一个测试用例和我的代码实际上会生成相同的安全 APDU 输出。

所以我认为我正确地构建了安全消息 APDU 和 DO(数据对象),但是在执行 BAC 并进行身份验证并尝试使用受保护的 APDU 读取 EF.COM 文件后,我不断收到 69 88 错误(不正确安全消息传递 (SM) 数据对象)。这与此处报告的问题类似,尽管我使用的不是 android,而是我自己的嵌入式 NFC 堆栈:Android NFC read data from ePassport

我认为这可能是我需要更改的 PN532(NXP NFC 芯片)中的一个设置,但我对此表示怀疑,因为我正确地进行了身份验证,并且在没有 PN532 错误的情况下发送和传输数据。我尝试将波特率提高到 424 kbits/s,但这并没有解决问题。

这是我的代码生成的安全(受保护)APDU 示例。

原始(不安全)APDU: 00 A4 02 0C 02 01 1E

受保护(安全)APDU: 0C A4 02 0C 15 87 09 01 5B B0 63 B9 2A 0D 71 C0 8E 08 E0 B6 68 D2 14 4F 28 B5 00

因此,根据 doc9303,我正在构建一个 DO87,因为存在命令参数,以及一个 DO8E,因为存在校验和 (MAC),但没有 DO97,因为不需要响应有效负载。我将 87 09 01 用于 DO87,因为 01 表示填充类型 80 00 00... 而 L 是 09(我猜它包括 01 - 填充指示符字节,这就是示例中的内容和来自 JMRTD 的 APDU 跟踪.)

我已尝试从末尾删除 Le=0x00,因为 7816-4 文档中的某些语言暗示了这一点,并且如上所示将 Lc' 设为 0x16 而不是 0x15。我还尝试将 DO87 设为 87 08 01 而不是 87 09 01,如上图所示。这些都没有奏效。

我在这里真的很绝望,我已经为此工作了一段时间,但无法弄清楚。我的受保护 APDU 结构有问题吗?是否有需要更改的低级别 PN532 设置?

2014 年 3 月 19 日更新 这是 PN532 命令/响应跟踪(我对其进行了注释,因此它的 gobedy gook 较少):

-> GetFirmwareVersion (test command to verify PN532 is awake and online):
00FF02FED4022A0000 
0000FF00FF0000 ->ACK
-> Response to GetFirwareVersion:
00FF06FAD50332010607E80000 

-> Diagnose, NumTst=0x00:
00FF12EED400000102030405060708090A0B0C0D0E0FB40000 
00FF00FF0000 ->ACK
-> Successfull diagnostic (Data returned):
00FF12EED501000102030405060708090A0B0C0D0E0FB20000 

-> Diagnose NumTst=0x01:
00FF03FDD400012B0000 
00FF00FF0000 ->ACK
-> Successfull diagnostic (0x00):
00FF03FDD501002A0000 

-> Diagnose NumTst=0x02:
00FF03FDD400022A0000 
00FF00FF0000 ->ACK
-> Successfull diagnostic (0x00):
00FF03FDD501002A0000 

-> InListPassiveTarget (max targets one, 106kbit/s Type A anticollision)
00FF04FCD44A0100E10000 
00FF00FF0000 ->ACK
-> Found one target, Tg=0x01, SENS_RES=0x07,0x04, SEL_RES=0x20 
-> UID = 0x08,0x8B,0x05,0xCF, ATS = 0x05,0x78,0x77,0xB4,0x02 DCS=0x9E:
00FF11EFD54B010107042004088B05CF057877B4029E0000 

-> inPSL (change baud to 424kbits/s)
00FF05FBD44E010202D90000
00FF00FF0000 -> ACK
00FF03FDD54F00DC0000 -> Status = 0x00, success

-> inDataExchange (select ePassport application w/ AID in doc9303):
00FF0FF1D4400100A4040C07A0000002471001360000
00FF00FF0000 -> ACK
00FF05FBD5410090005A0000 -> SW1SW2 = 9000 (success)

-> inDataExchange  (get nonce/challenge)
00FF08F8D4400100840000085F0000
00FF00FF0000 -> ACK
00FF0DF3D541008EAF826F89F1E5259000A80000 -> SW1SW2 = 9000 (success), RND.ICC = 0x8E,0xAF,0x82,0x6F,0x89,0xF1,0xE5,0x25

-> inDataExchange  (mutual authenticate)
00FF31CFD4400100820000284782B1700DD4F60373DA6632FCD1AB1E500D46FA11DEBDF9B88C39FCA7FDF8DBBE51F41D52D4B87928310000
00FF00FF0000 -> ACK
00FF2DD3D5410055A930856698D46C2AEF3CEDF3C56E71668150F2FECC75E28F42AB2A57CD2BA2F42727AE656CB3F49000470000 -> SW1SW2 = 9000 (success)

-> inDataExchange  (select EF.COM)
00FF1EE2D440010CA4020C158709012CA8E7AB995D13248E0810061DDC725A159300DB0000
00FF00FF0000 ->ACK
00FF05FBD541006988F90000 -> SW1SW2 = 6988 (Incorrect SM Data Objects)..BAH!!

会议详情如下:

MRZ = GF043591<586012072309062

Computed values from MRZ:

Kenc = BA 43 43 3B F4 7A AE F8 75 23 4F DF 32 08 20 6D
Kmac = EA 64 45 CD 62 2C EA EC BF 7C 9B 7C B0 20 B9 5D


RND.ICC = 8E AF 82 6F 89 F1 E5 25
RND.IFD = 23 E8 5A 99 3A 9A C5 B4
K.IFD = 75 DC 87 E5 0C 8E F3 00 47 D0 B5 32 5E 83 20 4D
SSC = 89 F1 E5 25 3A 9A C5 B4

The computed E.IFD = 47 82 B1 70 0D D4 F6 03 73 DA 66 32 FC D1 AB 1E 50 0D 46 FA 11 DE BD F9 B8 8C 39 FC A7 FD F8 DB

The computed MAC of the above = BE 51 F4 1D 52 D4 B8 79

The tag's response to the mutual authenticate was:

E[Kenc](RND.ICC) =  55 A9 30 85 66 98 D4 6C
E[Kenc](RND.IFD) =  2A EF 3C ED F3 C5 6E 71 
E[Kenc](K.ICC)   =  66 81 50 F2 FE CC 75 E2 8F 42 AB 2A 57 CD 2B A2
MAC              =  F4 27 27 AE 65 6C B3 F4

The computed session keys:
KSenc = 4C E6 EF A8 3D 3E DA FB FB 02 1A F2 D5 E0 6E 4F
KSmac = EA C7 5B 64 D9 80 52 23 4F 64 7A 51 45 7F 40 1A

【问题讨论】:

SM APDU 看起来正确(如果加密值/MAC 值正确)。填充指示符计入 DO87 的长度,SM APDU 的 Lc 应为 0x00。包装后的 APDU 的 Le 应为空,如 DO97 不存在所示。 @Michael 感谢您的回复。您能否澄清“SM APDU 的 Lc 应为 0x00”的含义。我将 SM APDU 的字节 5 设置为 00(是 ox15)并得到 6700 错误。你的意思是当我计算 N = SSC||填充的 4 字节 CMD 标头||87 L 01||加密填充数据||填充的 MAC 时,L 应该是 0x00?现在我的代码生成与 doc9303 相同的 APDU,因此我认为我的安全消息构建是正确的,因为密码与 doc9303 的密码匹配,具有相同的未受保护的 APDU 输入和 SSC。如果我不正确地增加 SSC,会产生 6988 错误吗? 抱歉,应该是“Le of the SM APDU should be 0x00”。 Lc 就这样就好了。 在这种情况下我不会想到这个错误。您是否在每次 MAC 计算之前增加 SSC? @MichaelRoland :是的,我在每次 MAC 计算之前都会增加 SSC。 【参考方案1】:

好的,我想通了!!感谢您让我创建 PN532 命令跟踪。当我将它与我的通用调试日志中的会话详细信息结合起来时,我开始编写代码来验证它。进行到一半时,我意识到我的错误,即会话密钥不正确,因为我没有将整个相互身份验证响应解密为 32 字节块,而是零碎地解密,并且由于 MRTD 的芯片使用密码块链接 K.ICC解密不正确,因此我的 K.SEED 不正确,因此会话密钥错误。我纠正了这个错误,现在我可以阅读 EF.COM 文件了!!

【讨论】:

以上是关于使用 PN532 读取电子护照,继续获取 SW1 SW2 = 0x69 0x88(不正确的安全消息传递数据对象)的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Python 中从 PN532 读取标签?

RPi 如何读取 I2C/SPI PN532 NFCRFID/NFC 模块?

PN532 串口通讯读取IC卡UID

PN532 卡模拟模式

为啥使用 libnfc 和 PN532 SHIELD “未找到 NFC 设备”

ESP32 无法检测到 PN532 NFC 模块