This are few notes to getting starting interfacing Java application with smart card. In particular, this step are what you need to read personal data on an Italian Healty Card by Java code.

cardreader.jpg

First to all, you need to install, if not already, the pcsc-lite daemon:

[root@raspi ~]# yum install -y pcsc-lite pcsc-lite-devel pcsc-tools

The reader I used is an Athena ASEDrive IIIe USB. you need to install the driver:

Warning To build the driver you needed the kernel header and libusb-devel package, if can install them with: [root@raspi ~]# yum install -y libusb-devel
[root@raspi ~]# wget http://www.athena-scs.com/docs/reader-drivers/asedriveiiie-usb-3-7-tar.bz2
    --2013-06-20 22:58:14--  http://www.athena-scs.com/docs/reader-drivers/asedriveiiie-usb-3-7-tar.bz2
    Risoluzione di www.athena-scs.com (www.athena-scs.com)... 50.61.225.43
    Connessione a www.athena-scs.com (www.athena-scs.com)|50.61.225.43|:80... connesso.
    Richiesta HTTP inviata, in attesa di risposta... 200 OK
    Lunghezza: 33062 (32K) [application/octet-stream]
    Salvataggio in: "asedriveiiie-usb-3-7-tar.bz2"
    
    100%[=======================================================================================================================================================================================>] 33.062      92,1KB/s   in 0,4s
    
    2013-06-20 22:58:15 (92,1 KB/s) - "asedriveiiie-usb-3-7-tar.bz2" salvato [33062/33062]
    
    [root@raspi ~]# tar xjvf asedriveiiie-usb-3-7-tar.bz2
    asedriveiiie-usb-3.7/
    asedriveiiie-usb-3.7/ifd-ASEDriveIIIe-USB.bundle/
    asedriveiiie-usb-3.7/ifd-ASEDriveIIIe-USB.bundle/Contents/
    asedriveiiie-usb-3.7/ifd-ASEDriveIIIe-USB.bundle/Contents/Linux/
    asedriveiiie-usb-3.7/ifd-ASEDriveIIIe-USB.bundle/Contents/Resources/
    asedriveiiie-usb-3.7/ifd-ASEDriveIIIe-USB.bundle/Contents/Resources/English.lproj/
    asedriveiiie-usb-3.7/Makefile
    asedriveiiie-usb-3.7/50-pcscd-asedriveiiie.rules
    asedriveiiie-usb-3.7/usb.c
    asedriveiiie-usb-3.7/ifdhandler.c
    asedriveiiie-usb-3.7/InitCardParams.c
    asedriveiiie-usb-3.7/ReaderCommands.c
    asedriveiiie-usb-3.7/CommandTypes.c
    asedriveiiie-usb-3.7/Ase.h
    asedriveiiie-usb-3.7/atr.c
    asedriveiiie-usb-3.7/T1Protocol.c
    asedriveiiie-usb-3.7/Makefile.inc
    asedriveiiie-usb-3.7/ChangeLog
    asedriveiiie-usb-3.7/README
    asedriveiiie-usb-3.7/T1Protocol.h
    asedriveiiie-usb-3.7/MemoryCards.h
    asedriveiiie-usb-3.7/MemoryCards.c
    asedriveiiie-usb-3.7/LinuxDefines.h
    asedriveiiie-usb-3.7/LICENSE
    asedriveiiie-usb-3.7/DriverIO.c
    asedriveiiie-usb-3.7/configure
    asedriveiiie-usb-3.7/atr.h
    asedriveiiie-usb-3.7/ifd-ASEDriveIIIe-USB.bundle/Contents/PkgInfo
    asedriveiiie-usb-3.7/ifd-ASEDriveIIIe-USB.bundle/Contents/Info.plist
    asedriveiiie-usb-3.7/ifd-ASEDriveIIIe-USB.bundle/Contents/Resources/English.lproj/InfoPlist.strings
    [root@raspi ~]# cd asedriveiiie-usb-3.7/
    [root@raspi asedriveiiie-usb-3.7]# ./configure
    [root@raspi asedriveiiie-usb-3.7]# make
    gcc -o libASEDriveIIIe-USB.so usb.c atr.c DriverIO.c CommandTypes.c ReaderCommands.c T1Protocol.c MemoryCards.c InitCardParams.c ifdhandler.c -fPIC -D_REENTRANT -DIFDHANDLERv2 -Wall -I. -pthread -I/usr/include/PCSC   -lpcsclite   -lusb -shared
    InitCardParams.c: In function ‘MatchReaderParams’:
    InitCardParams.c:52:9: warning: variable ‘F’ set but not used [-Wunused-but-set-variable]
    ifdhandler.c: In function ‘closeDriver’:
    ifdhandler.c:30:9: warning: variable ‘retVal’ set but not used [-Wunused-but-set-variable]
    [root@raspi asedriveiiie-usb-3.7]# make install
    install -c -d "//usr/lib/pcsc/drivers/ifd-ASEDriveIIIe-USB.bundle/Contents"
    install -c -m 0644 ifd-ASEDriveIIIe-USB.bundle/Contents/Info.plist ifd-ASEDriveIIIe-USB.bundle/Contents/PkgInfo "//usr/lib/pcsc/drivers/ifd-ASEDriveIIIe-USB.bundle/Contents"
    install -c -d "//usr/lib/pcsc/drivers/ifd-ASEDriveIIIe-USB.bundle/Contents/Resources/English.lproj"
    install -c -m 0644 ifd-ASEDriveIIIe-USB.bundle/Contents/Resources/English.lproj/InfoPlist.strings "//usr/lib/pcsc/drivers/ifd-ASEDriveIIIe-USB.bundle/Contents/Resources/English.lproj"
    install -c -d "//usr/lib/pcsc/drivers/ifd-ASEDriveIIIe-USB.bundle/Contents/Linux"
    install -c -m 0755 libASEDriveIIIe-USB.so "//usr/lib/pcsc/drivers/ifd-ASEDriveIIIe-USB.bundle/Contents/Linux"
    install -c -m 0644 50-pcscd-asedriveiiie.rules /etc/udev/rules.d/.
    [root@raspi asedriveiiie-usb-3.7]#

