Bagaimana Anda bisa menggunakan javax.smartcardio untuk mendeteksi kartu desfire?

Saya telah mengumpulkan contoh kode berikut untuk mendeteksi kartu pintar Mifare menggunakan perpustakaan javax.smartcardio. Kode ini berfungsi baik untuk tipe Mifare yang terdaftar.

public class DetectCardTester {
    private static final String PROTOCOL = "T=1";

    static Map<String,String> KNOWN_CARD_TYPES = ImmutableMap.<String, String>builder()
        .put("00-01", "Mifare 1K")
        .put("00-02", "Mifare 4K")
        .put("00-03", "Mifare Ultralight")
        .put("00-26", "Mifare Mini")
        .build();

    public static void main(String... args) {
        try {
            final TerminalFactory terminalFactory = SmartcardTerminalFactory.create();
            System.out.println("Place card on the reader");
            final Card card = awaitCard(terminalFactory, 3, SECONDS);
            final ATR atr = card.getATR();
            final byte[] bytes = atr.getBytes();

            System.out.println("ATR=" + String.valueOf(Hex.encodeHex(bytes, false)));

            if (bytes != null && bytes.length > 13) {
                String typeCode = String.format("%02X-%02X", bytes[13], bytes[14]);
                if (KNOWN_CARD_TYPES.containsKey(typeCode)) {
                    System.out.println("Known Type:" + KNOWN_CARD_TYPES.get(typeCode));
                } else {
                    System.out.println("Unknown Type:" + typeCode);
                }
            }
            // TODO: Detect Desfire Card

        } catch (Throwable t) {
            t.printStackTrace();
        }
    }


    public static Card awaitCard(final TerminalFactory terminalFactory, final int qty, final TemporalUnit unit) throws CardException {

        LocalDateTime timeout = now().plus(qty, unit);
        while (now().isBefore(timeout)) {
            Optional<CardTerminal> cardTerminal = getCardPresentTerminal(terminalFactory);
            if (cardTerminal.isPresent()) {
                return cardTerminal.get().connect(PROTOCOL);
            }
        }
        throw new CardNotPresentException("Timed out waiting for card");
    }

    private static Optional<CardTerminal> getCardPresentTerminal(final TerminalFactory terminalFactory) throws CardException {
        List<CardTerminal> terminals = terminalFactory.terminals().list();

        for (CardTerminal cardTerminal : terminals) {

            if (cardTerminal.isCardPresent()) {
                return Optional.of(cardTerminal);
            }
        }

        for (CardTerminal cardTerminal : terminals) {

            // waitForCardPresent / Absent doesn't work with some Jacax.smartcard.io implementations
            // i.e. OSX http://bugs.java.com/view_bug.do?bug_id=7195480
            // This is why we have the imediate check above
            if (cardTerminal.waitForCardPresent(250)) {
                return Optional.of(cardTerminal);
            }
        }

        return Optional.empty();
    }
}

Saya menggunakan sumber daya berikut untuk menyatukan kode ini:

Saya ingin menerapkan komentar TODO untuk mendeteksi kartu Desfire. Jika saya menempatkan kartu Desfire saat membaca kode ini, outputnya hanya seperti ini:

Place card on the reader
ATR=3B8180018080

Saya menemukan pertanyaan ini Tentukan jenis kartu dari ATR yang sedikit membantu tetapi saya melewatkan sesuatu . HistoricalByte untuk kartu yang dimaksud adalah 0x80 dan saya tidak dapat menemukan informasi apa pun.

Jika memungkinkan saya akan sangat menghargai contoh kode di atas yang diperluas sehingga dapat mendeteksi jenis kartu Desfire.


