javax.smartcardio: jak wysłać rodzime polecenia do karty Desfire?

Tworzę aplikację java komunikującą się z kartą Mifare DESFire za pomocą czytnika bezstykowego PC / SC i interfejsu API javax.smartcardio. Udało mi się wysłać regularne APDU ISO 7816 (CLA, INS, P1-P2, Lc, dane polecenia, Le).

Przeczytałem dalejBlog Ridrixa że karty DESFire (przynajmniej wersja EV1, której używam) obsługują zarówno APDU, jak iNatywne polecenia gdzie większość poleceń ma tylko 1 bajt.

Na przykład „Pobierz wersję" dowództwo:

Command: 60
Response: af 04 01 01 00 02 18 05

Przetestowałem to polecenie za pomocąPC / SC Diag program odSpringCard (dostępny tutaj) i otrzymuję poprawną odpowiedź.

Ale nie mogę wysłać tego polecenia z javax.smartcardio: wydaje się, że ten interfejs API został stworzony dlareal APDU i dlatego nie zezwala na komendy o długości 1 bajta.

Oto co zrobiłem:

public static void main(String[] args){
    TerminalFactory factory = TerminalFactory.getDefault();
    CardTerminals terminalList = factory.terminals();

    try {
        CardTerminal ct = terminalList.list().get(0);       
        ct.waitForCardPresent(0);
        Card card = ct.connect("*");
        CardChannel channel = card.getBasicChannel();

        byte[] command = { 0x60 };

        channel.transmit(new CommandAPDU(command));
    } catch (CardException e) {
        e.printStackTrace();
    }
}

Daje mi następujący błąd:

Exception in thread "main" java.lang.IllegalArgumentException: apdu must be at least 4 bytes long
    at javax.smartcardio.CommandAPDU.parse(Unknown Source)
    at javax.smartcardio.CommandAPDU.<init>(Unknown Source)

Próbowałem jedynego (AFAIK) innego sposobu wysłania polecenia:

        ByteBuffer command = ByteBuffer.allocate(1);
        command.put((byte) 0x60);

        ByteBuffer response = ByteBuffer.allocate(512);

        channel.transmit(command, response);

i uzyskać podobny błąd:

Exception in thread "main" java.lang.IllegalArgumentException: Command APDU must be at least 4 bytes long
    at sun.security.smartcardio.ChannelImpl.checkManageChannel(Unknown Source)
    at sun.security.smartcardio.ChannelImpl.doTransmit(Unknown Source)
    at sun.security.smartcardio.ChannelImpl.transmit(Unknown Source)

Czy znasz jakiś sposób na wysłanie tego rodzaju polecenia za pomocą javax.smartcardio lub czegoś innego?

Wiem, że to możliweowinąć te polecenia, ale wolałbym używać (prostszych) poleceń natywnych.

Dzięki.

questionAnswers(3)

yourAnswerToTheQuestion