Now run pcsc deamon in foreground just to see some informative log:

[root@raspi asedriveiiie-usb-3.7]# pcscd -f -d
    00000000 debuglog.c:269:DebugLogSetLevel() debug level=debug
    00004254 configfile.l:245:DBGetReaderListDir() Parsing conf directory: /etc/reader.conf.d
    00002498 configfile.l:298:DBGetReaderList() Parsing conf file: /etc/reader.conf.d/libccidtwin
    00004571 configfile.l:257:DBGetReaderListDir() Skipping non regular file: .
    00002167 configfile.l:257:DBGetReaderListDir() Skipping non regular file: ..
    00000276 pcscdaemon.c:525:main() pcsc-lite 1.8.7 daemon ready.
    00022326 hotplug_libudev.c:260:get_driver() Looking for a driver for VID: 0x1D6B, PID: 0x0002, path: /dev/bus/usb/001/001
    00003756 hotplug_libudev.c:260:get_driver() Looking for a driver for VID: 0x1D6B, PID: 0x0002, path: /dev/bus/usb/001/001
    00003800 hotplug_libudev.c:260:get_driver() Looking for a driver for VID: 0x0424, PID: 0x9512, path: /dev/bus/usb/001/002
    00003659 hotplug_libudev.c:260:get_driver() Looking for a driver for VID: 0x0424, PID: 0xEC00, path: /dev/bus/usb/001/003
    00003832 hotplug_libudev.c:260:get_driver() Looking for a driver for VID: 0x0424, PID: 0x9512, path: /dev/bus/usb/001/002
    00003737 hotplug_libudev.c:260:get_driver() Looking for a driver for VID: 0x1A40, PID: 0x0101, path: /dev/bus/usb/001/004
    00003834 hotplug_libudev.c:260:get_driver() Looking for a driver for VID: 0x04F3, PID: 0x0216, path: /dev/bus/usb/001/005
    00003836 hotplug_libudev.c:260:get_driver() Looking for a driver for VID: 0x1A40, PID: 0x0101, path: /dev/bus/usb/001/004
    00003692 hotplug_libudev.c:260:get_driver() Looking for a driver for VID: 0x1C4F, PID: 0x0016, path: /dev/bus/usb/001/006
    00003693 hotplug_libudev.c:260:get_driver() Looking for a driver for VID: 0x1C4F, PID: 0x0016, path: /dev/bus/usb/001/006
    00003968 hotplug_libudev.c:260:get_driver() Looking for a driver for VID: 0x1A40, PID: 0x0101, path: /dev/bus/usb/001/004
    00003751 hotplug_libudev.c:260:get_driver() Looking for a driver for VID: 0x1A40, PID: 0x0101, path: /dev/bus/usb/001/007
    00003868 hotplug_libudev.c:260:get_driver() Looking for a driver for VID: 0x1A40, PID: 0x0101, path: /dev/bus/usb/001/004
    00003677 hotplug_libudev.c:260:get_driver() Looking for a driver for VID: 0x0424, PID: 0x9512, path: /dev/bus/usb/001/002
    04086407 hotplug_libudev.c:260:get_driver() Looking for a driver for VID: 0x0DC3, PID: 0x0802, path: /dev/bus/usb/001/009
    00002260 hotplug_libudev.c:312:HPAddDevice() Adding USB device: AseIIIeUSB
    00002214 readerfactory.c:978:RFInitializeReader() Attempting startup of AseIIIeUSB 00 00 using /usr/lib/pcsc/drivers/ifd-ASEDriveIIIe-USB.bundle/Contents/Linux/libASEDriveIIIe-USB.so
    00032344 dyn_unix.c:81:DYN_GetAddress() IFDHCreateChannelByName: /usr/lib/pcsc/drivers/ifd-ASEDriveIIIe-USB.bundle/Contents/Linux/libASEDriveIIIe-USB.so: undefined symbol: IFDHCreateChannelByName
    00002717 readerfactory.c:836:RFBindFunctions() Loading IFD Handler 2.0
    00084851 readerfactory.c:327:RFAddReader() Using the pcscd polling thread

