本文主要见Paul Croker和Simão Melo de Sousa 2010年论文《Sniffing with the Portuguese Identify Card for fun and profit》。
摘要
本文描述了一个案例研究,详细介绍了在与葡萄牙电子身份证(Portuguese e-ID smart card)通信时,使用逆向工程技术发现底层应用协议数据单元(APDU)及其相关意义的过程。由于葡萄牙政府对公民卡(Citizens Card)的内部工作原理提供的文档非常有限,本文主要通过这一过程来学习相关技术。然而,本研究的另一目的是开发一个通用平台,以便访问和审计葡萄牙公民卡,并在不同场景下使用 Match-on-Card 生物识别功能。由于没有关于电子身份证的 Match-on-Card 功能的官方文档,因此这项工作面临着巨大的挑战。
1. 引言
葡萄牙政府三年前向社会推出了一种新的电子身份证,称为“Cartão de Cidadão Português”(CC)(官方网站:www.cartaodecidadao.pt)。该卡由“Imprensa Nacional-Casa da Moeda”(INCM,www.incm.pt)生产。其初衷是整合多个身份识别文件至单一电子智能卡,同时保证各机构之间的最大互操作性,并符合葡萄牙法律的要求。此外,该卡还旨在促进电子政务的使用,简化对电子服务的访问,提供合法的电子基础设施以验证电子文件,并支持新应用程序的开发。
一个有趣的事实是,葡萄牙宪法禁止使用单一 ID 号来唯一标识公民,以避免上一世纪独裁时期的情况。
CC 是一张 Java 智能卡,具有标准信用卡格式的芯片。卡片信息存储在多种格式中,包括人眼可读的视觉信息、条形码式的机器可读区域,以及芯片内的电子信息。芯片存储公民的个人信息(如姓名、地址)、照片和生物指纹模板。此外,它还包含由葡萄牙司法部的 PKI(公钥基础设施)创建的加密密钥和数字证书。
该 Java 多应用卡片的芯片配置如下:
- 8/16 位 CPU
- ROM 存储操作系统和加密算法
- 最小 64 KB EEPROM
- RAM 用于瞬时数据存储
- 动态内存管理和文件系统管理
该卡支持多个个人识别码(Personnel Identification Number,PIN)(本案例中有三个),支持 PIN 修改机制,并具备内部加密处理功能以生成数字签名。它兼容多通道读卡器(用于身份验证和数字签名),可以为电话、邮件、传真等替代渠道生成一次性密码,并支持 Match-on-Card(MoC)生物识别指纹验证。此外,该卡还具备防篡改和侧信道攻击防御能力(Rankl 2004)。
作为 Java 智能卡,该卡可通过 Java Card 运行环境(JCRE,即 Java Card Manager)执行 Java 小程序(Applets),这些 Applets 运行于卡片的原生操作系统之上。与读卡器的通信采用标准的 ISO 7816 APDU(应用协议数据单元)。
图 1. 葡萄牙公民卡上安装的 Applets 结构示意图
卡片上的相关数据通过不同的 Applets 及文件目录进行访问(Rankl 2007)。目前,该卡有两个不同版本,不同版本对数据的访问方式略有不同。如果有完整的 CC 文档和规范,复杂任务将变得更加简单。但实际上,所有公开的技术信息仅能在葡萄牙行政现代化机构(AMA,www.ama.pt)维护的官方网站上找到。此外,该网站仅提供了由 ZETES 公司开发的有限 API(Zetes 2010)。
本研究的主要目标之一是探索 CC 卡中的 IAS(身份认证服务)和 MoC(Match-on-Card)Applets,以开发一个不隶属于任何政府机构的开源平台。该平台应能够访问和测试公民数据,并提供一个透明且可自由使用的访问接口。如,希望能够访问 MoC 功能,以支持基于指纹的身份认证,但该功能并未在政府提供的软件中开放给普通公民。
本项目展示了一条开发智能卡访问平台(中间件)的路线图,该平台不仅适用于葡萄牙 CC,也适用于其他类似的电子身份证。
本文结构如下:
- 第 2 节 介绍与智能卡进行底层通信的过程。
- 第 3 节 介绍方法论和逆向工程方法。
- 第 4 节 介绍使用 USB 嗅探器和专有中间件开发平台的贡献和方法。
- 第 5 节 介绍如何使用 CC 进行应用开发的成果。
- 第 6 节 介绍基于 Match-on-Card 进行生物识别认证的方法,并展示最终的概念验证(PoC)应用。
- 第 7 节 讨论结论及未来工作方向。
2. Java Card 与公民卡内部机制
2.1 APDU 命令
智能卡与主机之间的 APDU 通信是半双工的。采用命令-响应模式,主机向智能卡发送命令 APDU,智能卡在同一通信信道上返回响应 APDU。
当前 CC 的 Java Card 平台采用主从编程模型,主机作为主设备(master),发送命令后等待智能卡的响应。发送的命令实际上是在调用智能卡上的方法,本质上是执行 Java Card Applet。要运行 Applet,必须先选择它。选定后,Applet 进入等待状态,接收来自主机的命令。
Java Card 虚拟机(VM)将 APDU 传递给相应的 Applet,调用其 process
方法。Applet 处理 APDU 并生成响应 APDU,返回给虚拟机,然后传输回主机(Li 2004)。
图 2. APDU 命令的执行流程
2.2 APDU 结构
APDU 由头部和数据体组成,理解其结构至关重要。命令 APDU 由 ISO 7816-4 定义,格式如下:
图 3. 命令 APDU 头部结构
- CLA:指令类别字节,标识指令类别
- INS:指令字节,确定类别内的具体命令
- P1、P2:参数字节,传递特定命令的参数
- Le:可选数据的长度
- Data:可选数据字段
- Lc:预期响应数据的长度
图 4. 可发送的不同类型 APDU 命令
图 5. APDU 响应格式
APDU 响应由可选的数据体和必需的尾部组成:
- 数据体:可能为空或包含“数据字段”,具体取决于执行的命令是否成功。
- 尾部(SW1、SW2 状态字):指示执行结果(图 6. APDU 尾部响应代码)。
图 6. APDU 尾部响应代码
所有回复代码可以通过在线表格进行解释(Cheef 2010)。理解这些代码的含义对嗅探和逆向工程至关重要。在掌握 APDU 通信原理后,需要研究实际的卡片通信,确定正确的 APDU 命令序列,以访问所需数据。
3. 方法论与逆向工程过程
电子身份证(e-ID)卡是一种相对较新的文件。其中一个被广泛研究并首次作为开源软件发布的e-ID卡是比利时e-ID卡(Cock 2006)。目前,作为欧洲STORK项目的一部分(Siddhartha 2008),欧洲各国电子身份证的互操作性及成熟的中间件解决方案正处于讨论阶段。然而,各国e-ID卡的内部运作仍然是各国政府的内部事务。在本节中,描述了用于理解葡萄牙公民卡(CC)功能的方法。本文的目标是确定现有应用程序的逆向工程难度,以获取CC中的数据,并探索目前尚未向公众开放的功能机制,例如MoC(Match-on-Card)。
本节首先描述了针对葡萄牙CC所采用的逆向工程过程。由于CC是一种智能卡,因此首先必须理解其通信机制,以便了解如何访问卡上的数据。在成功获取CC数据后,第二阶段涉及研究公民生物特征验证的所有相关过程。
图7展示了在本项目中使用的方法,从理解通信流程和访问正确的Applet,到构建带有Match-on-Card生物识别验证的平台。整个过程分为两个不同的项目阶段。第4节将详细介绍识别和与卡片通信的技术,包括e-ID Applet的选择和CC上的个人信息提取。
图7. 项目方法论示意图
4. 提出的平台
4.1 架构
要与CC进行通信,需要一个智能卡(SC)读卡器、适当的工具以及PCSC(个人计算机/智能卡)等实现方案。葡萄牙政府办公室出售由Gemalto制造的简单且廉价的SC读卡器,当然也可以使用任何兼容的读卡器。
PCSC是一项标准,它是ISO 7816的扩展,旨在为在PC上使用智能卡的解决方案提供灵活的集成平台。PCSC定义了智能卡读卡器应遵循的通信协议、连接性和应用程序编程接口(API)(PC/SC工作组,Corcoran 2004)。Windows XP通过“winscard.dll”实现了PCSC,而Linux通过PCSC lite中间件实现了该功能。
为了使本应用程序能够独立地与CC交互(不依赖于葡萄牙政府或其他第三方提供的中间件),我们开发了一个用于“winscard.dll”的封装器(见图8),使其能够通过PCSC与智能卡进行通信。该封装器被实现为一个动态链接库(DLL),其中包含用于创建和操作APDU命令结构的代码,并最终发展出一款专有的中间件。
图8. 用于与智能卡通信的封装器
在开发完必要的工具后,下一步是建立与CC的连接,以获取卡片的ATR(Answer to Reset,复位响应),并据此识别卡片的类型。
了解卡片类型很重要,因为不同的制造商和卡片类型会采用不同的通信机制。因此,正确识别卡片有助于确定适当的通信方法。
ATR是一串字节序列,定义了各种通信特性,如通信速度、使用的协议、硬件参数(如芯片系列、掩码版本等)(Rank 2007)。ATR可以通过PCSC的SCardStatus方法(Corcoran 2004)在winscard.dll中获取。当成功与卡片建立连接后,该方法会返回多个通信参数,其中之一就是ATR。
插入葡萄牙CC后,获得以下ATR:
3B 95 95 40 FF D0 00 54 01 32
在一些网站(如The SmartCard ATR Database 2010)上,可以找到关于卡片制造商和类型的定期更新的代码列表。在本案例中,得到了预期的结果:
3B 95 95 40 FF D0 00 54 01 3.
葡萄牙公民卡:http://www.cartaodecidadao.pt(SmartCard ATR Database)
通过这种方式,能够成功与智能卡建立通信,并正确识别(或无法识别)该卡是否为葡萄牙身份证。下一节将描述如何从卡中提取个人数据。
4.2 数据嗅探(Sniffing)
本文使用的USB端口嗅探程序是 UsbSnoop(SniffUsb 2010)。UsbSnoop 是一款USB协议分析工具,它能够监测计算机与USB设备之间的所有通信协议,并记录所有通信内容。该程序允许对日志文件进行精细控制,用户可以暂停、恢复、关闭或删除日志文件。此功能有助于剔除日志中的冗余数据,从而简化分析过程。
在调试模式下运行测试程序,可以捕获所有的通信数据,如对动态链接库(DLL)中某个高级函数调用的通信内容。我们所关注的APDU(应用协议数据单元)命令被封装在USB数据包中。然而,由于USB连接会产生大量数据包,因此需要解析日志文件,以便清晰地识别出有用的数据。
在运行葡萄牙政府官方网站提供的官方应用程序时,我们使用嗅探工具进行了监测。该应用程序可以访问并显示CC上的基本信息,但功能相当有限,例如它无法创建文件的数字签名。葡萄牙政府网站还提供了一个受限的SDK,该SDK支持Java和C#编程,并提供了用于访问部分CC功能的高级API。
通过嗅探工具(见图9),并结合在线网站(Cheef 2010)的帮助,成功发现了用于选择智能卡上e-ID Applet的APDU命令,并适用于两种版本的CC。利用这些信息,能够构造自己的APDU命令,与Applet进行通信,并通过不断调整APDU,使其能够返回“90 00”成功响应码。
图9. 嗅探工具的运行截图
5. 结果
如前所述,本文成功提取了智能卡(SC)与应用程序之间交换的APDU命令和响应序列。本文目标是提取公民的个人数据,因此需要审查智能卡上信息的组织方式(Rankl 2007)。
图10. 智能卡系统文件结构
智能卡内文件系统的内部结构遵循 ISO/IEC 7816-4 标准。文件具有唯一的ID,存储在EEPROM上,并采用层级结构,如图10所示,主要包括三种文件类型:
- MF(主文件,Master File)
- DF(专用文件,Dedicated File)
- EF(基本文件,Elementary File)
为了提取数据,需要选择包含相关数据的文件。因此,正确构造APDU命令以正确选择适当的文件至关重要。以下示例展示了如何从CC(公民卡)中选择一个文件:
00H A4H P1 P2 Lc Data Le – SELECT FILE 命令
P1 选项:
P1 = 00H – 通过 FID(文件ID)选择
P1 = 04H – 通过名称选择DF
P1 = 08H – 通过路径从MF选择
P1 = 09H – 通过路径从当前DF选择
P2 选项:
P2 = 00H – 选择第一个出现的文件
P2 = 01H – 选择最后一个出现的文件
P2 = 02H – 选择下一个文件
P2 = 03H – 选择上一个文件
如上所示,在构造APDU选择文件时,需要考虑多个选项(Rankl 2007,Cheef 2010,SmartCard ATR Database)。借助嗅探工具,逐步筛选并测试了所有命令,最终找到了存储公民个人信息的正确文件。这一阶段花费的时间最长,因为嗅探器生成的数据量巨大,除了APDU命令外,还包含大量USB协议信息。因此,分析SC与应用程序之间的命令交换序列以提取个人数据需要大量时间。
然而,通过对嗅探数据的深入测试,成功简化了应用程序所需的命令数量,仅保留提取必要信息的指令。最终,获得了 15,500 字节的原始数据。接下来,需要将其转换为 UTF-8 格式 以供人类阅读。这一转换过程相对复杂,因为必须将数据缓冲区划分为不同的块,每个块对应不同的信息(如地址、姓名等)。
5.1 获取和显示公民照片
下一个挑战是从CC中提取公民的照片。在之前读取的 15,500 字节 数据中,包含了公民的照片。因此,需要解析这些数据并正确提取图像数据。
该图像的格式为 JPEG2000,这是一种基于小波变换的图像压缩格式。据葡萄牙AMA(Agência para a Modernização Administrativa)消息,该格式的选择是出于存储空间管理的考虑。当时,JPEG2000被认为能最大限度地减少存储需求。然而,相比更广泛使用的 JPG格式,JPEG2000的选择可能还有其他因素。
表面上看,获取图像数据并进行显示似乎是一个简单的任务。但实际操作中,.NET 平台和标准 Java 库均不支持 JPEG2000 格式。由于本项目的应用程序基于 .NET 和 Java,因此必须先将图像转换为这些平台支持的格式(如 BMP 或 JPG),以便正常显示。
测试了 Aurigma Imaging Technology(www.aurigma.com)提供的试用版工具包,该工具可在内存中将图像转换为 .NET 平台支持的格式。然而,本项目的理念是 在 Windows 平台上创建开源解决方案。经过仔细筛选,最终选择了 CSJ2K-A Managed JPEG2000 Codec(http://csj2k.codeplex.com/)来处理 .NET 平台上的 JPEG2000 图像解码。
该工具包简单易用,可以顺利提取并显示 CC 上的公民照片。然而,一个需要注意的安全问题是,无需身份验证即可获取照片,这可能导致身份照片被滥用于其他目的。
5.2 带有增强功能的展示应用
通过上述过程,成功开发了一款应用程序,功能与葡萄牙政府官方的 CC 读取与展示应用类似。该应用程序使用自研的 中间件(之前提到的动态链接库)来模拟政府应用的功能。
此外,添加了一项额外功能:对任何文件进行数字签名,并验证该签名。这项功能在现有的葡萄牙政府应用程序中尚未提供,尽管 Adobe Acrobat 和 Microsoft Office 文档的数字签名过程 在 CC 官方网站的用户文档中有所描述。
图11. 个人信息展示与文件签名功能
6. 生物识别
本项目的第二部分是 公民的生物特征验证,即 Match-on-Card(MoC)。MoC 需要在 受控环境 下执行,以确保从正确的个人身上提取生物特征数据。
在 MoC 过程中,首先从智能卡中提取 生物识别头部数据(biometric header)。然后,通过扫描公民的指纹并对其进行处理,生成 验证数据,并将其发送回智能卡进行匹配和认证。
众所周知,CC 上的 第三个Applet 与生物识别相关,由 Precise Biometrics(PB) 公司开发。为了选择该 Applet,仅需对 e-ID Applet 选择方式进行 轻微修改,即可成功选取 生物识别 MoC Applet。一旦选定,该 Applet 将在其封闭环境内运行,仅接受与 MoC 相关的 APDU 命令。
为了找到与该 Applet 交互所需的 底层 APDU 指令,遵循了 图2 所示的流程。使用 Precise Biometrics 提供的工具包、测试卡以及 Precise Biometrics 250MC(集成指纹识别和智能卡读取功能) 设备,嗅探了测试卡的通信过程。
随后,通过实验,用 CC 替换 PB 专有的测试卡,成功完成了 MoC 过程。本部分的详细实现将在后续章节进一步说明。
6.1 指纹模板
在公民申请 CC(公民卡)的过程中,会在 受控环境 下采集其指纹图像(注册阶段)。这些指纹图像随后被转换为 指纹模板 并存储在智能卡上。
一个指纹模板由 两部分组成:参考数据 和 生物识别头部数据(biometric header)。
- 生物识别头部数据 用于验证应用程序,以便采集并预处理合适的指纹样本。它包含智能卡所需的数据类型和格式信息,因此存储在智能卡的 公共区域。
- 参考数据 则存储在智能卡的 私有区域,用于实际的身份验证。出于安全考虑,该数据无法被提取或修改。
使用 生物识别头部数据 是为了提高性能。通过该头部数据,验证应用程序在采集指纹图像后可以 预处理 该图像,然后再将其发送到智能卡进行比对。这样可以 最小化 MoC 验证时间,因为耗时的预处理阶段可由 计算能力更强的 PC 完成,而不是在计算能力有限的智能卡上进行(PB 2008)。
CC 上的指纹验证采用 细节点匹配(Minutia Matching) 技术。
- 指纹由多个 脊线(ridge)和谷线(valley) 组成。
- 其中 脊线端点(ridge ending)和脊线分叉(ridge bifurcation) 形成了细节点(minutiae points)。
- 在注册阶段,系统会定位指纹图像中的 细节点,计算它们的相对位置和方向,并将这些数据存储在 CC 内部的 指纹模板 中。
在身份验证时,系统会:
- 采集新的指纹图像,并提取其细节点,生成新的 指纹模板。
- 将新模板与存储在 CC 内的 参考模板 进行比对(见 图12)。
- 计算匹配的细节点数量,并与设定的阈值 进行比较,确定指纹是否匹配(PB 2008)。
阈值(Threshold) 的设定需要经过精细调整,以 最小化误识别(False Positive)和拒识率(False Negative)。
图12. 细节点匹配验证过程
为了执行 Match-on-Card(MoC),首先需要 构造指纹模板,这包括指纹采集和模板构建。在经过成本分析后,我们决定 继续使用 PB(Precise Biometrics)工具包 和 250MC 读卡器,因为该设备价格适中,且与我们开发的软件兼容。
6.2 Match-On-Card(卡上匹配,MoC)
在读取指纹并获取指纹模板后,下一步是确定执行 MoC(卡上匹配)所需的 APDU 指令。
APDU(应用协议数据单元)的构造基于:
- PB 官方文档
- 之前提到的测试卡嗅探
- PB 工具包的分析
APDU 指令格式如下:
参数 | 值 | 描述 |
---|---|---|
CLA | B0h | 指令类 |
INS | 32h | 指令代码(执行指纹验证) |
P1 | Template number | 选择智能卡上的指纹模板 |
P2 | Sequence number | 分隔多个验证命令(如果数据超过单个 APDU 长度) |
P3 | Data length | 数据长度 |
DATA | Biometric data | 指纹数据 |
模板编号参数用于选择智能卡上的模板容器。
序列号用于区分多个验证命令,当特定模板的生物特征数据超过单个 APDU 的最大数据长度时,将其分段处理。
序列号(Sequence number)定义:
- 00h:验证初始化
- 01h:验证更新(可选)
- 02h:验证完成
在经过多次测试后,我们成功构造了正确的 APDU 指令,并完成了所有 MoC 相关的必要操作。当我们使用采集的指纹模板与葡萄牙 CC 内存储的模板进行比对时,成功收到了 9000 响应码,表明验证通过。
6.3 概念验证(Proof of Concept)
基于之前的所有研究,开发了一套支持任何具有 MoC 功能的 CC(公民卡) 的系统。值得注意的是,该平台在完全没有政府官方技术文档的情况下成功开发,并且可以使用一些普通公民无法访问的 CC 功能。
本文所开发的一款 Windows Presentation Foundation(WPF) 应用程序(见 图13)具有以下特点:
- 自动检测 CC 的插入和移除
- 动画效果 表示 CC 数据读取过程(由于读取速度较慢)
- 可视化公民信息(包括动画照片)
- 基于 MoC 的身份验证反馈
- 指纹图像(灰/黑色)在认证成功时变为 绿色,失败时变为 红色
- 认证结果伴随简单的 音效提示
图13. Match-on-Card 身份认证界面
7. 结论与未来工作
本研究详细描述了 葡萄牙 CC 的逆向工程过程,以发现其与智能卡的底层通信协议。此外,基于这些信息 开发了自己的中间件,并证明可以利用 CC 进行 生物识别身份认证,甚至开发出比官方应用更强大的功能。
整个研究过程涉及 安全性、智能卡技术、生物识别技术 等多个方面。其中,最具挑战性 的部分是访问和提取智能卡上的信息。在 缺乏政府官方文档 的情况下,不得不 嗅探、反汇编并逆向工程 整个葡萄牙 CC 平台,最终成功获取所有必要数据。这些信息本应 公开透明,而不是被隐藏在专有中间件 之下 —— 但我们仍然成功复现了它!
未来工作有:
-
优化指纹模板生成:
- 目标是摆脱 PB 工具包,采用 标准国际方法 自行构建指纹模板。
- 这将推动开发 开源中间件,允许更多编程语言(如 Python、Go)访问葡萄牙 CC。
-
CC 安全性分析:
- 研究 CC 安全漏洞,特别是:
- 无需 PIN 即可获取照片的风险
- 结合 生物识别 + PIN 的更强身份认证方法
- 研究 CC 安全漏洞,特别是:
-
探索 OTP Applet(一次性密码):
- CC 内部还有 第三个 Applet(OTP 认证),已被 EMV-CAP 读卡器 用于 双因素身份验证。
- 目前该功能并未向公众开放,后续研究将尝试逆向工程并利用该功能。
-
扩展至其他国家 e-ID 研究:
- 复用此项目的 逆向工程技术,分析 其他国家的电子身份卡(e-ID)。
-
低成本硬件原型(商业化方向):
- 目标是开发 低成本 MoC 身份认证设备,可应用于:
- 发展中国家(例如葡语非洲国家 PALOPs)
- 投票站、生物识别登记、医疗系统 等场景
- 目标是开发 低成本 MoC 身份认证设备,可应用于:
本项目的商业化正在进行中,有望为全球低成本 生物识别身份验证 方案提供新的可能性。