文章目录
Commands与Responses结构
Command APDU
APDU command由header和body部分组成,header由CLA,INS,P1,P2组成,header是一个 APDU command中必须存在一部分,而body部分是可选的,body部分由Lc,Data ,Le组成。
body部分中的Lc,Data ,Le不一定要全部出现在APDU command中,可能的组合如下图:
下面分别介绍每个字段的含义,如下表:
字段 | 长度 | 含义描述 | 分组 |
---|---|---|---|
CLA | 1 | 指令类型 | Header |
INS | 1 | 指令操作码 | Header |
P1 | 1 | 指令参数1 | Header |
P2 | 1 | 指令参数2 | Header |
Lc | 0或者1 | 数据字段的Byte长度 | Body |
Data | Lc | 数据字符串 | Body |
Le | 0或者1 | 希望获取的最大返回值长度 | Body |
CLA字段编码格式
标准逻辑信道下:
扩展逻辑信道下:
INS字段编码方式
P1和P2字段
这两个字段的具体含义由具体的command确定,如果该字段未使用(例如,command不需要传参的时候)则置为’00’。
举个例子,如SELECT命令的P1和P2字段含义如下图:
Lc字段
Lc用来告诉UICC,终端发送给UICC的数据长度,这个字段的取值范围介于1到255Bytes。这个字段是可选的,如果出现在APDU command中则数据字段必须出现,且紧跟在Lc字段之后。
Data字段
依赖于具体的APDU command,例如,更新电话簿文件就需要将电话号作为Data字段传入UICC中。
Le字段
举个例子,我想从UICC中获取一个随机数,获取多长的随机数呢,通过Le字段告诉UICC。
这个字段也是可选的,如果不出现则表示在response command中不希望携带任何data,如果出现则response command会返回Le个Byte长度的数据。
如果设置Le为’00’,则表示终端希望获取尽可能长的数据。这种情况下,UICC可能返回1到256Bytes中的任意长度的数据。
Response APDU
Response APDU由状态比特和数据字段组成,数据字段是可选的部分,而状态字段是必须出现的,如下表:
字段 | 长度 | 含义描述 |
---|---|---|
Data | Lr | response数据 |
SW1 | 1 | 状态Byte1 |
SW2 | 1 | 状态Byte2 |
SW1和SW2含义
正常流程
SW1 | SW2 | 含义描述 |
---|---|---|
‘90’ | ‘00’ | 命令正常结束,没有异常 |
‘91’ | ‘XX’ | 命令正常结束,但是有额外的XX Bytes的数据需要读取,这些数据来自proactive UICC,包含对终端的command |
‘92’ | ‘XX’ | 命令正常结束,但是有额外的XX Bytes的数据需要读取,这些数据与当前的会话相关 |
延迟处理
SW1 | SW2 | 含义描述 |
---|---|---|
‘93’ | ‘00’ | SIM Application当前繁忙,当前无法立即执行命令,将稍后执行 |
警告
SW1 | SW2 | 含义描述 |
---|---|---|
‘62’ | ‘00’ | 没有给出具体的警告信息,非易失性内存状态没有发生变化(也就是文件没有被修改) |
‘62’ | ‘81’ | 返回的数据可能被破坏 |
‘62’ | ‘82’ | 读取Le个Bytes的数据时,到达file/record尾(就是说Le大于file/record的长度了)或者 search失败 |
‘62’ | ‘83’ | 选择的文件无效 |
‘62’ | ‘85’ | 被选择的文件在一个termination state |
‘62’ | ‘F1’ | 更多的数据可以获取 |
‘62’ | ‘F2’ | 更多的数据可以获取,proactive command被挂起 |
‘62’ | ‘F3’ | response数据可读 |
‘63’ | ‘F1’ | 希望更多的数据 |
‘63’ | ‘F2’ | 希望更多的数据,proactive command被挂起 |
‘63’ | ‘CX’ | 使用内部更新重试程序’X’次之后,命令执行成功 或者 当前鉴权失败,剩余’X’次机会 |
执行错误
SW1 | SW2 | 含义描述 |
---|---|---|
‘64’ | ‘00’ | 没有给出具体的错误信息,非易失性内存状态没有发生变化(也就是文件没有被修改) |
‘65’ | ‘00’ | 没有给出具体的错误信息,但是非易失性内存状态发生变化(也就是文件被修改了) |
‘65’ | ‘81’ | 内存问题 |
基础错误检查
SW1 | SW2 | 含义描述 |
---|---|---|
‘67’ | ‘00’ | 命令长度错误 |
‘67’ | ‘XX’ | 这个状态字段的含义取决于具体的命令 |
‘6B’ | ‘00’ | P1、P2参数错误 |
‘6D’ | ‘00’ | INS字段错误或者不持支 |
‘6E’ | ‘00’ | CLA字段不支持 |
‘6F’ | ‘00’ | 技术问题,无法精确诊断错误 |
‘6F’ | ‘XX’ | 这个状态字段的含义取决于具体的命令 |
CLA不支持
SW1 | SW2 | 含义描述 |
---|---|---|
‘68’ | ‘00’ | 没有给出具体的错误信息 |
‘68’ | ‘81’ | 不支持逻辑信道 |
‘68’ | ‘82’ | 不支持安全报文发送 |
命令未授权
SW1 | SW2 | 含义描述 |
---|---|---|
‘69’ | ‘00’ | 没有给出具体的错误信息 |
‘69’ | ‘81’ | 命令与当前文件不兼容 |
‘69’ | ‘82’ | 安全状态不满足 |
‘69’ | ‘83’ | 鉴权/PIN被锁定 |
‘69’ | ‘84’ | Referenced数据无效 |
‘69’ | ‘85’ | 不满足使用条件 |
‘69’ | ‘86’ | 命令不允许执行,没有选择EF |
‘69’ | ‘89’ | 命令不允许执行-安全通道-安全不满足 |
错误参数
SW1 | SW2 | 含义描述 |
---|---|---|
‘6A’ | ‘80’ | 数据字段中的参数错误 |
‘6A’ | ‘81’ | 功能不支持 |
‘6A’ | ‘82’ | 文件未找到 |
‘6A’ | ‘83’ | record未找到 |
‘6A’ | ‘84’ | 没有足够的内存空间 |
‘6A’ | ‘86’ | P1、P2参数错误 |
‘6A’ | ‘87’ | Lc与P1、P2不一致 |
‘6A’ | ‘88’ | Referenced数据未找到 |
Application错误
SW1 | SW2 | 含义描述 |
---|---|---|
‘98’ | ‘50’ | INCREASE命令无法执行,已经达到最大值 |
‘98’ | ‘62’ | 鉴权失败,具体失败原因由Application定义 |
‘98’ | ‘63’ | 安全会话超时 |
‘98’ | ‘64’ | Minimum UICC suspension时间太长 |
通过PCSC实际操作一下USIM
大致流程
具体演示
我们以读取USIM的IMSI文件为例进行演示
- IMSI文件位于USIM Application中,我们需要先选择EFDIR
-
解析SELECT命令返回值,获取EFDIR的record信息(record长度)
-
遍历EFDIR的record,获取USIM Application AID
-
选择USIM Application
-
选择EFIMSI文件名读取IMSI