卡片和終端之間的資料傳輸是通過命令響應的方式進行的,卡片只能被動地接收命令,並且給出響應。所有的命令都是以命令頭開始,而該命令被完整地執行後(無論結果對錯),必須以包含狀態字(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
卡片和終端之間的資料傳輸是通過命令響應的方式進行的,卡片只能被動地接收命令,並且給出響應。所有的命令都是以命令頭開始,而該命令被完整地執行後 無論結果對錯 必須以包含狀態字 sw1 sw2 的響應結束。卡片和終端之間如何具體進行資料傳輸的,就依靠不同的通訊協議來實現,其中主要有t 0 t 1 t c...
深入理解7816(3) 關於T 0
本文 支援原創,傳播知識,僅供學習自用。卡片和終端之間的資料傳輸是通過命令響應的方式進行的,卡片只能被動地接收命令,並且給出響應。所有的命令都是以命令頭開始,而該命令被完整地執行後 無論結果對錯 必須以包含狀態字 sw1 sw2 的響應結束。卡片和終端之間如何具體進行資料傳輸的,就依靠不同的通訊協議...
深入理解7816(4) 關於T 1
本文 支援原創,傳播知識,僅供學習自用。之前說過的t 0協議,基本上相當於是透明的資料,也就是說從應用的角度看,通過t 0傳遞的tpdu資料資訊大都可以直接轉換為對應的apd命令響應資料,位元組 是t 0協議最小的資料傳輸單元。對於t 1協議而言,最小的資料傳輸單元是 資料塊 這個資料塊由若干個位元...