Какой APDU использовать для чтения / записи записей в теге MIFARE Ultralight NFC? - PullRequest
1 голос
/ 24 мая 2019

Я создаю программное обеспечение VBA для чтения и записи тегов NFC.Мне удалось связаться с тегом, чтобы получить основные данные (например, я получил его идентификатор).Но когда я посылаю APDU для команды READ RECORD, она не работает.Я полагаю, мне нужно отправить команду SELECT FILE раньше;но я думаю, что для этого мне нужен правильный DF.

Я пробовал "00 B2 01 05 00" для команды READ RECORD и "00 A4 00 00 00" для команды SELECT FILE.

VBA
Sub test()
Dim hContext As Long
Dim hCard As Long
Dim retval As Long
Dim readers As String * 256
Dim groups As String * 256
Dim activeprotocol As Long
Dim readerlen As Long
Dim scard_protocol_t0_or_t1 As Long
Dim scard_share_shared As Long
Dim APDU() As Byte
Dim recvbuf() As Byte
Dim recvbuff(256) As ByteArray
Dim recvlen As Long
Dim iosendreq As SCARD_IO_REQUEST
Dim iorecvreq As SCARD_IO_REQUEST
Dim bytRecvAttr As ByteArray
Dim LenAPDU As Long

scard_protocol_t0_or_t1 = 1 Or 2
scard_share_shared = 2 '2  1

retval = SCardEstablishContext(SCARD_SCOPE_USER, 0, 0, hContext)
If retval <> 0 Then
    MsgBox "erreur n." & CStr(retval)
End If

readerlen = 256

retval = SCardListReaders(hContext, groups, readers, readerlen)
If retval <> 0 Then
    MsgBox "erreur n. " & CStr(retval)
End If


Do While hCard = 0
    retval = SCardConnect(hContext, readers, scard_share_shared,         scard_protocol_t0_or_t1, hCard, activeprotocol)
    DoEvents
Loop
If retval <> 0 Then MsgBox "erreur n. " & CStr(retval)

recvlen = 256


Do While State < 2
    retval = SCardStatus(hCard, readers, readerlen, State,     scard_protocol_t0_or_t1, recvbuff(0), recvlen)
    If retval <> 0 Then MsgBox "Erreur n. " & CStr(retval)
    DoEvents
Loop


'retval = SCardGetAttrib(hCard, SCARD_ATTR_ICC_PRESENCE, bytRecvAttr, lRecLen)
'If retval <> 0 Then MsgBox "Erreur n. " & CStr(retval)



iosendreq.dwProtocol = activeprotocol
iosendreq.dwPciLength = Len(iosendreq)
iorecvreq.dwProtocol = activeprotocol
iorecvreq.dwPciLength = Len(iorecvreq)


'recherche de file
ReDim APDU(7)
APDU(0) = &H0    'cla  80
APDU(1) = &HA4  'INs  B2-read record
APDU(2) = &H4   'P1 1-PREMIER RECORD
APDU(3) = &H0   'P2   5-tous les records
APDU(4) = &H2   'longueur de data
APDU(5) = &H0   'a changer pour trouver ID du DF
APDU(6) = &H0   'a changer pour trouver ID du DF
APDU(7) = &H0   'Le


LenAPDU = (UBound(APDU) + 1)
If APDU(LenAPDU - 1) = 0 Then
    ReDim recvbuf(255)
Else
    ReDim recvbuf(APDU(LenAPDU - 1) + 2)
End If
recvlen = UBound(recvbuf) + 1

'this is a loop to test the different DFs
For x = 0 To 255
    For y = 1 To 255
        APDU(5) = x
        APDU(6) = y
        retval = SCardTransmit(hCard, iosendreq, APDU(0), LenAPDU, iorecvreq, recvbuf(0), recvlen)
        If recvbuf(4) > 0 Or recvlen > 2 Then Exit For
    Next
Next

Debug.Print Hex(recvbuf(0)) & "-" & Hex(recvbuf(1)) & "-" & Hex(recvbuf(2)) & "-" & Hex(recvbuf(3)) & "-" & Hex(recvbuf(4)) & "-" & Hex(recvbuf(5)) & "-" & Hex(recvbuf(6)) & "-" & Hex(recvbuf(7)) & " " & recvlen & " CLA:" & APDU(0) & " INS:" & APDU(1) & " P1:" & APDU(2) & " P2:" & APDU(3)


If retval <> 0 Then MsgBox "Erreur n. " & CStr(Hex(retval))

retval = SCardDisconnect(hCard, scad_leave_card)
If retval <> 0 Then MsgBox "erreur n. " & CStr(retval)

retval = SCardReleaseContext(hContext)
If retval <> 0 Then MsgBox "erreur n. " & CStr(retval)

End Sub

1 Ответ

0 голосов
/ 28 мая 2019

MIFARE Сверхлегкие теги не используют команды APDU. Следовательно, вы не можете отправлять какие-либо APDU на сам тег, и тег не поддерживает понятие файлов (EF / DF / MF). Вместо этого PC / SC (бесконтактные) считыватели смарт-карт обычно предоставляют набор APDU, которые могут быть отправлены считывателю и которые преобразователь переводит в команды MIFARE Ultralight. Эти команды APDU, которые обрабатываются читателем, обычно начинаются с байта класса &HFF.

Если в ридере реализованы стандартные расширения PC / SC для доступа к бесконтактным картам памяти, APDU ридера для чтения с тегов Ultralight будет выглядеть так:

FF B0 00XX 10
        ^^
         \-------- Block number

Следовательно, ваш APDU будет выглядеть так:

ReDim APDU(5)
APDU(0) = &HFF  'CLA  0xFF = PC/SC READER COMMAND
APDU(1) = &HB0  'INS  0xB0 = READ BINARY
APDU(2) = &H00  'P1   0x00
APDU(3) = &H00  'P2   block number (potentially also in P1 if more than 255)
APDU(4) = &H10  'Le   0x10 = 16 bytes (= 4 blocks) expected, which is the standard read size for the native Ultralight READ command
...