คุณจะใช้ javax.smartcardio เพื่อตรวจจับการ์ด desfire ได้อย่างไร

ฉันได้รวบรวมตัวอย่างโค้ดต่อไปนี้เพื่อตรวจจับสมาร์ทการ์ด Mifare โดยใช้ไลบรารี javax.smartcardio รหัสนี้ใช้งานได้ดีกับประเภท Mifare ที่ระบุไว้

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();
    }
}

ฉันใช้ทรัพยากรต่อไปนี้เพื่อรวบรวมโค้ดนี้:

ฉันต้องการใช้ความคิดเห็น TODO เพื่อตรวจจับการ์ด Desfire ถ้าฉันวางการ์ด Desfire ไว้บน read รหัสนี้เพิ่งส่งออก:

Place card on the reader
ATR=3B8180018080

ฉันพบคำถามนี้ กำหนดประเภทการ์ดจาก ATR ซึ่งช่วยได้นิดหน่อย แต่ฉันขาดอะไรบางอย่างไป . HistoricalByte สำหรับการ์ดที่ต้องการคือ 0x80 ซึ่งฉันไม่สามารถหาข้อมูลใดๆ ได้

ถ้าเป็นไปได้ ฉันขอขอบคุณตัวอย่างโค้ดข้างต้นที่ขยายออกไปเพื่อให้สามารถตรวจจับประเภทการ์ด Desfire ได้


person bludginozzie    schedule 17.01.2017    source แหล่งที่มา
comment
แล้ว ATS แบบกำหนดเองสำหรับการ์ดของคุณล่ะ? หรือส่ง GetVersion? หรือส่งคำสั่งบางอย่างใน DESFire ดั้งเดิมแทนการห่อ ฉันไม่ได้มาพร้อมกับตัวเลือกอื่นเนื่องจากเป็น ISO14443-4A แม้จะใช้ SAK (ไม่มีใน Java) คุณก็อาจพบการชนกัน   -  person jlanza    schedule 18.01.2017
comment
ขอบคุณสำหรับข้อเสนอแนะของคุณ ฉันไม่แน่ใจว่าจะส่ง ATS โดยใช้ Java ได้อย่างไร และไม่แน่ใจว่าจะใช้อย่างไรเพื่อให้แน่ใจว่าการ์ดนั้นเป็นการ์ด Desfire ฉันคิดว่าจะใช้ GetVersion แต่รู้สึกเหมือนเป็นการแฮ็ก!   -  person bludginozzie    schedule 20.01.2017
comment
ATS จะมีไว้สำหรับการ์ดของคุณโดยเฉพาะ ไม่ใช่ DESFire หรืออย่างน้อยฉันก็คิดอย่างนั้น จากนั้นเป็นสิ่งที่คุณกำหนดค่าบนการ์ดของคุณ เกี่ยวกับ GetVersion ในฐานะแฮ็ก ฉันคิดว่าเมื่อพิจารณาว่าเป็นการ์ดประเภท 4A มันคงเป็นเรื่องยาก จริงๆ แล้ว บางคนสามารถใช้คำสั่งที่คล้ายกันบน JavaCard และปลอมว่าเป็นการ์ด DESFire :(   -  person jlanza    schedule 20.01.2017
comment
smartcard-atr.appspot.com โดย Ludovic Rousseau ค่อนข้างดีที่จะจับคู่ ATR กับการ์ด ยังมีไพ่ที่แตกต่างกันมาก โดยมี ATR เท่ากัน ดังนั้นจึงไม่เพียงพอที่จะระบุไพ่ของคุณ   -  person Daniel Heldt    schedule 31.01.2017


คำตอบ (1)


คำตอบในการรีเซ็ต (ATR) น่าจะเป็นข้อบ่งชี้ที่ดีว่าคุณมีการ์ดใบใด SPEC ที่คุณติดตามเรียกว่า "7816-3" ส่วนที่ 8 จริงๆ แล้วมันเป็น Spec ที่ต้องเสียเงิน แต่ถ้าคุณใช้ Google ล่ะก็...

อย่างไรก็ตาม ข้อกำหนดของ SIM นั้นซับซ้อนในการทำความเข้าใจ มีการกำหนดไว้อย่างดี แต่คุณต้องลงไปที่ระดับบิตเพื่อทำความเข้าใจอย่างถ่องแท้

ATR ถูกถอดรหัสเป็นไบต์ มาถอดรหัส ATR เฉพาะของคุณกัน:

ไบต์ 1 เรียกว่า "TS" ซึ่งถูกกำหนดให้เป็น 3B หรือ 3F โดยที่ 3F หมายถึง "แบบแผนผกผัน" ที่ใช้ และ 3B "แบบแผนโดยตรง"

Byte2 เรียกว่า "T0" ซึ่งถูกกำหนดให้เป็น "อักขระรูปแบบ" แทะแรกของไบต์ "8" นี้หมายถึงพารามิเตอร์ Y1 และแทะที่สองหมายถึงพารามิเตอร์ "K" แทปแรก "T0" ของคุณ Y1 = 8 และแทปที่สอง K = 1 พารามิเตอร์ Y1 8 = (ในรูปแบบไบนารี่) 1,000 หมายถึงมีเพียงพารามิเตอร์ TA1 เท่านั้นที่จะตามมา ถ้าเป็น 9 = (ในรูปแบบไบนารี่) 1001 หมายถึง TA1 เปิดอยู่ (1) TB1 ปิดอยู่ (0) TC1 ปิดอยู่ (0) และ TD1 เปิดอยู่ (1) K กำหนดจำนวนไบต์ในอดีต เช่น 1 ไบต์ในอดีตในกรณีของคุณ

หากต้องการสรุปเรื่องยาว ใช่ "80" คือไบต์ประวัติของคุณ (กำหนดในข้อมูลจำเพาะ 7816-4) 80 เป็นไบต์ประวัติพื้นฐานที่สุดที่คุณมีได้ 80 คือ "ตัวบ่งชี้หมวดหมู่/สถานะ" และทั้ง 80 รายการถูกกำหนดให้หมายถึง:

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

คำหลักคือ "อาจมีอยู่" เช่น ในกรณีของคุณ พวกเขาได้ตัดสินใจที่จะไม่รวมข้อมูลเพิ่มเติมใดๆ

กลับมาที่คำถามของคุณ การตรวจสอบ ATR ที่ตรงกับค่าที่แน่นอน "3B8180018080" น่าจะเพียงพอที่จะระบุการ์ด DESfire ได้ อย่างไรก็ตาม ในแอปพลิเคชันของฉัน ฉันยังได้ใช้การมีอยู่ของไฟล์เฉพาะ (เช่น พบเฉพาะในการ์ด desfire) เนื้อหาของไฟล์ หรือความพร้อมของแอปพลิเคชันเฉพาะของการ์ดโดย AID เพื่อจำแนกประเภทการ์ดได้แม่นยำยิ่งขึ้น

person QuickPrototype    schedule 25.01.2017