如何使用APDU读取和下载ddd行车记录仪文件?

我正在尝试使用javax.smartcardio. 问题是我在盲目地做大部分事情,因为我找不到关于APDU commands.


目前,我设法打印了卡片类型 ( card: PC/SC card in HID Global OMNIKEY 3x21 Smart Card Reader 0, protocol T=0, state OK) 并读取了卡片识别信息(所选文件0520)。


如何下载行驶记录仪 .ddd 文件?


这是到目前为止的代码:


public static void main(String[] args) {


        try {

            TerminalFactory factory = TerminalFactory.getDefault();

            List<CardTerminal> terminals = factory.terminals().list();

            System.out.println("Terminals: " + terminals);

            // get the first terminal

            CardTerminal terminal = terminals.get(0);

            // establish a connection with the card

            Card card = terminal.connect("T=0");

            System.out.println("card: " + card);

            CardChannel channel = card.getBasicChannel();


            byte[] c1 = hexStringToByteArray(stripCommandSpace("00 A4 04 0C 06 FF544143484F"));

            //byte[] c1 = hexStringToByteArray(stripCommandSpace("FF CA 00 00 00"));

            ResponseAPDU r1 = channel.transmit(new CommandAPDU(c1));

            System.out.println("response: " + byteArrayToHexString(r1.getBytes()));

            byte[] c2 = hexStringToByteArray(stripCommandSpace("00 a4 02 0c 02 05 04"));

            ResponseAPDU r2 = channel.transmit(new CommandAPDU(c2));

            System.out.println("response: " + byteArrayToHexString(r2.getBytes()));

            byte[] c3 = hexStringToByteArray(stripCommandSpace("00 B0 00 01 128"));

            ResponseAPDU r3 = channel.transmit(new CommandAPDU(c3));

            System.out.println("response: " + byteArrayToHexString(r3.getBytes()));

            System.out.println("data: " + byteArrayToHexString(r3.getData()));

我设法识别并读取了驱动程序活动文件 - 我必须将标识符更改为0504如下图所示:

http://img1.mukewang.com/60e5558c0001a6d906630284.jpg

现在我的问题是如何将我得到的字节数组转换为 .ddd 文件

我在我的代码的更新版本中尝试过(见上文),但 .ddd 阅读器告诉我文件已损坏(我使用第三方应用程序将 .ddd 转换为 .txt - 称为readesm)。


慕尼黑8549860
浏览 179回答 1
1回答

慕尼黑的夜晚无繁华

卡驱动中的结构块:结构块是(ICC,IC,Application_Identificacion ........):标头:“文件 2(0501h,0502h ....)字节”+“类型(数据-0 或有符号-1)1 个字节”+“长度 2 个字节”+ 数据(读卡):ICC、IC 和 Card_donwload 不需要签名,所以 0501 到 0522(不是 050e),签名块文件是授权所必需的,但读取字节文件和创建二进制文件不需要。阅读 Fid 的递归:&nbsp;for (Fid fid : Fid.values()) {&nbsp; &nbsp; System.out.println(fid.getId());&nbsp; &nbsp; // not read 03f00 and 0500 not files&nbsp; &nbsp; if(!fid.getId().equals("3f,00") && !fid.getId().equals("05,00")){&nbsp; &nbsp; &nbsp; &nbsp; b = readCard(r, channel, fid.getId());&nbsp; &nbsp; &nbsp; &nbsp; // header block file&nbsp; &nbsp; &nbsp; &nbsp; byte[] htba = OperationHelper.hexToByteAr(fid.getId());&nbsp; &nbsp; &nbsp; &nbsp; byte[] sizeByte = ByteBuffer.allocate(4).putInt(b.length).array();&nbsp; &nbsp; &nbsp; &nbsp; headerBlock[0] = htba[0];&nbsp; &nbsp; &nbsp; &nbsp;// id file byte 1&nbsp; &nbsp; &nbsp; &nbsp; headerBlock[1] = htba[1];&nbsp; &nbsp; &nbsp; &nbsp;// id file byte 2&nbsp; &nbsp; &nbsp; &nbsp; headerBlock[2] = 0;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// type file data&nbsp; &nbsp; &nbsp; &nbsp; headerBlock[3] = sizeByte[2];&nbsp; &nbsp;// size file byte 1&nbsp; &nbsp; &nbsp; &nbsp; headerBlock[4] = sizeByte[3];&nbsp; &nbsp;// size file byte 2&nbsp; &nbsp; &nbsp; &nbsp; try{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fileTGD.write(headerBlock);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fileTGD.write(b);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // add signature file&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!fid.getId().equals("00,02") && !fid.getId().equals("00,05")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; && !fid.getId().equals("C1,00") && !fid.getId().equals("C1,08")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; && !fid.getId().equals("05,0E")){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; performHashFile(r, channel);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; b = signature(r, channel);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sizeByte = ByteBuffer.allocate(4).putInt(b.length).array();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; headerBlock[0] = htba[0];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; headerBlock[1] = htba[1];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; headerBlock[2] = 1;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; headerBlock[3] = sizeByte[2];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; headerBlock[4] = sizeByte[3];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fileTGD.write(headerBlock);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fileTGD.write(b);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }catch (Exception e){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e.printStackTrace();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}读取数据:public static byte[] readCard( ResponseAPDU r, CardChannel channel, String fid){ByteArrayOutputStream dataResponseBuffer = new ByteArrayOutputStream();try {&nbsp; &nbsp; //r = channel.transmit(new CommandAPDU(0x00, 0x84, 0x00, 0x00,&nbsp; OperationHelper.hexToByteAr("6f,07,00,00,00,08,00,00,00,00,00,a4,02,0c,02,05,04")));&nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp;*&nbsp; GetParameters&nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp;*&nbsp; Headers&nbsp; &nbsp; &nbsp;*&nbsp; CLA - 00&nbsp; &nbsp; &nbsp;*&nbsp; INS - A4&nbsp; &nbsp; &nbsp;*&nbsp; P1 - 02&nbsp; &nbsp; &nbsp;*&nbsp; P2 - 0C&nbsp; &nbsp; &nbsp;*&nbsp; DATA - 00,02&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//6C,00,00,00,00,08,01,00,00,00&nbsp; &nbsp; &nbsp;*&nbsp; dataOffset - 00&nbsp; &nbsp; &nbsp;*&nbsp; dataLength - length of trama&nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; //r = channel.transmit(new CommandAPDU(0x00, 0xA4, 0x02, 0x0C,&nbsp; OperationHelper.hexToByteAr("00,02"), 0x00, 0x02));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; if (!fid.equals("00,02") && !fid.equals("00,05"))&nbsp; &nbsp; &nbsp; &nbsp; //select MF - Only positioning&nbsp; &nbsp; &nbsp; &nbsp; r = channel.transmit(new CommandAPDU(0x00, 0xA4, 0x04, 0x0C, OperationHelper.hexToByteAr("ff,54,41,43,48,4f"), 0x00, 0x06));&nbsp; &nbsp; // select EF&nbsp; &nbsp; r = channel.transmit(new CommandAPDU(0x00, APDUCommand.SELECT_FILE.getCommand(), 0x02, 0x0C, OperationHelper.hexToByteAr(fid), 0x00, 0x02));&nbsp; &nbsp; boolean end = true;&nbsp; &nbsp; int p1 = 0x00;&nbsp; &nbsp; int p2 = 0x00;&nbsp; &nbsp; Byte le = Byte.valueOf((byte) 255);&nbsp; &nbsp; int size = 0x00;&nbsp; &nbsp; do {&nbsp; &nbsp; &nbsp; &nbsp; r = channel.transmit(new CommandAPDU(0x00, APDUCommand.READ_BINARY.getCommand(), p1, p2, (le < 0) ? le & 255 : le));&nbsp; &nbsp; &nbsp; &nbsp; switch (r.getSW1()) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case 0x90:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dataResponseBuffer.write(r.getData());&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; size += (le < 0) ? le.intValue() & 255 : le.intValue();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; byte[] offsetarray = ByteBuffer.allocate(4).putInt(size).array();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; p1 = (offsetarray[2] < 0) ? offsetarray[2] & 255 : offsetarray[2];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; p2 = (offsetarray[3] < 0) ? offsetarray[3] & 255 : offsetarray[3];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case 0x67: // dec 103&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // normal process XX = number of bytes for response enabled&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case 0x61:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nuevaLong = Byte.valueOf(codigoError[1]);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // incorrect parameters (out of EF)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case 0x6a:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (r.getSW2() == 0x86)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println("Parameters P1-P2 incorrects");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // incorrect long, sw2 = exact long. If not return field data&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case 0x6c: //dec 108&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //nuevaLong = Byte.valueOf(codigoError[1]);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (r.getSW2() == 0x86)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println("Parameter P1-P2 incorrects");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case 0x69: //dec 108&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end = false;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case 0x6b: //dec 107&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end = false;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int div = (le < 0)? le.intValue() & 255: le.intValue() ;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; size -= div;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; le = Byte.valueOf((byte) (div / 2));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; size += le;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (le.byteValue() == (byte) 0) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; le = Byte.valueOf((byte) 1);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end = false;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; offsetarray = ByteBuffer.allocate(4).putInt(size).array();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;entero = Integer.valueOf(byteArraySize4ToInt(offsetarray) );&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; p1 = (offsetarray[2] < 0)? offsetarray[2] & 255: offsetarray[2];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; p2 = (offsetarray[3] < 0)? offsetarray[3] & 255: offsetarray[3];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; */&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; default:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; } while (end);} catch (CardException e1) {&nbsp; &nbsp; e1.printStackTrace();} catch (IOException e) {&nbsp; &nbsp; e.printStackTrace();}return dataResponseBuffer.toByteArray();}5.根据开关内部的文档进行错误处理
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java