The following three methods were developed for communicating
with a Schlumberger Cryptoflex Smart Card, through a Saho Card
Reader. While the format will differ depending on the card used,
they should give an indication of how card communication can be
structured.
Ø The selectFile() method
enables a file to be selected
Ø command() takes a full APDU
and converts it into a format suitable for the Saho reader (not one
of the most powerful on the market). When writing for a mobile
phone, the card communication method will differ depending on the
phone, but may well be much more simplistic.
Ø The getResponse() method
takes the response from the Saho reader and strips off the checksum
before returning the actual ADPU that came from the card.
private boolean selectFile(int fName1, int fName2) {
System.out.print("SELECTING : ");
System.out.print(Integer.toHexString(fName1).toUpperCase());
System.out.print(" ");
System.out.println(Integer.toHexString(fName2).toUpperCase());
return command(new int[] {0xC0, 0xA4, 0x00, 0x00,
0x02, fName1, fName2});
}
private boolean command(int bits[]) {
try {
toCard.write(0x36);
toCard.write(0x30);
checkSum = 0x60;
tempStore =
Integer.toHexString(bits.length + 1).toUpperCase();
checkSum = checkSum ^ bits.length
+ 1;
if(tempStore.length() == 1) {
tempStore = "0"
+ tempStore;
}
toCard.write((int)tempStore.charAt(0));
toCard.write((int)tempStore.charAt(1));
if(bits[1] == 164 || bits[1] ==
42 ||
bits[1] == 220
|| bits[1] == 214) {
checkSum =
checkSum ^ 0x14;
toCard.write(0x31);
toCard.write(0x34);
} else {
checkSum =
checkSum ^ 0x13;
toCard.write(0x31);
toCard.write(0x33);
}
for(int i = 0; i <
bits.length; i++) {
checkSum =
checkSum ^ bits[i];
tempStore =
Integer.toHexString(bits[i]).toUpperCase();
if(tempStore.length() == 1) {
tempStore = "0" + tempStore;
}
toCard.write((int)tempStore.charAt(0));
toCard.write((int)tempStore.charAt(1));
}
tempStore =
Integer.toHexString(checkSum).toUpperCase();
if(tempStore.length() == 1) {
tempStore = "0"
+ tempStore;
}
toCard.write((int)tempStore.charAt(0));
toCard.write((int)tempStore.charAt(1));
toCard.write(0x03);
toCard.flush();
return true;
} catch(Throwable e) {
System.out.println("Error Sending
Data");
return false;
}
}
private int[] getResponse() throws SmartcardErrorException {
try {
alsoFromCard.readByte();
alsoFromCard.readByte();
int temp =
alsoFromCard.readByte();
int temp2 =
alsoFromCard.readByte();
char[] c = new char[2];
c[0] = (char)temp;
c[1] = (char)temp2;
String tempStore = new
String(c);
temp = Integer.valueOf(tempStore,
16).intValue();
alsoFromCard.readByte();
alsoFromCard.readByte();
int[] myResult = new int[temp];
for(int i = 0; i <
myResult.length; i++) {
int t1 =
alsoFromCard.readByte();
int t2 =
alsoFromCard.readByte();
char[] c2 = new
char[2];
c2[0] =
(char)t1;
c2[1] =
(char)t2;
String s = new
String(c2);
myResult[i] =
Integer.valueOf(s, 16).intValue();
if(myResult[i]
== -1) {
throw new SmartcardErrorException("Unexpected Response From
Card");
}
}
alsoFromCard.readByte();
return myResult;
} catch(Throwable e) {
System.out.println("Error Sending
Data : "+e);
return new int[] {0,0,0};
}
}