1

I'm developing a Java application that connects to HID Omnikey 5022 card reader. What I need is reading PACS bits (raw Wiegand data).

I have exactly the same problem with this question, I also can see the data with PACS Probe application:

How to read Smart Card data

Unfortunately the provided answer to that is not working for me.

This is what I get from PACS Probe:

  • Card Reader: HID Global OMNIKEY 5022 Smart Card Reader 0
  • Card type: PicoPass 32KS (8x2 + 16)
  • Card serial number (CSN, UID): 32966202F8FF12E0 (hex)
  • PACS bits (raw Wiegand) data: 000000310BC53938 (hex)

I have already tried the command I found in Omnikey 5023 guide, surprisingly it returns some data but it's not what I need.

That command is:

commandAPDU = new CommandAPDU(new byte[] { (byte) 0xFF, (byte) 0x70, (byte) 0x07, (byte) 0x6B, (byte) 0x07,
                (byte) 0xA0, (byte) 0x05, (byte) 0xBE, (byte) 0x03, (byte) 0x80, (byte) 0x01, (byte) 0x04, (byte) 0x00 }); // Read PACS 5023

It returns this:

9E020003
// I need 000000310BC53938

Any help is appreciated since I am new to smart card development. Thanks in advance.

Pouria Moosavi
  • 662
  • 7
  • 22

2 Answers2

0

The response APDU you are getting from the reader is an error code for unsupported proprietary command.

You will need a secure session to access PACS bit data using OMNIKEY 5022 or OMNIKEY 5023 readers.

Unless you have the appropriate documentation for this reader, I would probably stick to the card serial number (UID, CSN) and use a Java wrapper for PC/SC (or pcsclite) to connect to reader and card.

Then issue (via SCardTransmit(FFCA0000 APDU) to get the UID (32966202F8FF12E0) shown in your the sample output from https://PACSprobe.com

As for Java: use smartcardio lib. That's a good wrapper for native PC/SC

It's a lot of work porting the secure channel protocols to Java. Calling a third-party library may be easier.

Marc
  • 1
  • 1
  • Hi Marc, thanks for the answer. I'm already using smartcardio lib. I can already get UID and ATR with that library, but sticking to one of those is not option for me, because we need Facility Code (FAC) and Card Number (CN) which can be found only in PACS bits. Also I can enter and exit Transparent Session successfully. The only thing I need is the PACS bits, which is not documented in the 5022 reader's documentation. Thanks for anything to point me into right direction. – Mehmet Sadi Jul 03 '19 at 05:37
0

I was able to use javax.smartcardio, and get the Wiegand data using code like below. At the end you can see the facility code and card number are printed.

TerminalFactory terminalFactory = TerminalFactory.getDefault();

CardTerminals cardTerminals = terminalFactory.terminals();

List<CardTerminal> terminalList = cardTerminals.list();

CardTerminal cardTerminal = terminalList.get(0);
cardTerminal.waitForCardPresent(10 * 1000); // wait 10 seconds
Card card = cardTerminal.connect("*");
System.out.println("Card: " + card);
CardChannel channel = card.getBasicChannel();

byte[] aid = { (byte) 0xA0, (byte) 0x05, (byte) 0xA1, (byte) 0x03, (byte) 0x80, (byte) 0x01, (byte) 0x04 };
CommandAPDU apdu = new CommandAPDU(0xFF, (byte) 112, (byte) 7, (byte) 107, aid, 256);
ResponseAPDU r = channel.transmit(apdu);
byte[] bytesOut = r.getBytes();

int num1 = (int) bytesOut[3];
if (bytesOut.length - 6 != num1)
System.out.println("problem");

int numberOfBitsShifted = (int) bytesOut[4];
int num2 = num1 - 1;

byte[] newBytesArr = Arrays.copyOfRange(bytesOut, 5, 5 + num2);
if (newBytesArr.length != num2)
    System.out.println("problem");

ByteBuffer wrapped = ByteBuffer.wrap(newBytesArr);
int num = wrapped.getInt();
int first26 = num >> 6;
int withoutParity = first26 >> 1;

int cardNumber = withoutParity & 0xffff;
int facilityCode = (withoutParity >> 16) & 0xff;

System.out.println(facilityCode);
System.out.println(cardNumber);

Ed-
  • 1
  • 2