Mifare Ultra Light 非接触式IC卡发卡总结

概述:

1、  容量512bit,分为16page,每个page4byte

2、  每个page可以通过编程的方式锁定为只读功能

3、  384(page4往后)用户读写区域

4、  唯一7字节物理卡号(page03bytepage1

存储结构:

页号

Byte0

Byte1

Byte2

Byte3

说明

0

SN0

SN1

SN2

BCC0

只读,存放卡的序列号:Page03字节+整个Page1

1

SN3

SN4

SN5

SN6

2

BCC1

保留

LOCK0

LOCK1

只读,通过设置LOCK0LOCK1可以讲16page设为只读

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个字节。自己写的功能函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    ''' <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 = True
End 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是拿来作为单程票的,它的消费充值等流程是由其他人来做的,而且跟具体的卡结构有关,不好讲。

posted @   诚实小郎君  阅读(4855)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
点击右上角即可分享
微信分享提示