2016-09-17 11 views
0

Итак, у меня есть бесконтактная карта Mastercard и телефон Visa Paywave. Я использую бесконтактный HID Omnikey 5427 CK.PSE карты не то, что должно быть

Это мой код: `

static boolean cardReading = true; 

public static void main(String[] args) throws CardException, UnsupportedEncodingException { 

    while (cardReading == true) { 

    try { 
    TerminalFactory factory = TerminalFactory.getDefault(); 
    List<CardTerminal> terminals = factory.terminals().list(); 
    CardTerminal terminal = terminals.get(0); 

    if (!terminal.isCardPresent()) { 

     continue; 

    } 

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

    Card card = terminal.connect("T=0"); 
    System.out.println("\n\nInserted card: " + card); 
    CardChannel channel = card.getBasicChannel(); 

    String pse = "00A404000E325041592E5359532E444446303100"; 
    CommandAPDU apdu = new CommandAPDU(pse.getBytes()); 
    ResponseAPDU r = channel.transmit(apdu); 

    System.out.println("Response: " + toHex(r.getData().toString()) + " " + r); 
    System.out.println("ADPU: " + toHex(apdu.getBytes().toString()) + " " + r.getSW() + " " + r.getSW1() + " " + r.getSW2() + " " + r.getNr()); 

    apdu = new CommandAPDU((byte)0x00, (byte)0xB2, (byte)0x01, (byte)0x0C, (byte)0x00); 
    r = channel.transmit(apdu); 

    cardReading = false; 
    Toolkit.getDefaultToolkit().beep(); 

    System.out.println("Terminals: " + terminals); 
    System.out.println("Used terminal: " + terminal); 
    System.out.println("\n\nInserted card: " + card); 
    System.out.println("Response: " + toHex(r.getData().toString()) + " " + r); 
    System.out.println("ADPU: " + toHex(apdu.getBytes().toString()) + " " + r.getSW() + " " + r.getSW1() + " " + r.getSW2() + " " + r.getNr()); 



    System.exit(1); 

    } catch(Exception e) { 

     continue; 

    } 

    } 

} 

public static byte[] hexStringToByteArray(String s) { 
    int len = s.length(); 
    byte[] data = new byte[len/2]; 
    for (int i = 0; i < len; i += 2) { 
     data[i/2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) 
          + Character.digit(s.charAt(i+1), 16)); 
    } 
    return data; 
} 

public static String toHex(String arg) { 
    return String.format("%040x", new BigInteger(1, arg.getBytes())); 
} 

`

И поэтому выход:

Terminals: [PC/SC terminal HID OMNIKEY 5427 CK 0] 
Used terminal: PC/SC terminal HID OMNIKEY 5427 CK 0 


Inserted card: PC/SC card in HID OMNIKEY 5427 CK 0, protocol T=0, state OK 
Response: 0000000000000000005b42403163343630306630 ResponseAPDU: 65 bytes, SW=9000 
ADPU: 000000000000000000005b424035623665663230 36864 144 0 63 
Terminals: [PC/SC terminal HID OMNIKEY 5427 CK 0] 
Used terminal: PC/SC terminal HID OMNIKEY 5427 CK 0 


Inserted card: PC/SC card in HID OMNIKEY 5427 CK 0, protocol T=0, state OK 
Response: 0000000000000000005b42403565616235383039 ResponseAPDU: 14 bytes, SW=9000 
ADPU: 0000000000000000005b42403433323065373664 36864 144 0 12 

Я не понимаю, почему это ответ 0000000000000000005b42403565616235383039 ... Пожалуйста, помогите ,

С уважением, Влад.

+0

Какой ответ вы ожидаете? Что не работает? Просьба уточнить. –

+0

@JimGarrison Люди обычно получают что-то вроде этого в ответ: 6F2F840E325041592E5359532E4444463031A51DBF0C1A61184F07A0000000031010500A564953412044454249548701019000 –

+0

В него входит AID или еще что-то. –

ответ

2

Как говорит Майкл Роланд, ваша обработка шестнадцатеричных строк неверна.

Мета-ошибка 1: 'байт [] ToString()' Использование

r.getData().toString() 

byte[].toString использует Object.toString() реализацию по умолчанию, которая возвращает имя класса с последующим @ и значение Object.hashCode() (например, "[[email protected]") - это не то, что вы хотите для дальнейшей обработки.

Вы можете использовать метод Arrays.toString() (который не выполняет шестнадцатеричный дамп), или any other method.

Мета-ошибка 2: Использование «String.getBytes()»

String pse = "00A404000E325041592E5359532E444446303100"; 
CommandAPDU apdu = new CommandAPDU(pse.getBytes()); 

Не создает желаемый объект APDU как метод String.getBytes() не выполняет шестнадцатеричное преобразование, но преобразование кодировок в платформы стандартная кодировка, например: "1234".getBytes() дает { 0x31, 0x32, 0x33, 0x34 } (а не { 0x12, 0x34 }, как и следовало ожидать).

Ниже приведен простой пример кода, который выполняет (почти) такой же, как ваш код:

package test.java.so; 

import java.util.List; 

import javax.smartcardio.Card; 
import javax.smartcardio.CardChannel; 
import javax.smartcardio.CardTerminal; 
import javax.smartcardio.CommandAPDU; 
import javax.smartcardio.ResponseAPDU; 
import javax.smartcardio.TerminalFactory; 

import org.apache.commons.codec.binary.Hex; 

@SuppressWarnings("restriction") 
public class So39543402 { 

    public static void main(String[] args) throws Exception { 
       TerminalFactory factory = TerminalFactory.getDefault(); 
       List<CardTerminal> terminals = factory.terminals().list(); 
       CardTerminal terminal = terminals.get(0); 

       Card card = terminal.connect("*"); 
       CardChannel channel = card.getBasicChannel(); 

       String pse = "00A404000E325041592E5359532E444446303100"; 
       CommandAPDU apdu = new CommandAPDU(Hex.decodeHex(pse.toCharArray())); 
       exchangeApdu(channel, apdu); 

       apdu = new CommandAPDU(0x00, 0xB2, 0x01, 0x0C, 256); 
       exchangeApdu(channel, apdu); 
    } 

    private static ResponseAPDU exchangeApdu(CardChannel channel, CommandAPDU apdu) throws javax.smartcardio.CardException { 
     System.out.println("APDU: " + Hex.encodeHexString(apdu.getBytes())); 
     ResponseAPDU r = channel.transmit(apdu); 
     System.out.println("Response: " + Hex.encodeHexString(r.getBytes())); 
     return r; 
    } 

} 

Обратите внимание на некоторые интересные части:

  • этот код использует Apache Commons Codec для преобразования шестнадцатеричных

  • аргумент "*" используется для CardTerminal.connect(), который более универсален, чем всегда требуется ужалить протокол T=0

  • ваш READ RECORD APDU был изменен, чтобы ожидать 256 байт данных отклика - this is how this particular constructor works (ваш код будет производить случай ISO 1 Command-APDU, которое, вероятно, не то, что вы хотите)

еще одно замечание:

  • не использовать метод String.getBytes() без параметров (даже тогда, когда вы хотите конвертировать отдельные символы в байтах). Всегда указывайте желаемый набор символов (например, «US-ASCII», «UTF-8»)

Удачи!

 Смежные вопросы

  • Нет связанных вопросов^_^