本文转载自:http://blog.sina.com.cn/s/blog_4df8400a0102vcyp.html

深入理解7816(3)-----关于T=0

卡片和终端之间的数据传输是通过命令响应的方式进行的,卡片只能被动地接收命令,并且给出响应。所有的命令都是以命令头开始,而该命令被完整地执行后(无论结果对错),必须以包含状态字(SW1 SW2)的响应结束。卡片和终端之间如何具体进行数据传输的,就依靠不同的通讯协议来实现,其中主要有T=0、T=1、T=CL。其中T=0和T=1适用于接触式卡片(7816),而T=CL适用于非接触式卡片(14443)。

T=0是按照单个字符的方式实现智能卡和终端数据传输的通讯协议,理解协议最好的方式就是尝试自己来设计协议,我们先看看该如何实现字符的传输。

假设让你来完成数据的正确接收,首先要解决的应该是从哪开始接收的问题。所以我们需要定义一个叫做“起始位”的标志,一旦发现“起始位”就可以确定一个全新的字符传过来了。然后就按照etu的约定逐位接收一个完整字节的数据。在接收的过程中万一有某一位识别错了,比如把“1”识别成了“0”怎么办?所以还要有一个校验位,看看之前接收的数据位是否有错误。如果有错误,则需要反馈一个出错信息,那么发送方会把刚才那个出错的字节再重新发送一次,如果接收再次出错,则要求发送方再重发,最多需要重发多少次由具体的应用规范来确定;如果没有错误,则反馈一个接收正确的状态,然后准备接收下一个字符。

因为7816的数据传输采用的是串行半双工的方式,而且数据的收发都通过一条I/O信号线来完成,所以在I/O线上传递的数据就有两个方向:可能是从终端到卡(“命令”),也可能是从卡到终端(“响应”)。如果两个连续字符的传输方向一致则称为“同向连续字符”,反之则称为“反向连续字符”。为了保证数据的正确接收,需要规定传递两个连续字符(无论是同向还是反向)的最小和最大时间间隔,最小间隔是为了让接收方有足够的时间准备接收下一个字符,而最大间隔是为了避免接收方无限制地等待,不然就算你已痴痴地等待了千年,那个“良人”还是不来。

那究竟需要接收多少个字符才算完成了一次完整的数据收发过程呢?怎么来判断发送方发送的动作已经“over”了呢?对于T=0协议而言,卡片和终端必须清楚彼此之间每次数据通讯需要收发多少字节的数据。可是有的时候终端在开始发送命令的那一刻是真不知道,比如在读一条记录时,终端事先可能并不知道这条记录的长度,那该怎么办?其实也没有别的好办法,只能靠试错的方式来投石问路。

首先,终端发给卡片的命令必须包含5个字节(分别是CLA + INS + P1 + P2 + P3,其中INS表示指令,说明该命令的作用)的命令头,也就是说卡片必须要收到来自终端的5个字节的命令头,才能决定下一步该干什么,然后根据做出的决定给终端一个反馈意见。同样终端在发送完5个字节的命令头后,也需要等待来自卡片的反馈后,再决定下一步该干什么。

这个反馈的信息一共有三类:1)空操作的过程字节NULL(0x60);2)响应字节ACK;3)状态字的第一个字节SW1。

NULL字节相当于网络通信中的“心跳包”,就是告诉终端不要进行超时处理,继续等待,而且NULL字节不见得是在卡片接收5个字节的命令头后反馈,通常在卡片需要进行大量数据更新或者复杂的加解密运算时,来不及返回状态字(SW)时先发一个0x60;

ACK是用来决定后续的数据传输的,不仅能决定传输的方向,还能决定后续传输字节的多少。如果ACK = INS,则传输剩余的全部字节,如果ACK = INS ^ FF,则传输后续的一个字节(早期版本的7816规范中还有ACK = INS ^ 01,以及ACK = INS ^ FE的定义,用来说明编程电压Vpp的,后来的版本中因为Vpp已经不再使用就把这两个值剔除了);

