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.