天天看點

深入了解7816(3)-----關于T=0

深入了解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,然後終端再利用取響應的指令,獲得卡片傳回的響應資料。