ATKey.Karta NFC Referencje dla programistów
ATKey.Karta NFC to karta inteligentna obsługująca FIDO2, uwierzytelnianie odciskiem palca, weryfikację tożsamości osobistej (PIV) oraz format wymiany danych NFC (NDEF) za pośrednictwem apletów. Deweloperzy mogą używać poleceń jednostki danych protokołu aplikacji (APDU) do interakcji z apletami i tworzenia niestandardowych aplikacji lub integracji. ATKey.Karta NFC z istniejącym stosem.
rozdziały
ATKey.Karta NFC Odniesienia do poleceń PIV APDU
Pobierz metadane biograficzne
Z ATKey.Karta NFC Użytkownicy mogą zabezpieczyć swoje logowanie PIV uwierzytelnianiem odciskiem palca. Aby to zrobić, ATKey.Karta NFC należy skonfigurować dane biometryczne za pomocą apletu FIDO2. Aby sprawdzić, czy rejestracja danych biometrycznych została ukończona, należy użyć polecenia Pobierz metadane biograficzne może być użyty.
Informacje o poleceniu APDU
| CLA | INS | P1 | P2 | Lc | Dane | Le |
|---|---|---|---|---|---|---|
| 00 | F7 | 00 | 96 | (nieobecny) | (nieobecny) | (nieobecny) |
Informacje o APDU w odpowiedzi
Długość całkowita: 10 + 2
Długość danych: 10
| Dane | SW1 | SW2 |
|---|---|---|
| metadane biologiczne jako zestaw TLV | 90 | 00 |
Dane składają się z zestawu znaczników TLV (Typ-Długość-Wartość). Możliwe prawidłowe znaczniki (T w TLV) są wymienione w poniższej tabeli. Długość (L w TLV) wynosi jeden. Wartości (V w TLV) zależą od znaczników opisanych w poniższej tabeli.
| etykieta | Imię i nazwisko | Znaczenie | Dane |
|---|---|---|---|
| 07 | Jest skonfigurowany | stan konfiguracji weryfikacji biometrycznej (czyli czy odciski palców zostały zarejestrowane) | Dane 1B - 01 (skonfigurowane) - 00 (nie skonfigurowano) |
| 06 | Pozostałe próby | wskazuje, ile prób dopasowania biometrycznego pozostało | Dane 2B - 1 bajt określa maksymalną liczbę ponownych prób biometrycznych, obecnie wynosi 08. - 2. bajt to liczba pozostałych prób, zakres wartości wynosi 00-08, a 00 oznacza, że korzystanie z funkcji biometrycznych w PIV jest zablokowane. |
| 08 | Czy ochrona biologiczna dla pinów jest włączona czy nie | wskazuje, czy ochrona Bio-for-pin jest włączona, czy nie | Dane 1B - 01 (włączone) - 00 (wyłączone) |
Włącz/wyłącz ochronę biologiczną dla pinów
Aby włączyć lub wyłączyć ochronę biometryczną dla logowań PIV, można użyć tego polecenia.
| CLA | INS | P1 | P2 | Lc | Dane | Le |
|---|---|---|---|---|---|---|
| 00 | 20 | 00 | 96 | 09 | 8B-PIN + 1B-Val | (nieobecny) |
1B-Val ma inne intencje, jak podano poniżej.
01 - Włącz ochronę biologiczną dla pinów
00 - Wyłącz ochronę biologiczną dla pinów.
Uwaga: funkcja ochrony Bio-for-pin zostanie automatycznie wyłączona w przypadku wystąpienia dwóch następujących zdarzeń:
PIV-Reset
Bio jest usuwane, tzn. aplet FIDO2 usuwa je lub przetwarza FIDO2-Reset.
Informacje o APDU w odpowiedzi
| Wynik | Dane | SW1 | SW2 |
|---|---|---|---|
| sukces | (brak danych) | 90 | 00 |
| Niepowodzenie, brak zarejestrowanych danych biometrycznych | (brak danych) | 69 | 86 |
| Błąd, nieprawidłowy PIN | (brak danych) | 63 | CX |
Jeżeli wprowadzony PIN jest nieprawidłowy, wyświetlony zostanie błąd 63 CX, gdzie X to liczba pozostałych prób. Jeśli nie ma już prób, zwracany jest błąd 0x6983.
.
Zweryfikuj dane biometryczne
Aby kontynuować, użytkownik musi potwierdzić swój odcisk palca na karcie.
| CLA | INS | P1 | P2 | Lc | Dane | Le |
|---|---|---|---|---|---|---|
| 00 | 20 | 00 | 96 | (nieobecny) | (nieobecny) | (nieobecny) |
Informacje o APDU w odpowiedzi
| Wynik | Dane | SW1 | SW2 |
|---|---|---|---|
| sukces - Długość całkowita 16 + 2 - Długość danych: 16 |
16B tymczasowy PIN | 90 | 00 |
| Nieudane dopasowanie biometryczne | (brak danych) | 63 | CX |
| Oczekiwanie na przekroczenie limitu czasu danych biometrycznych (około 1400 ms) |
(brak danych) | 69 | 85 |
| Brak zarejestrowanych danych biometrycznych | (brak danych) | 69 | 86 |
Jeżeli dopasowanie biometryczne się nie powiedzie, błąd wynosi 63 CX, gdzie X to liczba pozostałych prób. Jeśli nie ma już żadnych prób, weryfikacja biometryczna jest blokowana, a zwracany jest błąd 0x6983.
Zweryfikuj tymczasowy PIN
To polecenie należy zastosować po pomyślnej odpowiedzi na polecenie Verify Bio, które ustanowiłoby tymczasowy kod PIN.
| CLA | INS | P1 | P2 | Lc | Dane | Le |
|---|---|---|---|---|---|---|
| 00 | 20 | 00 | 96 | 10 | tymczasowy PIN | (nieobecny) |
Informacje o APDU w odpowiedzi
| Wynik | Dane | SW1 | SW2 |
|---|---|---|---|
| sukces | (brak danych) | 90 | 00 |
| Nieprawidłowy tymczasowy PIN | (brak danych) | 63 | CX |
Jeżeli wprowadzony tymczasowy PIN jest nieprawidłowy, wówczas błąd to 63 CX, gdzie X Liczba pozostałych prób jest współdzielona z PIV-PIN. Jeśli nie ma już prób, zwracany jest błąd 0x6983.
Próby resetowania danych biometrycznych
| CLA | INS | P1 | P2 | Lc | Dane | Le |
|---|---|---|---|---|---|---|
| 00 | 2C | 00 | 96 | 10 | 8B Aktualny PUK + 8B jakiekolwiek dane |
(nieobecny) |
Drugi głos dla Danych (8B dowolne dane) nie jest używany w tym poleceniu, ale zachowuje spójny format polecenia z ponownymi próbami resetowania kodu PIN.
Informacje o APDU w odpowiedzi
| Wynik | Dane | SW1 | SW2 |
|---|---|---|---|
| sukces | (brak danych) | 90 | 00 |
| Nieprawidłowy kod PUK | (brak danych) | 63 | CX |
Jeżeli wprowadzony kod PUK jest niepoprawny, wówczas błąd wynosi 63 CX, gdzie X to liczba pozostałych prób. Jeśli nie ma już prób, zwracany jest błąd 0x6983.
Ustanawianie zasad weryfikacji odcisków palców
Zasady weryfikacji odcisków palców można wybrać dla dowolnego slotu i ustawić je jako:
Nigdy: weryfikacja odcisku palca nie jest nigdy potrzebna podczas korzystania z tego slotu
Zawsze: weryfikacja odcisków palców jest wymagana przy każdym użyciu
Jednorazowo: weryfikacja odcisku palca jest wymagana tylko raz podczas każdej sesji wyłączania i ponownego zasilania
Ustaw klucz zarządzania (0xFF)
| CLA | INS | P1 | P2 | Lc | Dane | Le |
|---|---|---|---|---|---|---|
| 00 | FF | FF | polityka dotycząca dotyku: - FF: Nigdy - FE: Zawsze - FD: Kiedyś |
1B | nowe kluczowe dane zarządcze | (nieobecny) |
Wygeneruj asymetryczną parę kluczy (0x47)
| CLA | INS | P1 | P2 | Lc | Dane | Le |
|---|---|---|---|---|---|---|
| 00 | 47 | 00 | numer slotu | len danych | [Klimatyzacja 80 01 …] [AA 01 … ] [AB 01 - 01: Nigdy - 02: Zawsze - 03: [Kiedyś] |
(nieobecny) |
Importuj asymetryczną parę kluczy (0xFE)
| CLA | INS | P1 | P2 | Lc | Dane | Le |
|---|---|---|---|---|---|---|
| 00 | FE | ALG | numer slotu | len danych | zestaw TLV zawierający kluczowe elementy [AA 01 … ] [AB 01 - 01: Nigdy - 02: Zawsze - 03: Raz] |
(nieobecny) |
Informacje o APDU w odpowiedzi
Poniżej przedstawiono odpowiedź na Polecenie APDU Info (0xF7) z P2 = numer slotu.
Należy pamiętać, że znaczenie wartości zasad PIN i Touch jest różne.
| etykieta | Imię i nazwisko | Znaczenie | Dane | Sloty |
|---|---|---|---|---|
| 02 | Polityka | Zasady dotyczące PIN-u i dotyku | KOŁEK: - 00: Domyślnie = Nigdy - 01: Nigdy - 02: Kiedyś - 03: Zawsze Dotknąć: - 00: Domyślnie = Nigdy - 01: Nigdy - 02: Zawsze - 03: Kiedyś |
9a, 9b, 9c, 9d, 9e, f9, 82~ |
ATKey.Karta NFC Odniesienia do poleceń NDEF APDU
ATKey.Karta NFC Odniesienia do poleceń NDEF APDU
Funkcja NDEF (NFC Data Exchange Format) w ATKey.Karta wykorzystuje Aplet Javacard emulować komunikat NDEF zgodny z NFC Specyfikacja działania tagu typu 4 NFC Forum ale tylko minimalna liczba poleceń APDU określona w specyfikacji NDEF. Aplet NDEF ma własny identyfikator aplikacji i jest przetwarzany oddzielnie.
Identyfikator NDEF: 0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01
Dostępny ATKey.Card NFC SKU
Wybierz Plik oraz Czytaj dane: 630B02, 630B03, 630B04, 630B12, 630B13
Wybierz Plik, Odczyt danych i zapis danych: 630B04, 630B13
Obsługiwane polecenia APDU
W tym aplecie NDEF zdefiniowano 2 pliki, ale ten dokument skupia się tylko na części danych NDEF.
0xE103 - Możliwości NDEF
0xE104 - Dane NDEF
| Polecenia | CLA | INS | P1 | P2 | Lc | Dane | Le |
|---|---|---|---|---|---|---|---|
| Wybierz plik danych NDEF | 0x00 | 0xA4 | 0x00 | 0x0C | 0x02 | 0xE1 0x04 | (nieobecny) |
| Czytaj dane | 0x00 | 0xB0 | 0x00 | 0x00 | (nieobecny) | (nieobecny) | 0x00 |
| Napisz dane | 0x00 | 0xD6 | 0x00 | 0x00 | Nagłówek rekordu 6B NDEF + nB NDEF Rekordowy ładunek |
Ładunek rekordu NDEF | (nieobecny) |
Nagłówek rekordu NDEF jest zdefiniowany w następujący sposób:
| Pole | Rozmiar | OPIS |
|---|---|---|
| etykieta | 1 | Zawsze 0 |
| Długość | 1 | Długość rekordu NDEF |
| Nagłówek NDEF | 1 | Zawsze 0xD1: Początek+koniec wiadomości, krótki rekord, format nazwy typu = znane forum NFC |
| Długość typu rekordu | 1 | Zawsze 1 |
| Długość ładunku | 1 | |
| Typ | 1 | Globalny typ forum NFC „U” = 0x55 |
| Ładunek | (różni się) | Rzeczywista wiadomość NDEF. O długości „długości ładunku” bajtów. |
UWAGA. Pierwszy bajt danych rekordu NDEF ma wskazywać następujący protokół danych. W tym dokumencie używa się 0x04 co znaczy „https://„na przykład wartość.
Przykład
Poniżej przykład demonstracyjny jak używać OpenSC aby wykonać poniższe polecenia
Wybierz aplet z NDEF AID
Wybierz plik danych NDEF do użycia
Zapisz dane NDEF https://authentrend.com
Odczytaj dane NDEF
opensc-tool.exe -c default -r 0 -s 00:A4:04:00:07:D2:76:00:00:85:01:01 -s 00:A4:00:0C:02:E1:04 -s 00:D6:00:00:16:00:14:D1:01:10:55:04:61:75:74:68:65:6E:74:72:65:6E:64:2E:63:6F:6D -s 00:B0:00:00:00
Sending: 00 A4 04 00 07 D2 76 00 00 85 01 01
Received (SW1=0x90, SW2=0x00)
Sending: 00 A4 00 0C 02 E1 04
Received (SW1=0x90, SW2=0x00)
Sending: 00 D6 00 00 16 00 14 D1 01 10 55 04 61 75 74 68 65 6E 74 72 65 6E 64 2E 63 6F 6D
Received (SW1=0x90, SW2=0x00)
Sending: 00 B0 00 00 00
Received (SW1=0x90, SW2=0x00):
00 14 D1 01 10 55 04 61 75 74 68 65 6E 74 72 65 .....U.authentre
6E 64 2E 63 6F 6D 00 00 00 00 00 00 00 00 00 00 nd.com..........
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
Jak wysłać polecenie do interfejsu AT-USB-HID? Przykładowy kod w sieci
Poniższy przykładowy kod można uruchomić na https://seleniumbase.io/w3schools/.
<!DOCTYPE html>
<script>
const CMD_INIT = 0x86;
const CMD_MSG = 0x83;
var usb_device;
var channel_id = [0xFF, 0xFF, 0xFF, 0xFF];
async function request_hid() {
const filters = [
{
vendorId: 0x31bb,
productId: 0x0635,
usagePage: 0x4154,
},
];
const devices = await navigator.hid.requestDevice({ filters });
usb_device = devices[0];
await usb_device.open();
usb_device.addEventListener("inputreport", (event) => {
const { data, device, reportId } = event;
const cid = data.getUint32(0);
const cmd = data.getUint8(4);
if (cmd == CMD_INIT) {
const cid = data.buffer.slice(14, 4);
channel_id = [data.getUint8(15), data.getUint8(16), data.getUint8(17), data.getUint8(18)];
console.log(`CID: ${channel_id}`);
}
});
//const cmd_get_cid = [0xFF, 0xFF, 0xFF, 0xFF, CMD_INIT, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0];
let nonce = [0, 0, 0, 0, 0, 0, 0, 0];
let packet = new ArrayBuffer(64);
let cmd_get_cid = new Uint8Array(packet);
cmd_get_cid.set(new Uint8Array(channel_id), 0);
cmd_get_cid.set(new Uint8Array([CMD_INIT, 0, nonce.length]), 4);
cmd_get_cid.set(new Uint8Array(nonce), 4 + 3);
await usb_device.sendReport(0x00, cmd_get_cid);
}
async function get_keycode() {
usb_device.addEventListener("inputreport", (event) => {
const { data, device, reportId } = event;
const cid = data.getUint32(0);
const cmd = data.getUint8(4);
if (cmd == CMD_MSG) {
//const keycode = [data.getUint8(15), data.getUint8(16), data.getUint8(17), data.getUint8(18)];
const keycode = data.getUint32(15);
console.log(`Keycode: ${keycode}`);
alert(`Keycode: ${keycode.toString(16)}`);
}
});
//const cmd_get_keycode = [??, ??, ??, ??, CMD_MSG, 0, 19, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x55, 0xAA, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x7C, 0x00, 0x00];
const payload = [0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x55, 0xAA, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x7C, 0x00, 0x00];
let packet = new ArrayBuffer(64);
let cmd_get_keycode = new Uint8Array(packet);
cmd_get_keycode.set(new Uint8Array(channel_id), 0);
cmd_get_keycode.set(new Uint8Array([CMD_MSG, 0, payload.length]), 4);
cmd_get_keycode.set(new Uint8Array(payload), 4 + 3);
await usb_device.sendReport(0x00, cmd_get_keycode);
}
</script>
<html>
<body>
<p>Step 1: </p>
<button onclick="request_hid()">List Devices</button>
<br>
<br>
<p>Step 2: </p>
<button onclick="get_keycode()">Get Keycode</button>
</body>
</html>
