Online Store

uFCoder 图书馆机器可读旅行证件 (MRTD) 支持

介绍 #

uFCoder 库中已支持从嵌入在机器可读旅行证件 (MRTD) 中的 NFC 标签读取数据组,包括符合 ICAO 规范的电子护照。

该实现支持 NFC 芯片访问的基本访问控制 (BAC) 机制。 BAC 支持身份验证和安全的加密通信通道,并在 MRTD 中嵌入了 NFC 标签。 BAC 完全基于使用 3DES 算法的对称加密,并根据 ICAO 9303 第 11 部分实施。

国际民航组织 代表 国际民用航空组织 (https://www.icao.int)。 ICAO 9303 规范标准化了MRTD,包括电子护照。 您可以在 https://www.icao.int/publications/pages/publication.aspx?docnum=9303网站上找到整个国际民航组织9303号文件系列。

MRTD 基本访问控制在版本 5.0.12uFCoder 库中受支持。

为了首先对嵌入在MRTD中的NFC标签进行身份验证,您必须将文档编号,文档持有人的出生日期和文档到期日期传递给功能MRTD_MRZDataToMRZProtoKey(),以便获取“原型密钥”,从中将派生其他必要的安全密钥。 获取“原型密钥”(文档编号、文档持有人的出生日期和文档到期日期)所需的所有数据都编码在机器可读区 (MRZ) 中,因此库具有 MRTD_MRZSubjacentToMRZProtoKey() 函数,可以调用该函数而不是 MRTD_MRZDataToMRZProtoKey()。 此函数接受以 null 结尾的字符串,其中包含文档 MRZ 的下层行。下面的屏幕截图显示了带有标记下层行的 MRZ 示例,您必须将其内容作为参数传递给函数 MRTD_MRZSubjacentToMRZProtoKey()。

电子护照 MRZ

捷运支持库功能 #

MRTD_MRZDataToMRZProtoKey #

功能说明

为了获取后续步骤中所需的MRZ Proto密钥,您可以调用此函数并向其传递以null结尾的字符串,其中包含文档编号,文档持有人出生日期和文档到期日期。 成功执行函数后,MRZ 原型密钥将存储在 25 字节mrz_proto_key数组中。

函数声明(C 语言)

UFR_STATUS MRTD_MRZDataToMRZProtoKey(常量字符 *doc_number,

常量字符 *date_of_birth,

常量字符 *date_of_expiry,

uint8_t mrz_proto_key[25]);

参数

doc_number 指向以 null 结尾的字符串的指针,该字符串正好包含 9 个字符的文档编号。
date_of_birth 指向以 null 结尾的字符串的指针,该字符串正好包含 6 个字符,以“YYMMDD”格式表示出生日期。
date_of_expiry 指向以 null 结尾的字符串的指针,该字符串正好包含 6 个字符,表示“YYMMDD”格式的到期日期。
mrz_proto_key 此字节数组将在成功执行函数后包含计算出的 MRZ 原型密钥。 在调用此函数之前,此数组必须至少分配 25 个字节。

 

MRTD_MRZSubjacentToMRZProtoKey #

功能说明

为了获取后续步骤中所需的 MRZ 原型密钥,对于 TD3 MRZ 格式(总共 88 个字符长),您可以调用此函数并向其传递一个包含 MRZ 子交集的以 null 结尾的字符串。 打印在 eMRTD 文档上的 TD3 MRZ 格式的示例如下所示:

P<UTOERIKSSON<<ANNA<MARIA<<<<<<<<<<<<<<<<<<<

L898902C36UTO7408122F1204159ZE184226B<<<<<10

此函数应接收指向包含 MRZ 下贾分行的以 null 结尾的字符串的指针,即“L898902C36UTO7408122F1204159ZE184226B<<<<<10”。

函数声明(C 语言)

UFR_STATUS MRTD_MRZSubjacentToMRZProtoKey(Const char *mrz, uint8_t mrz_proto_key[25]);

参数  
MRZ 指向包含 MRZ 数据的以 null 结尾的字符串的指针。 根据国际民航组织第9303-10号文件,它有三种MRZ数据格式:TD1、TD2或TD3格式。 TD1 正好包含 90 个字符,TD2 正好包含 72 个字符,TD3 正好包含 88 个字符。
mrz_proto_key 此字节数组将在成功执行函数后包含计算出的 MRZ 原型密钥。 在调用此函数之前,此数组必须至少分配 25 个字节。

MRTDAppSelectAndAuthenticateBac #

功能说明

使用此函数通过 BAC 对 eMRTD NFC 标记进行身份验证。 此功能建立安全的通信通道。 使用 send_sequence_cnt 参数维护安全通道。 通道会话密钥是 ksenc(用于加密)和 ksmac(用于计算 MAC)。

函数声明(C 语言)

UFR_STATUS MRTDAppSelectAndAuthenticateBac(const uint8_t mrz_proto_key[25], uint8_t ksenc[16],

uint8_t ksmac[16],

uint64_t *send_sequence_cnt);

参数

mrz_proto_key 使用先前调用 MRTD_MRZDataToMRZProtoKey() 或 MRTD_MRZSubjacentToMRZProtoKey() 函数获取的 MRZ 原型密钥
克森克 在调用此函数之前,此数组必须至少分配 16 个字节。成功执行函数后,此数组将包含会话加密密钥
KSMAC 此数组在调用此函数之前必须至少分配 16 个字节。此数组将包含一个会话密钥,用于在成功执行函数后计算 MAC。
send_sequence_cnt 成功执行此函数后,应在每次后续调用 MRTDFileReadBacToHeap() 和/或其他用于读取 eMRTD 的函数时保存并转发指向此 64 位值的指针。

MRTDFileReadBacToHeap #

功能说明

使用此函数从 eMRTD NFC 标签读取文件。 只有在之前调用的 成功建立安全通道后,才能调用此函数

MRTDAppSelectAndAuthenticateBac() 函数。 会话键 ksenc 和 ksmac,以及参数send_sequence_cnt由先前调用的

MRTDAppSelectAndAuthenticateBac() 函数。 成功调用此函数后,*输出指向从 file_index 参数指定的 eMRTD 文件中读取的文件数据。 存储数据的缓冲区在函数执行期间自动分配到内存堆上。 分配的最大数据量可以是 32KB。 程序员有责任在使用后清理分配的数据(即通过调用标准 C 函数 free()。

函数声明(C 语言)

UFR_STATUS MRTDFileReadBacToHeap(const uint8_t *file_index,

uint8_t **输出,

uint32_t *output_length,

康斯特uint8_t ksenc[16],

康斯特uint8_t KSMAC[16],

参数

file_index

指定我们要从 eMRTD 读取的文件的参数。 这是一个指向字节数组的指针,该数组恰好包含两个指定 eMRTD 文件的字节。这两个字节是文件标识 (FID),并且有一个 FID 列表:

EF.COM = {0x01, 0x1E}
英 孚。DG1 = {0x01, 0x01}
英 孚。DG2 = {0x01, 0x02}
英 孚。DG3 = {0x01, 0x03}
英 孚。DG4 = {0x01, 0x04}
英 孚。DG5 = {0x01, 0x05}
英 孚。DG6 = {0x01, 0x06}
英 孚。DG7 = {0x01, 0x07}
英 孚。DG8 = {0x01, 0x08}
英 孚。DG9 = {0x01, 0x09}
英 孚。DG10 = {0x01, 0x0A}
英 孚。DG11 = {0x01, 0x0B}
英 孚。DG12 = {0x01, 0x0C}
英 孚。DG13 = {0x01, 0x0D}
英 孚。DG14 = {0x01, 0x0E}
英 孚。DG15 = {0x01, 0x0F}
英 孚。DG16 = {0x01, 0x10}
英 孚。SOD = {0x01, 0x1D}

*输出 成功调用此函数后,此指针指向从 file_index 参数指定的 eMRTD 文件中读取的文件数据。 存储数据的缓冲区在函数执行期间自动分配。 分配的最大数据量可以是 32KB。 程序员有责任在使用后清理分配的数据(即通过调用标准 C 函数 free()。
output_length 成功调用此函数后,此指针指向从 file_index 参数指定的 eMRTD 文件中读取的文件数据的大小。
克森克 使用先前调用 MRTDAppSelectAndAuthenticateBac() 函数获取的会话加密密钥。
KSMAC 用于计算使用先前调用 MRTDAppSelectAndAuthenticateBac() 函数获取的 MAC 的会话密钥。
send_sequence_cnt 此指针应指向由先前
初始化的 64 位值
成功调用 MRTDAppSelectAndAuthenticateBac() 函数。 指向此 64 位值的指针应保存,并在每次后续调用此函数和/或用于读取 eMRTD 的其他函数时转发。

uint64_t *send_sequence_cnt);

 

电子护照捷运示例 #

此示例可从以下位置下载:

https://www.d-logic.com/code/nfc-rfid-reader-sdk/ufr-examples-ePassport_mrtd.git

或者使用以下方法克隆整个 eclipse CDT 项目:

git clone –递归 https://www.d-logic.com/code/nfc-rfid-reader-sdk/ufr-examples-ePassport_mrtd.git

命令。

如果只想快速运行,请下载项目并从相应的文件夹启动二进制可执行文件:

  • 对于 32 位 Windows,请启动 win32_releaserun_me.cmd
  • 对于 64 位 Windows 启动 win64_releaserun_me.cmd
  • 对于 32 位 Linux 启动 linux32_release/ePassport_mrtd
  • 对于 64 位 Linux 启动 linux64_release/ePassport_mrtd。

软件示例要求将 uFR 读卡器设备连接并配置到 PC。 计算机上不应运行使用 uFR 读取器的其他应用程序或服务。 成功启动“电子护照MRTD示例”后,软件启动主要许多示例,如下所示。

电子护照阅读器 MRTD NFC

<“>现在,您应该选择屏幕上应用程序使用说明中所述的”M“或”P“选项之一。

如果您选择“M”选项,系统将提示您以下文本:

您已选择输入位于“P<XXXSURNAME<<FIRSTNAME<<<<<<<<<<<<<<<<<<<<<”下的下 MRZ 行:

输入下 MRZ 行。 下 MRZ 行的长度必须为 44 个字符。

所以输入下 MRZ 行。 在第一个图像中可以看到下 MRZ 行的示例。

否则,如果您选择“P”选项,系统将提示您以下文本:

您已选择分别输入文档编号、出生日期和到期日期:

输入文档编号。 文档编号的长度应为 9 个字符。

_________ …

输入出生日期。 日期格式必须为 YYMMDD。

______ …

输入到期日期。 日期格式必须为 YYMMDD。

______ …

因此,请以适当的格式输入数据。

输入有效数据后,应用程序将通过一条消息通知您:

已成功设置 MRZ 原型密钥。

——————————————————————-

在此消息之后,您可以继续对嵌入到您之前输入的数据所属的电子护照中的NFC标签进行读取操作。

现在,您可以将护照放在uFR阅读器字段中。 成功建立通信后,您将在阅读器字段中获得有关NFC标签的基本信息。 例如:

——————————————————————-

标签类型:DL_GENERIC_ISO14443_4,sak = 0x??,uid[4] = ??:??:??:????

——————————————————————-

此示例中的 SAK 和 UID 是屏蔽的,它们可以具有任意值。电子护照将始终像DL_GENERIC_ISO14443_4标签类型一样被识别。

现在,您可以选择应用程序读取选项:

C” – 此选项从电子护照读取通用数据(EF.COM 基本文件)。 读取成功后,数据将按以下格式解析和显示:

已成功读取 EF.COM。 文件长度为 ??字节

原始数据: 60 xx xx xx

解析 EF.COM 原始数据:

LDS 版本是 01.07

UNICODE 版本是 04.00.00

现有数据组列表:

找到:EF。DG1

找到:EF。DG2

找到:EF。DG3

找到:EF。DG14

——————————————————————-

此示例中的原始数据被屏蔽,它们可以具有任意值。 只有原始数据标记存在,并且它将始终相同(0x60)。 当您阅读自己的文档时,您将在此处获得其实际原始数据。 有关LDS版本和UNICODE版本的更多信息,您可以在 ICAO 9303第10部分中阅读。

LDS和UNICODE版本后跟电子护照包含的数据组列表。 只有DG1和DG2是强制性的。 所有其他数据组可以存在于特定 MRTD 中,也可以不存在。

S” – 此选项读取文档安全对象 (EF.SO elementary file),并将其保存到二进制文件中,当您提示时必须输入该路径和名称。 文档安全对象包含标准 PKCS#7CMS格式的数字签名。 EF 的存在。MRTD上的SO是强制性的。

D

1” – 此选项读取 EF。DG1,解析它并按以下格式显示原始数据和解析的数据:

英 孚。已成功读取 DG1。 文件长度是??字节

原始数据:

61 xx xx

  1. xx xx xx x  

简单分析 EF。DG1 原始数据:

文件代码:P(电子护照)

发证国或发证组织:???

持有人姓名:姓氏FIRST_NAME

文档编号:?????????

国籍:???

出生日期(日月): ??.??.????.

性:????

到期日期(日月): ??.??.????.

可选数据:??????????????

——————————————————————-

此示例中的原始数据被屏蔽,它们可以具有任意值。 只有原始数据标记存在,并且它将始终相同(0x61)。 当您阅读自己的文档时,您将在此处获得其实际原始数据。

2” – 此选项读取 EF。DG2 并将其保存到二进制文件中,当您出现提示时必须输入该路径和名称。 英 孚。DG2包含一个文件持有人面部图像,这是强制性的。 英 孚。面部图像旁边的DG2也可以包含生物识别面部特征。 有关 EF 的更多信息。您可以在 ICAO 9303第10部分文件中阅读DG2内容。

I” – 此选项读取 EF。DG2到。 在这种情况下,仅从MRTD文件中提取面部图像,并将其保存到您输入的路径和名称的文件中。 自动检测图像格式,并根据它设置文件扩展名。 为此上下文定义了两种可能的图像文件格式:JPEG 或 JP2(即 2000.jpeg)。

D” – 此选项读取任何基本数据组 (EF.DG) 文件,并将其保存到二进制文件中,当您出现提示时,您必须输入该路径和名称。 选择此选项后,系统将提示你输入 EF。DG指数。 索引的范围可以是 1 到 16(例如,EF 为 1。DG1 和 14 用于 EF。DG14)。 要读取的基本文件必须列在 EF.COM 数据组列表中。

读取某些可选的基本文件,尤其是包含生物识别数据的文件,需要特殊的安全机制,这些机制超出了本文档的范围。

“电子护照MRTD示例”的当前版本为1.0,取决于uFCoder库版本5.0.12和uFR固件版本5.0.22。