You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

关于ISO 7816接触式欧洲行车记录仪公司卡的内存结构、访问方法及获取唯一标识的技术问询

ISO 7816接触式智能卡开发疑问(实习任务相关)

背景

我是一名实习学生,目前首次实习任务是开发欧洲行车记录仪读卡器相关功能:需要用智能卡读卡器读取接触式(非射频)ISO 7816公司卡的唯一标识,之后要把该标识和复位应答(ATR)发送至后端处理。现在没有现成代码,得从零搭建包括服务器在内的全部功能,当前正聚焦在智能卡交互部分。

我用C#语言基于Linux平台的PCSC-lite库开发,已经实现了和卡片的基础通信,能获取复位应答(ATR),还能通过返回的sw1、sw2代码做调试,也仔细研读了ISO 7816相关技术文档,但还是有几个疑问,想请领域内专业人士用通俗易懂的方式解答:


我的疑问

  1. 此类智能卡的内存结构是如何构建的?(已知数据结构涉及EF文件,需先进行“选择”操作再通过正确APDU指令提取数据,但对具体工作机制及内存结构逻辑仍不理解)
  2. 如何访问此类智能卡的内存?(即正常情况下,需按何种顺序发送哪些APDU指令以访问指定内存区域)
  3. 需发送哪些APDU指令及按何种顺序操作,才能获取卡片的唯一标识?或请指引可获取内存映射的渠道

专家解答

关于内存结构:

ISO 7816卡的内存结构其实和咱们电脑的文件系统几乎一模一样——有根目录、子文件夹,还有存数据的文件。核心分三层:

  • MF(主文件):相当于电脑的C盘根目录,每张卡只有一个,固定标识符是3F00。所有其他文件都是它的子项。
  • DF(专用文件):就像根目录下的子文件夹,用来归类不同功能的数据,比如有的DF存身份信息,有的存设备关联数据,每个DF有自己独有的标识符。
  • EF(基本文件):这就是真正存数据的文件了,卡片的唯一标识、设备绑定信息这些关键内容都存在EF里。EF还有不同类型,但咱们读唯一标识的话,碰到的大多是线性固定结构的,就是数据按顺序存在里面,读的时候按字节取就行。

你提到的“选择”操作,说白了就像在电脑上双击打开文件夹或文件——只有先选中某个DF或EF,后面发的指令才会针对这个对象生效,不然系统不知道你要操作哪个文件。

关于内存访问的顺序:

访问卡内内存的流程就是“逐层进入+读取”,就像你打开电脑文件夹找文件一样,步骤大概是这样:

  1. 先进入根目录(选MF):先发送选择MF的APDU指令,确保咱们在最顶层,指令是:00 A4 00 00 02 3F 00
    给你拆解下:00是指令类别(CLA),A4是“选择”这个操作的指令码(INS),00 00表示按文件标识符来选择,02是后面标识符的长度,3F 00就是MF的固定标识符。发送后如果返回90 00,就说明成功进入MF了。
  2. 进入目标子文件夹(选DF):如果你的卡片唯一标识存在某个特定DF里,就发送选这个DF的指令,格式和选MF一样,把最后两个字节换成这个DF的标识符就行。比如DF标识是DF01,指令就是00 A4 00 00 02 DF 01,同样等90 00的成功返回。
  3. 选中要读的文件(选EF):找到存唯一标识的EF后,还是用选择指令,比如EF的标识是0001,指令就是00 A4 00 00 02 00 01,等成功返回。
  4. 读取文件内容:选中EF后,就可以发读取指令了,常用的是00 B0 00 00 XX——B0是读取指令码,00 00是从文件的起始位置开始读,XX是你要读的字节数。比如读16字节就是00 B0 00 00 10

当然,有些卡片可能把唯一标识直接存在MF下的EF里,那你就跳过选DF的步骤,直接选对应的EF就行。

关于获取卡片唯一标识:

首先,卡片的唯一标识大概率存在两个地方:一是ATR里可能带一部分,但一般不完整,所以还是读卡内文件更靠谱;二是某个约定好的EF文件里,这是最常见的情况。

如果不知道具体是哪个EF,给你两个实用的办法:

  1. 遍历当前目录下的文件:在选中MF或某个DF后,发送00 20 00 00 00这个指令,卡会返回当前目录下所有DF和EF的列表,你可以逐个尝试选择并读取,看看哪个里面是你要的唯一标识。
  2. 找厂商的卡片规范:如果能拿到这款欧洲行车记录仪配套卡的技术文档,里面肯定会明确写清楚存储唯一标识的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

火山引擎 最新活动