关于ISO 7816接触式欧洲行车记录仪公司卡的内存结构、访问方法及获取唯一标识的技术问询
背景
我是一名实习学生,目前首次实习任务是开发欧洲行车记录仪读卡器相关功能:需要用智能卡读卡器读取接触式(非射频)ISO 7816公司卡的唯一标识,之后要把该标识和复位应答(ATR)发送至后端处理。现在没有现成代码,得从零搭建包括服务器在内的全部功能,当前正聚焦在智能卡交互部分。
我用C#语言基于Linux平台的PCSC-lite库开发,已经实现了和卡片的基础通信,能获取复位应答(ATR),还能通过返回的sw1、sw2代码做调试,也仔细研读了ISO 7816相关技术文档,但还是有几个疑问,想请领域内专业人士用通俗易懂的方式解答:
我的疑问
- 此类智能卡的内存结构是如何构建的?(已知数据结构涉及EF文件,需先进行“选择”操作再通过正确APDU指令提取数据,但对具体工作机制及内存结构逻辑仍不理解)
- 如何访问此类智能卡的内存?(即正常情况下,需按何种顺序发送哪些APDU指令以访问指定内存区域)
- 需发送哪些APDU指令及按何种顺序操作,才能获取卡片的唯一标识?或请指引可获取内存映射的渠道
专家解答
关于内存结构:
ISO 7816卡的内存结构其实和咱们电脑的文件系统几乎一模一样——有根目录、子文件夹,还有存数据的文件。核心分三层:
- MF(主文件):相当于电脑的C盘根目录,每张卡只有一个,固定标识符是
3F00。所有其他文件都是它的子项。 - DF(专用文件):就像根目录下的子文件夹,用来归类不同功能的数据,比如有的DF存身份信息,有的存设备关联数据,每个DF有自己独有的标识符。
- EF(基本文件):这就是真正存数据的文件了,卡片的唯一标识、设备绑定信息这些关键内容都存在EF里。EF还有不同类型,但咱们读唯一标识的话,碰到的大多是线性固定结构的,就是数据按顺序存在里面,读的时候按字节取就行。
你提到的“选择”操作,说白了就像在电脑上双击打开文件夹或文件——只有先选中某个DF或EF,后面发的指令才会针对这个对象生效,不然系统不知道你要操作哪个文件。
关于内存访问的顺序:
访问卡内内存的流程就是“逐层进入+读取”,就像你打开电脑文件夹找文件一样,步骤大概是这样:
- 先进入根目录(选MF):先发送选择MF的APDU指令,确保咱们在最顶层,指令是:
00 A4 00 00 02 3F 00
给你拆解下:00是指令类别(CLA),A4是“选择”这个操作的指令码(INS),00 00表示按文件标识符来选择,02是后面标识符的长度,3F 00就是MF的固定标识符。发送后如果返回90 00,就说明成功进入MF了。 - 进入目标子文件夹(选DF):如果你的卡片唯一标识存在某个特定DF里,就发送选这个DF的指令,格式和选MF一样,把最后两个字节换成这个DF的标识符就行。比如DF标识是
DF01,指令就是00 A4 00 00 02 DF 01,同样等90 00的成功返回。 - 选中要读的文件(选EF):找到存唯一标识的EF后,还是用选择指令,比如EF的标识是
0001,指令就是00 A4 00 00 02 00 01,等成功返回。 - 读取文件内容:选中EF后,就可以发读取指令了,常用的是
00 B0 00 00 XX——B0是读取指令码,00 00是从文件的起始位置开始读,XX是你要读的字节数。比如读16字节就是00 B0 00 00 10。
当然,有些卡片可能把唯一标识直接存在MF下的EF里,那你就跳过选DF的步骤,直接选对应的EF就行。
关于获取卡片唯一标识:
首先,卡片的唯一标识大概率存在两个地方:一是ATR里可能带一部分,但一般不完整,所以还是读卡内文件更靠谱;二是某个约定好的EF文件里,这是最常见的情况。
如果不知道具体是哪个EF,给你两个实用的办法:
- 遍历当前目录下的文件:在选中MF或某个DF后,发送
00 20 00 00 00这个指令,卡会返回当前目录下所有DF和EF的列表,你可以逐个尝试选择并读取,看看哪个里面是你要的唯一标识。 - 找厂商的卡片规范:如果能拿到这款欧洲行车记录仪配套卡的技术文档,里面肯定会明确写清楚存储唯一标识的EF位置、标识符以及读取方法,这是最省时间的方式。
给你举个具体的操作例子(假设唯一标识在MF下的EF01里):
- 第一步:发
00 A4 00 00 02 3F 00→ 收到90 00(成功进入MF) - 第二步:发
00 A4 00 00 02 00 01→ 收到90 00(成功选中EF01) - 第三步:发
00 B0 00 00 10→ 收到返回的数据(就是卡片唯一标识)+90 00(读取成功)
另外一定要注意每次指令后的sw1/sw2:90 00是万事大吉;如果是6A 82,说明你选的文件不存在,那大概率是标识符写错了,得换一个试试;如果是其他代码,就查ISO 7816的错误码对照表就行。
内容的提问来源于stack exchange,提问作者Oscar K