SW1只能是“0x9X”以及“0x6X”(不能是空操作字节“0x60”),如果卡片返回的是SW1,那么接下来必须紧跟着另一个状态字节SW2,标志着卡片对于该命令处理的结束,如果不断电,卡片在发送完SW2之后会等待下一个命令的到来。另外,因为SW1只能是“0x6X”和“0x9X”,所以INS一定不能取值0x6X和0x9X。至于ISO/IEC  JTC1/SC17 的人为什么选择6 9作为SW1的高4位,是不是他们有什么特别的偏好就不得而知了。

ACK里面为什么会有仅传输后续一个字节的情形,而不是一次传完后续的所有字节?主要是因为如果智能卡芯片没有那么多可以用于临时缓存命令数据的RAM空间的话,就需要接收一个字节先处理一个字节,直到剩余的字节能被一次性地处理了,再反馈一个INS作为过程字节,把剩余的字节全部收进来。

除了这5个字节的命令头之外,可能还包含终端发送给卡片的命令数据(命令数据长度表示为Lc),也可能还需要卡片返回响应数据(响应数据长度表示为Le)。于是可以把终端和卡片之间的不同命令类型分为4类:1)只有命令头,没有命令数据也没有响应数据;2)有命令头没有命令数据,但是有响应数据;3)有命令头和命令数据,没有响应数据;4)有命令头、命令数据和响应数据。

对于情形1,P3=00;对于情形2,P3=Le,如果事先不知道Le的具体数值,可以填“00”,卡片会返回“0x6CXY”,其中的“XY”就是Le的正确值,终端用“XY”替换原来作为Le的“00”重新再发一遍命令就能正确获得响应数据了(就是前面提到的试错);对于情形3,P3=Lc;对于情形4,P3=Lc,卡片会返回“0x61XY”,其中的“XY”用来表示Le,然后终端再利用取响应的指令,获得卡片返回的响应数据。

上面说的这些命令和响应严格来说是属于TPDU(传输层协议数据单元)的概念,和通常智能卡规范里面说的APDU(应用层协议数据单元)概念是有差别的。因为应用层协议是不关心你的数据如何具体传输的,APDU只定义命令、命令数据、响应数据、返回状态,如何保证这些命令、数据的正确传输则是TPDU该做的事情。新的7816规范对于包含命令数据和响应数据的情形2、3、4还定义了扩展情形2E、3E、4E,用来处理数据长度Lc和Le大于256的场景,但是目前支持该扩展的卡片和终端还不多。

