ISO7816是一种接触式的读卡协议,PSAM、SAM、手机的SIM卡都是按照这个协议定制的。协议分为2个部分,复位和数据的传输。本文档主要介绍自己的理解和在调试的过程,具体协议部分的内容需要翻看ISO7816的协议文档。本文重点是带着数据对协议进行分析。适合刚接触ISO7816的人。加深对协议的理解。
一、复位
上电复位或者手动给卡复位之后,卡会发出一段数据,这段数据是代表卡本身的一些信息,如发送的格式是什么样子的,卡支持什么样的协议,卡片的号码等等。复位的结构如下:
TS…………………………………………表示正向或者反向约定,强制性在
T0…………………………………………格式字符,强制性
TA(i) TB(i) TC(i) TD(i)…………… 接口字符,可选的
T1 T2…Tk…………………………………历史字符,可选的
Tck……………………………………… 检测字符,有条件的
第一个数据是TS,我个人理解是大端和小端的问题,第一个数据永远是“0X3B”或者是“0X3F”,其中“0X3B”代表正向约定,“0X3F”代表反向约定,在我见到的卡片里面,只见过“0X3B”,还没有见过“0X3F”。如果第一个数据不是这两个值,那么代表接收的时序有问题,需要查看驱动或者硬件是否有问题。
第二个数据是T0,这个数据比较重要,他决定了下面的数据代表什么意思。也就是说,从第三个数据开始,每个数据代表什么意思是不确定的。T0的结构如下。
b8 msb | b7 | b6 | b5 | b4 | b3 | b2 | b1 lsb |
Y(1) | K |
图1 — T0编码
Y(1)……接口字节存在的标记
b5=1时TA(1)存在
b6=1时TB(1)存在
b7=1时TC(1)存在
b8=1时TD(1)存在
K……历史字节的数目,从0到15
由图1 可知,第三个数据代表什么意思,是由T0的高4位决定的。T0的低4位代表是历史字节的数目,这个后面在介绍。
第三个数据是有T0决定的,下面我就举一段例子,来说明。下面是我读取到的一张卡的数据。
1 | 0x3b |
2 | 0x69 |
3 | 0x00 |
4 | 0x00 |
5 | 0x45 |
6 | 0x53 |
7 | 0x41 |
8 | 0x4d |
9 | 0x10 |
10 | 0xd3 |
11 | 0x4c |
12 | 0x8a |
13 | 0xe6 |
上面这段数据是我抓取的一张T=0协议卡的复位数据。第一个数据是“0x3B”,代表TS,是正向约定,就是小端的意思。第二个数据是0X69,代表T0,二进制“01101001”,则带表下面第三个数据是TB1,因为其b6位是1,那么顺下去,b7位也是1,则第四个数据就代表TC1,所以说TA(i) TB(i) TC(i) TD(i)是可选字符(i代表1,2,3,4、、、由于可能存在好多组TA、TB、TC、TD,所以用i来表示),也就是说他们不一定都存在,会根据T0和TD(i)来决定。至于TA(i) TB(i) TC(i) TD(i)是干什么用的,我们下面会介绍。这组数据由于T0的b8位由于没有TD1,所以就没有TA2、TB2、TC2、TD2、、、、、以及以后的数据,那么,剩下的数据代表什么意思的,剩下的从第5个开始到第13个,代表的是历史字符,也就是T1 T2…Tk,我们上面说了,历史字符的个数是由T0的低4位决定的,我们这组数据中,T0为0X69,低4位是9,则说明有9个历史数据,而剩下的数据正好是9个,由于最后一个字符Tck是有条件的,也就是说不一定存在,在T=0的卡中,一般是不存在Tck的。分析到这里,这组数据和我们的复位协议也都对上了。简单的总结一下,这组数据代表了这张卡是正向约定的卡,存在TB1和TC1,有9个历史字符。那么这张卡到底是T=0的卡还是T=1的卡,根据现在的情报还没办法分析出来。下面开始介绍TA(i) TB(i) TC(i) TD(i)。
TA(1)
— FI,位b8到b5 上的时钟率转换因子的引用。
— DI,位b4到b7上波特率校正因子的引用。
这位和etu有关系,总之是和两个数据的传输间隔时间相关。这位确定了卡支持的传输速率。
TB(1) b8=0代码处
— II,位b7 b6上最大编程电流的引用。
— PI1,位b5到b1上编程电压的值。
注:接口设备可以忽略TB(1)的位b8。
这一位我也没用到过。所以这里也就不介绍了。
TC(1)代码(见8.5.3)
— N,计算八位额外保护时间的引用。
— 这一位我也没用到过。所以这里也就不介绍了。
下面是重点TD1
字节TD1由两部分组成。
— 位b8到b5构成Y2);每个等于1的位指明接口字节的存在。
— 位b4到b1构成8.2中定义的参数T的值。
b8 msb | b7 | b6 | b5 | b4 | b3 | b2 | b1 lsb |
Y(2) | T |
图2 — TD(1)编码
Y(2)……接口字节存在的标记
b5=1时TA(2)存在
b6=1时TB(2)存在
b7=1时TC(2)存在
b8=1时TD(2)存在
T……协议参考和/或接口字节限制符
TD1和T0差不多,高4为代表了TA(2)TB(2) TC(2) TD(2)是否存在,低4为代表了这张卡支出什么协议,参数T的定义如下:
——T=0 异步半双工字符传输协议 在第8章中说明。
——T=1 异步半双工块传输协议 在第9章中说明。
——T=2和T=3 保留用于将来的全双工操作。
——T=4 保留用于增强的异步半双工字符传输协议。
——T=5到T=13 保留待未来使用。
——T=14 未由ISO/IEC JTC1 SC17标准化的传输协议
——T=15 不属于传输协议,仅指明了全程接口字节的类型(见8.4.3.2)
TD2、TD3的高四位定义和TD1差不多,类推一下就好了,低4位目前我没用过,反正我判断是什么协议的卡只判断TD1的低4位,TD2、TD3的低4位我直接忽略了。如果TD1不存在,则代表了该卡支持的是T=0的卡。
TA2、TB2、TC2我也没有用到,所以没有仔细研究过,如果想要了解就需要看协议的相关文档。
TA3 也是比较重要的一个值,他确定了IFSC的大小,IFSC后面会介绍,这里只要记住有这个东西,并且比较重要就好了。
TB3的值和CWT和BWT,这两个值关系到了数据传输的时间,具体看协议,我也没有了解过。
TC3的值也比较重要,他决定T=1的检验位采用什么方式,第1位是0,则采用LRC校验,第1位是1,则采用CRC校验。如果没有TC3,则代表采用LRC校验。
接下来的数据是历史字符,具体代表什么意思需要看卡片。我也没研究过。
还有最后一个数据,Tck—校验字符
TCK具有一个检验复位应答期间所发送数据完整性的值。TCK的值应使从T0到包括TCK在内的所有字
由于T=0的卡没有校验,所以没有该值,在T=1的卡中,会正常返回该值。
下面我给出一组T=1卡的复位数据,进行分析。
序号 | 值 | 分析 |
1 | 0x3b | TS,正向约定 |
2 | 0xff | T0,有TA1、TB1、TC1、TD1,历史数据为15个 |
3 | 0x18 | TA1控制了传输的速率,详细看下面的介绍 |
4 | 0x00 | TB1 我也不知道具体什么意思 |
5 | 0xff | TC1 我也不知道具体什么意思 |
6 | 0x81 | TD1,有TD2,卡支持T=1协议 |
7 | 0x31 | TD2,有TA3和TB3,后四位好像不是代表支持的协议 |
8 | 0xfe | TA3,代表IFSC的值为254 |
9 | 0x45 | TB3 我也不知道具体什么意思 |
10 | 0x65 | T1 |
11 | 0x63 | T2 |
12 | 0x0d | T3 |
13 | 0xoc | T4 |
14 | 0x76 | T5 |
15 | 0x01 | T6 |
16 | 0x56 | T7 |
17 | 0x00 | T8 |
18 | 0x0d | T9 |
19 | 0x92 | T10 |
20 | 0x94 | T11 |
21 | 0x03 | T12 |
22 | 0x00 | T13 |
23 | 0x07 | T14 |
24 | 0x30 | T15 |
25 | 0x0a | Tck,最后的校验位 |
二、数据传输
1、 传输速度
卡的传输速度除了有卡本身的决定外,还由CLK的时钟决定。在ISO7816协议中规定,CLK的时钟必须1Mhz-5Mhz,CLK的时钟是由读卡器决定的,而DATA的位持续时间是由CLK和卡本身决定的,所以说,卡的传输速度是由读卡器和卡共同决定。这里有一个叫做etu的东西,我把他理解成为每一位的持续时间。在复位期间,etu的计算如下:
etu =372 / f
其中F即为CLK的时钟,假如CLK的时钟为3.6M,则
etu =372 / 3600000 = 103us
那么,在CLK为3.6M的情况下,波特率为
1 / (372 / 3600000)= 9677
“STM32 ISO7816 智能卡”的DEMO中,其CLK的时钟输出就是3.6M,所以其波特率为9677。而我在调试过程中,将STM32的主频修改为8M,那么,CLK无论怎么分频都无法输出3.6M,所以我只能将CLK设置为2M,那么相应的波特率也改为了5376。
而复位的信息中包含了时钟率转换因子(FI)和波特率矫正因子(DI),那么etu的计算就变成了:
etu =FI / (DI * f)
FI和DI由TA决定,一般情况下,FI=372,DI=1,所以,一般情况下,复位完成后无需重新设置波特率,如果有遇到特殊的卡,在复位完成之后还需要对波特率进行重新设置。
2、 传输协议
卡支持不同的协议,传输方式也不同,目前最常见的就是T=0的卡和T=1的卡,他们的传输都是通过APDU格式进行传输,协议的内容我就不介绍了。
其中T=0叫字符传输,T=1叫块传输。说白了就是T=0的卡没有校验,你不知道还剩下多少个数据。也不知道传输过来的数据对不对。T=1的卡就不一样了,分为头域、信息域、尾域。其中,头域代表了传输的地址、命令以及信息域的长度,信息域代表的意思和头域有关,如果发送的是I块,那么信息域就是APUD数据,如果发送的S块,那么信息域代表了控制信息,R块的信息域为0,我们上面说的IFSC指的就是信息域的大小,刚刚那组数据中,IFSC的值为254,那么代表传输过程中,信息域最大的长度就是254。尾域的作用就是校验接收的数据是否正确。
T=0的卡百度也有很多现成的代码,直接搜“STM32 ISO7816 智能卡 代码”应该就能找得到。可以做一些参考。T=1的卡百度代码较少。可以在美信的官网上找一下智能卡相关的内容,应该可以找得到源码,或者在下面的连接下载也可以。
https://www.maximintegrated.com/cn/design/tools/appnotes/4200/an4200_sw.zip
这个代码支持T=0和T=1的卡,可以用作参考。
另外需要注意的就是,T=1的卡复位完成之后,必须先发一个S块,应该是规定好的。
下面给出一组T=0的卡传输过程中的数据分析。
序号 | 值 | 收发 | 分析 |
1 | 0x00 | 发 | CLA 指令类别 根据卡的文档决定 |
2 | 0x84 | 发 | INS 指令类别 0x84代表获取随机数 |
3 | 0x00 | 发 | P1 |
4 | 0x00 | 发 | P2 |
5 | 0x04 | 发 | LE(没有LC,则没有DATA),希望得到4个数据 |
6 | 0x84 | 收 | INS,卡回应INS,则代表相应了这个命令 |
7 | 0x86 | 收 | DATA1 |
8 | 0x91 | 收 | DATA2 |
9 | 0xd3 | 收 | DATA3 |
10 | 0x48 | 收 | DATA4 |
11 | 0x90 | 收 | SW1 和SW2一起表示正常结束 |
12 | 0x00 | 收 |
|
这支持一个简单的测试卡是否可以正常通信的命令。该支持的意思是获取4个随机数。其实每个代表什么意思,还需要看卡的文档。
下面给出一组T=1的卡传输过程中的数据分析,举一个I块的例子。
序号 | 值 | 收发 | 分析 | |
1 | 0x00 | 发 | NAD 节点地址,一般都是0 | |
2 | 0x00 | 发 | PCB 协议控制字节 b0=1代表是I块,b7=0代表是第1组数据,b6=0代表是最后一个块,剩下的字节保留 | |
3 | 0x05 | 发 | LEN 长度,代表信息域的长度为5 | |
4 | 0x00 | 发 | 信息域,其实内容和T=0一样的 | CLA 指令类别 根据卡的文档决定 |
5 | 0x84 | 发 | INS 指令类别 0x84代表获取随机数 | |
6 | 0x00 | 发 | P1 | |
7 | 0x00 | 发 | P2 | |
8 | 0x04 | 发 | LE(没有LC,则没有DATA),希望得到4个数据 | |
9 | 0x85 | 发 | EDC 校验位,前面所有数据的异或值 | |
10 | 0x00 | 收 | NAD 节点地址,和发送的一样 | |
11 | 0x00 | 收 | PCB 协议控制字节 b0=1代表是I块,b7=0代表是第1组数据,b6=0代表是最后一个块,剩下的字节保留 | |
12 | 0x20 | 收 | LEN 长度,代表信息域的长度为2 | |
13 | 0x67 | 收 | SW1 0x67代表长度错误 | |
14 | 0x00 | 收 |
| |
15 | 0x1e | 收 | EDC 校验位,前面所有数据的异或值 |
我特意选了一组带有错误值,发送的数据和T=0的卡一样,是一个希望得到4个随机数的指令,而返回的只有SW1和SW2,没有DATA的值,SW1为0X67代表数据的长度错误,后来才发现,我手里的这张T=1的卡只支持获取8个随机数的指令,所以,把LE改成8之后,接收的数据就正确了。