person bludginozzie    schedule 17.01.2017    source sumber
comment
Bagaimana dengan ATS khusus untuk kartu Anda? Atau mengirimkan GetVersion? Atau mengirimkan beberapa perintah dalam DESFire asli alih-alih dibungkus. Saya tidak memberikan opsi lain karena ini adalah ISO14443-4A. Bahkan menggunakan SAK (tidak tersedia di Java) Anda mungkin menemukan tabrakan.   -  person jlanza    schedule 18.01.2017
comment
Terima kasih atas saran Anda. Saya tidak yakin bagaimana cara mengirim ATS menggunakan Java dan juga tidak yakin bagaimana cara menggunakannya untuk memastikan kartu tersebut adalah kartu Desfire. Saya sempat terpikir untuk menggunakan GetVersion, namun rasanya seperti diretas!   -  person bludginozzie    schedule 20.01.2017
comment
ATS akan khusus untuk kartu Anda bukan DESFire atau setidaknya menurut saya begitu. Kemudian, itu adalah sesuatu yang Anda konfigurasikan pada kartu Anda. Mengenai GetVersion sebagai peretasan, menurut saya mengingat ini adalah kartu tipe 4A maka akan sulit. Sebenarnya, seseorang dapat mengimplementasikan perintah serupa di JavaCard dan memalsukan itu adalah kartu DESFire :(   -  person jlanza    schedule 20.01.2017
comment
smartcard-atr.appspot.com oleh Ludovic Rousseau cukup bagus untuk memetakan ATR ke kartu; Masih ada kartu yang sangat berbeda, memiliki ATR yang sama, sehingga tidak cukup untuk mengidentifikasi kartu Anda.   -  person Daniel Heldt    schedule 31.01.2017


Jawaban (1)


Answer To Reset (ATR) mungkin merupakan indikasi yang baik tentang kartu apa yang Anda miliki. SPEC yang Anda kejar disebut "7816-3" bagian 8. Sebenarnya ini adalah spesifikasi berbayar tetapi jika Anda google dengan baik...

Bagaimanapun, spesifikasi SIM rumit untuk dipahami, sudah didefinisikan dengan baik tetapi Anda perlu turun ke tingkat bit untuk memahaminya sepenuhnya.

ATR didekodekan dalam byte, mari dekode ATR spesifik Anda:

Byte1 Disebut "TS", didefinisikan sebagai 3B atau 3F dimana 3F berarti "konvensi terbalik" yang digunakan dan 3B "konvensi langsung"

Byte2 Disebut "T0" , ini didefinisikan sebagai "karakter format". gigitan pertama dari byte "8" ini mengacu pada parameter Y1 dan gigitan kedua mengacu pada parameter "K". Nibble pertama "T0" Anda Y1 = 8 dan nibble kedua K = 1 Parameter Y1 8 = (dalam biner) 1000 artinya hanya parameter TA1 yang diikuti. jika 9 = (dalam biner) 1001 berarti TA1 hidup(1) TB1 mati (0) TC1 mati (0) dan TD1 hidup (1). K mendefinisikan jumlah byte historis, yaitu 1 byte historis dalam kasus Anda.

Singkatnya, ya "80" adalah byte historis Anda (didefinisikan dalam spesifikasi 7816-4). 80 adalah byte sejarah paling dasar yang dapat Anda miliki. 80 adalah "indikator kategori/status" dan semua 80 diartikan sebagai:

A status indicator (one, two or three bytes) may be present in an optional COMPACT-TLV data object

kata kuncinya adalah "mungkin ada" yaitu dalam kasus Anda mereka telah memutuskan untuk tidak memasukkan informasi lebih lanjut.

Kembali ke pertanyaan Anda, Memeriksa ATR yang cocok dengan nilai persis "3B8180018080" sudah cukup untuk mengidentifikasi kartu DESfire. Namun dalam aplikasi saya, saya juga menggunakan keberadaan file tertentu (yaitu hanya ditemukan pada kartu desfire), isi file, atau ketersediaan aplikasi khusus kartu oleh AID untuk mengklasifikasikan kartu dengan lebih akurat.

person QuickPrototype    schedule 25.01.2017