Mifare Ultra Light 非接觸式IC卡髮卡總結
概述:
1、 容量512bit,分為16個page,每個page佔4byte
2、 每個page可以通過程式設計的方式鎖定為只讀功能
3、 384位(從page4往後)使用者讀寫區域
4、 唯一7位元組物理卡號(page0前3個byte加page1)
儲存結構:
頁號 |
Byte0 |
Byte1 |
Byte2 |
Byte3 |
說明 |
0 |
SN0 |
SN1 |
SN2 |
BCC0 |
只讀,存放卡的序列號:Page0前3位元組+整個Page1 |
1 |
SN3 |
SN4 |
SN5 |
SN6 |
|
2 |
BCC1 |
保留 |
LOCK0 |
LOCK1 |
只讀,通過設定LOCK0和LOCK1可以講16個page設為只讀 |
3 |
OTP0 |
OTP1 |
OTP2 |
OTP3 |
可讀寫,一次性交易計數器,不可逆 |
4 |
Data0 |
Data1 |
Data2 |
Data3 |
可讀寫,資料存放區域 |
5 |
Data0 |
Data1 |
Data2 |
Data3 |
|
6 |
Data0 |
Data1 |
Data2 |
Data3 |
|
7 |
Data0 |
Data1 |
Data2 |
Data3 |
|
8 |
Data0 |
Data1 |
Data2 |
Data3 |
|
9 |
Data0 |
Data1 |
Data2 |
Data3 |
|
10 |
Data0 |
Data1 |
Data2 |
Data3 |
|
11 |
Data0 |
Data1 |
Data2 |
Data3 |
|
12 |
Data0 |
Data1 |
Data2 |
Data3 |
|
13 |
Data0 |
Data1 |
Data2 |
Data3 |
|
14 |
Data0 |
Data1 |
Data2 |
Data3 |
|
15 |
Data0 |
Data1 |
Data2 |
Data3 |
總的來說,你可以把UltraLight卡簡單地看成是一種儲存介質,對它的操作也就是對扇區中每個Page的讀取和寫入的過程。
UltraLight卡的發卡流程:
第一步:尋卡
dc_card(icdev,cardMode, snr)
dc_anticoll2(icdev, 0, snr2)
dc_select2(icdev,snr2, size)
第二步:寫卡
獲得想要寫入卡片的資料(十六進位制字串形式),呼叫dc_write_hex函式,寫入對應page
關於這個函式有個比較怪的問題,文件中規定,對於Ultralight卡,一次必須寫入4個位元組,也就是一個Page,但你仍需將你寫入的資料以後補0的方式補足16位元組,儘管它實際寫入的只是前4個位元組。自己寫的功能函式:
''' <summary> ''' 將進位制串寫入指定地址的卡片記憶體中 ''' </summary> ''' <param name="start">要寫入的起始塊地址</param> ''' <param name="finish">要寫入的結束塊地址</param> ''' <param name="dataBufHex">要寫入的串</param> ''' <returns>寫卡是否成功</returns> ''' <remarks></remarks> Private Function Write(ByVal start As Short, ByVal finish As Short, ByVal dataBufHex As String) Dim i As Byte '迴圈標記 Write = False '假設dataBufHex為字8節,start為4,finsh為5,但對Ultralight來說,一次只能寫4個位元組,即 '一次只能寫一個塊,因此需要分兩次來寫。雖然每次只能寫四個位元組,但 'dc_write_hex函式規定寫入的資料必須為16位元組,因此需要做右補0操作 For i = 0 To (finish - start) Dim tmp As String tmp = Mid(dataBufHex, i * 8 + 1, 8) '補0 If Len(tmp) < 32 Then tmp = tmp & New String("0", 32 - Len(tmp)) End If Log("往Page" & (start + i) & "中寫資料:" & tmp) st = dc_write_hex(icdev, start + i, tmp) If (st <> 0) Then '寫卡失敗 Write = False Exit Function End If Next Write = TrueEnd Function
第三步:讀卡
發好卡後,需要驗證寫入的資料是否正確,這時你就需要呼叫dc_read_hex函式讀入卡片中的資料,有例子:
st = dc_read_hex(icdev, address, dataBufHex)
這裡icdev是通訊裝置識別符號,address是要讀入的起始頁地址,dataBufHex是存放讀入資料的變數。
dc_read_hex函式一次性讀入16位元組資料,因此dataBufHex字串長度最長為32,但是不管你的dataBufHex設成任何長度(只要不大於32),該函式仍然讀出16位元組資料,只不過它會擷取前面的部分放到dataBufHex中返還給你罷了。
其他:
關於發行驗證碼和交易TAC的計算方法,等過幾天總結了CPU卡和M1卡的發卡流程之後再寫出來。還有就是卡片的應用,我發的UltraLight是拿來作為單程票的,它的消費充值等流程是由其他人來做的,而且跟具體的卡結構有關,不好講。