深入理解7816(3)-----关于T=0 【转】的更多相关文章

  1. 深入理解7816(2)---关于ATR【转】

    本文转载自:http://blog.sina.com.cn/s/blog_4df8400a0102vcrk.html 深入理解7816(2)---关于ATR 智能卡(此处主要指接触式CPU卡)本身始终 ...

  2. 深入理解7816(1)---- 关于F/D和etu【转】

    本文转载自:http://blog.sina.com.cn/s/blog_4df8400a0101gkss.html 深入理解7816(1)---- 关于F/D和etu 对于刚接触智能卡的工程师来说, ...

  3. 如何理解Apache License, Version 2.0(整理)

    如何理解Apache License, Version 2.0(整理) 问题: 最近看到apache发布了2.0版本的License.而且微软也以此发布了部分源代码.我对OpenSource不是特熟, ...

  4. 深入理解7816(3)-----关于T=0

    卡片和终端之间的数据传输是通过命令响应的方式进行的,卡片只能被动地接收命令,并且给出响应.所有的命令都是以命令头开始,而该命令被完整地执行后(无论结果对错),必须以包含状态字(SW1 SW2)的响应结 ...

  5. 深入理解7816(4)---关于T=1

    之前说过的T=0协议,基本上相当于是透明的数据,也就是说从应用的角度看,通过T=0传递的TPDU数据信息大都可以直接转换为对应的APD命令响应数据,“字节”是T=0协议最小的数据传输单元. 对于T=1 ...

  6. 深入理解7816(1)---- 关于F/D和etu

    对于刚接触智能卡的工程师来说,在阅读7816-3规范的时候,常常被其中的一些术语迷惑,读起来会觉得有些别扭.尤其是在看到复位应答中的F和D设置,以及对应的etu的时候,会觉得有些复杂和难以理解. 其实 ...

  7. PHP代码审计理解(二)----齐博CMS7.0文件覆盖

    0x00 前言 因为我是跟着视频操作的,这回真的没理解为什么定位到了这个存在漏洞的文件... /do/fujsarticle.php 因为没有前文,所以这里无法分析这个$FileName为什么可以$_ ...

  8. 深入理解7816(5)-----关于文件DF/EF/MF/FID/AID/SFI

    刚开始接触CPU卡的时候,对于各种文件.应用的定义容易模糊不清,通常不能准确地界定什么是文件?什么是应用?DF和EF的区别真的就像计算机里的目录和文档那样吗?FID.AID.SFI这些概念都在什么时候 ...

  9. 深入理解7816(2)---关于ATR

    智能卡(此处主要指接触式CPU卡)本身始终处于被动的状态,所以终端设备在和智能卡进行数据交互的时候,需要首先给智能卡发指令,智能卡才会对应地给出应答.而智能卡告诉终端的第一句话就是ATR,亦即“复位应 ...

随机推荐

  1. CAD从二进流加载数据(com接口VB语言)

    主要用到函数说明: MxDrawXCustomFunction::ReadBinStreamEx 从二进流加载数据,详细说明如下: 参数 说明 IMxDrawBinStream* pBinStream ...

  2. 牛客多校Round 9

    Solved:1 rank:112 E. Music Game 题解说有个非简化的原题 bzoj4318 #include <bits/stdc++.h> using namespace ...

  3. Ajax 调用案例及错误捕捉

    function postFunc() { var scoreResultStr = readyData(); $.ajax({ type: "post", url: " ...

  4. 代码分析工具splint安装介绍

    官网 http://www.splint.org/ splint能干什么? splint是一个静态检查C语言代码安全弱点和编写错误的开源程序.(不支持C++) splint会进行多种常规检查,包括 空 ...

  5. 总结struts2 iterator status的用法

    1:#status.odd 是否奇数行 2:#status.count 当前行数 3:#status.index 当前行的序号,从0开始『#status.count=#status.index+1』 ...

  6. 解决移动端 footer fixd 定位被键盘顶起来的方案

    直接上代码: $(document).ready(function () { var u = navigator.userAgent; var isAndroid = u.indexOf('Andro ...

  7. 洛谷——P3919 【模板】可持久化数组(可持久化线段树/平衡树)

    P3919 [模板]可持久化数组(可持久化线段树/平衡树) 题目背景 UPDATE : 最后一个点时间空间已经放大 标题即题意 有了可持久化数组,便可以实现很多衍生的可持久化功能(例如:可持久化并查集 ...

  8. 洛谷——P1156 垃圾陷阱

    P1156 垃圾陷阱 题目描述 卡门――农夫约翰极其珍视的一条Holsteins奶牛――已经落了到“垃圾井”中.“垃圾井”是农夫们扔垃圾的地方,它的深度为D(2 \le D \le 100)D(2≤D ...

  9. LCS(HDU_5495 循环节)

    传送门:LCS 题意:给出两个序列an和bn,想在给出一个序列pn,问经过a[p1],,,,a[pn]和b[p1],,,b[pn]变换后序列a和序列b的最长公共子序列的长度是多少. 思路:对a[i]- ...

  10. try catch影响Spring事务吗?

    对于这个问题有两种情况: 1.catch只打印异常,不抛出异常 try { 数据库做添加订单表; /; 数据库减少库存; }catch (Exception e){ e.printStackTrace ...