Insert the smart card into reader:

99999999 eventhandler.c:372:EHStatusHandlerThread() powerState: POWER_STATE_POWERED
    00002218 eventhandler.c:387:EHStatusHandlerThread() Card inserted into AseIIIeUSB 00 00
    00002378 Card ATR: 3B DF 18 00 81 31 FE 7D 00 6B 15 0C 01 81 01 11 01 43 4E 53 10 31 80 E8
    00403402 eventhandler.c:446:EHStatusHandlerThread() powerState: POWER_STATE_UNPOWERED

In a new windows compile and run this simple Java programm:

ReadCard.java
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 javax.xml.bind.DatatypeConverter;
    
    public class ReadCard {
    
            public static void main(String[] argv) throws Exception {
    
                    // show the list of available terminals
                    TerminalFactory factory = TerminalFactory.getDefault();
    
                    List<CardTerminal> terminals = factory.terminals().list();
                    System.out.println("Terminals: " + terminals);
    
                    // get just the first terminal
                    CardTerminal terminal = terminals.get(0);
    
                    // establish a connection with the card
                    Card card = terminal.connect("T=1");
                    System.out.println("card: " + card);
    
                    CardChannel channel = card.getBasicChannel();
    
                    byte[] apdu = DatatypeConverter.parseHexBinary("00A40800063F001100110200");
                    ResponseAPDU r = channel.transmit(new CommandAPDU(apdu));
                    System.out.println("response: " + new String(r.getBytes()));
    
                    apdu = DatatypeConverter.parseHexBinary("00B0000080");
                    r = channel.transmit(new CommandAPDU(apdu));
                    System.out.println("response: " + new String(r.getBytes()));
    
                    apdu = DatatypeConverter.parseHexBinary("00B0008080");
                    r = channel.transmit(new CommandAPDU(apdu));
                    System.out.println("response: " + new String(r.getBytes()));
    
                    apdu = DatatypeConverter.parseHexBinary("00B0010080");
                    r = channel.transmit(new CommandAPDU(apdu));
                    System.out.println("response: " + new String(r.getBytes()));
    
                    apdu = DatatypeConverter.parseHexBinary("00B0018010");
                    r = channel.transmit(new CommandAPDU(apdu));
                    System.out.println("response: " + new String(r.getBytes()));
    
                    // disconnect
                    card.disconnect(false);
    
            }
    }

This is the result:

[dometec@raspi ~]$ javac ReadCard.java
    [dometec@raspi ~]$ java ReadCard
    Terminals: [PC/SC terminal AseIIIeUSB 00 00]
    card: PC/SC card in AseIIIeUSB 00 00, protocol T=1, state OK
    response: o;������      f����f���▒���������������������������
    response: 00006B04603..........XXXX..HIDE PERSONAL DATA :).................
Last modify on Sunday December 06, 2020