



| AES | Advanced Encryption Standard |
| AID | Application IDentifier |
| APDU | Application Protocol Data Unit |
| API | Application Programming Interface |
| ATR | Answer To Reset |
| BCV | ByteCode Verifier |
| CAP | Converted APplet |
| COS | Card Operating System |
| CRC | Cyclic Redundancy Check |
| DES | Data Encryption Standard |
| ECB | Electronic CodeBook |
| EEPROM | Electrically Erasable Programmable Read Only Memory |
| EMV | Europay Mastercard Visa |
| GP | Global Platform |
| JAR | Java ARchive |
| JCA | Java Card Assembly |
| JCRE | Java Card Runtime Environment |
| JCVM | Java Card Virtual Machine |
| JDK | Java Development Kit |
| MAC | Message Authentication Code |
| NOP | No Operation Performed |
| PIN | Personal Identification Number |
| PIX | Proprietary Identifier eXtension |
| PTS | Protocol Type Selection |
| RAM | Random Access Memory |
| RID | Resource IDentifier |
| ROM | Read-Only Memory |
| RSA | Rivest Shamir Adelman |
| SCQL | Smart Card Query Language |
| SDK | Software Development Kit |
| TDES | Triple Data Encryption Standard |
| TPDU | Transmission Protocol Data Unit |

| Pin # | Name | Description |
|---|---|---|
| 1 | VCC | +5 V or 3.3 V DC |
| 2 | Reset | Card Reset (Optional) |
| 3 | CLOCK | Card Clock |
| 4 | AS | Application Specific |
| 5 | GND | Ground |
| 6 | VPP | +21 V DC [Programming], or NC |
| 7 | I/O | In/Out [Data] |
| 8 | AS | Application Specific |















| Requête | Réponse |
|---|---|
| CLA INS P1 P2 Lc [Lc octets] | sw1 sw2 |
| CLA INS P1 P2 Le | [Le octets] sw1 sw2 |
| CLA INS P1 P2 Lc [Lc octets] | 61 Le |
| CLA C0 00 00 Le (GET RESPONSE) | [Le octets] sw1 sw2 |
CLA B0 P1 P2 LeCLA D0 P1 P2 Lc [Lc octets]CLA D6 P1 P2 Lc [Lc octets].CLA 0E P1 P2 [Lc=2 ou non présent] [2 octets ou rien]CLA B2 P1 P2 LeCLA D2 P1 P2 Lc [lc octets]CLA E2 P1 P2 Lc [Lc octets]CLA DC P1 P2 Lc [Lc octets]CLA CA P1 P2 LeCLA DA P1 P2 Lc [Lc octets]CLA A4 P1 P2 Lc [Lc octets] [Le ou omis]CLA 20 P1 P2 Lc(ou omis) [Lc octets]CLA 88 P1 P2 Lc [Lc octets] LeCLA 88 P1 P2 Lc[Lc octets] LeCLA 84 P1 P2 LeCLA C0 P1 P2 LeCLA C2 P1 P2 Lc [Lc octets] Le ou omis







package fr.salaun.tristan.javacard.helloworld;
import javacard.framework.*;
import javacard.security.RandomData;
public class HelloWorld extends Applet
{
private static final short BUFFER_SIZE = 32;
private byte[] tmpBuffer = JCSystem.makeTransientByteArray(BUFFER_SIZE, JCSystem.CLEAR_ON_DESELECT);
private RandomData random;
public static void install(byte[] bArray, short bOffset, byte bLength)
{
// new HelloWorld().register(bArray, (short) (bOffset + 1), bArray[bOffset]);
new HelloWorld(bArray, bOffset, bLength);
}
protected HelloWorld(byte[] bArray, short bOffset, byte bLength){
//random = RandomData.getInstance(RandomData.ALG_SECURE_RANDOM);
random = RandomData.getInstance(RandomData.ALG_PSEUDO_RANDOM);
register(bArray, (short) (bOffset + 1), bArray[bOffset]);
}
public void process(APDU apdu)
{
if (selectingApplet())
{
return;
}
byte[] apduBuffer = apdu.getBuffer();
byte cla = apduBuffer[ISO7816.OFFSET_CLA];
byte ins = apduBuffer[ISO7816.OFFSET_INS];
short lc = (short)apduBuffer[ISO7816.OFFSET_LC];
short p1 = (short)apduBuffer[ISO7816.OFFSET_P1];
short p2 = (short)apduBuffer[ISO7816.OFFSET_P2];
random.generateData(tmpBuffer, (short) 0, BUFFER_SIZE);
Util.arrayCopyNonAtomic(tmpBuffer, (short)0, apduBuffer, (short)0, BUFFER_SIZE);
apdu.setOutgoingAndSend((short)0, BUFFER_SIZE);
}
}










javacard.framework.Applet
comporte 8 méthodes principales :
static void install(byte[]bArray, short bOffset, byte bLength) throws ISOExceptionprotected final void register() throws SystemExceptionprotected void register(byte[]bArray, short bOffset, byte bLength)public boolean select()protected final boolean selectingApplet()public void deselect()public Shareable getShareableInterfaceObject(AID clientAID, byte parameter)public abstract void process(APDU apdu) throws ISOExceptionjavacard.framework.APDU :
public short setIncomingAndReceive() throws APDUExceptionpublic void setOutgoingAndSend(short bOff, short len) throws APDUExceptionjavacard.framework.ISOException :
public static void throwIt(short sw)ISO7816 contient
une liste de valeurs utiles.
javacard.framework.Util :
public static final short arrayCopy(byte[] src, short srcOff, byte[] dest, short destOff, short length)public static final short arrayCopyNonAtomic(byte[] src, short srcOff, byte[] dest, short destOff, short length)public static final short makeShort(byte b1, byte b2)



build.gradle :

dependencies, Alt + Inser, puis : Add Maven artifact dependency :

jcardsim, sélectionnons la dernière version :


JcardSimClient :


import com.licel.jcardsim.base.Simulator;
import com.licel.jcardsim.samples.HelloWorldApplet;
import javacard.framework.AID;
import javax.smartcardio.CommandAPDU;
import javax.smartcardio.ResponseAPDU;
import java.nio.charset.StandardCharsets;
public class JcardSimClient {
public static void main(String[] args) {
// 1. create simulator
Simulator simulator = new Simulator();
// 2. install applet
AID appletAID = new AID(new byte[]{(byte) 0xF0, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01}, (short) 0, (byte) 5);
simulator.installApplet(appletAID, HelloWorldApplet.class);
// 3. select applet
simulator.selectApplet(appletAID);
// 4. send APDU echoWorld
CommandAPDU commandAPDU = new CommandAPDU(0x00, 0x01, 0x00, 0x00);
byte[] responseBytes = simulator.transmitCommand(commandAPDU.getBytes());
ResponseAPDU response = new ResponseAPDU(responseBytes);
// 5. check response
System.out.println(JavaCardTools.bytesToHex(response.getBytes()));
System.out.println(Integer.toHexString(response.getSW()));
System.out.println(new String(response.getData(), StandardCharsets.UTF_8));
// 6. send APDU echoWorld2
commandAPDU = new CommandAPDU(0x00, 0x03, 0x00, 0x00, "Bonjour le monde".getBytes());
responseBytes = simulator.transmitCommand(commandAPDU.getBytes());
response = new ResponseAPDU(responseBytes);
System.out.println(JavaCardTools.bytesToHex(response.getBytes()));
System.out.println(Integer.toHexString(response.getSW()));
System.out.println(new String(response.getData(), StandardCharsets.UTF_8));
// 7. send APDU echoWorld2
commandAPDU = new CommandAPDU(0x00, 0x07, 0x00, 0x00);
responseBytes = simulator.transmitCommand(commandAPDU.getBytes());
response = new ResponseAPDU(responseBytes);
System.out.println(JavaCardTools.bytesToHex(response.getBytes()));
System.out.println(Integer.toHexString(response.getSW()));
System.out.println(new String(response.getData(), StandardCharsets.UTF_8));
}
}
JavaCardTools :
public class JavaCardTools {
private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
public static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = HEX_ARRAY[v >>> 4];
hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
}
return new String(hexChars);
}
}
register(bArray, (short) (bOffset + 1), bArray[bOffset]);
par :
register();
Il ne nous reste plus qu'à adapter le code de notre client.
| Carte à puce traditionnelle | Carte à puce récente compatible V3 |
|---|---|
| 8/16-bit CPU | 32-bit CPU |
| 2 kb RAM | 24 kb RAM |
| 48 kb - 64 kb ROM | >256 kb ROM |
| 8–32 kb EEPROM | >128 kb EEPROM |
| Serial I/O interface | High-speed interfaces |
| 9,6 kb/s - 30 kb/s | 1,5 Mb/s - 12 Mb/s |
| Full duplex | Half duplex |
| SW1 SW2 | Message |
|---|---|
| '6X XX' | Transmission protocol related codes |
| '61 XX' | SW2 indicates the number of response bytes still available |
| '62 00' | No information given |
| '62 81' | Returned data may be corrupted |
| '62 82' | The end of the file has been reached before the end of reading |
| '62 83' | Invalid DF |
| '62 84' | Selected file is not valid. File descriptor error |
| '63 00' | Authentification failed. Invalid secret code or forbidden value |
| '63 81' | File filled up by the last write |
| '63 CX' | Counter provided by 'X' (valued from 0 to 15) (exact meaning depending on the command) |
| SW1 SW2 | Message |
|---|---|
| '65 01' | Memory failure. There have been problems in writing or reading the EEPROM. Other hardware problems may also bring this error. |
| '65 81' | Write problem / Memory failure / Unknown mode |
| '67 XX' | Error, incorrect parameter P3 (ISO code) |
| '67 00' | Incorrect length or address range error |
| '68 00' | The request function is not supported by the card. |
| '68 81' | Logical channel not supported |
| '68 82' | Secure messaging not supported |
| SW1 SW2 | Message |
|---|---|
| '69 00' | No successful transaction executed during session |
| '69 81' | Cannot select indicated file, command not compatible with file organization |
| '69 82' | Access conditions not fulfilled |
| '69 83' | Secret code locked |
| '69 84' | Referenced data invalidated |
| '69 85' | No currently selected EF, no command to monitor / no Transaction Manager File |
| '69 86' | Command not allowed (no current EF) |
| '69 87' | Expected SM data objects missing |
| '69 88' | SM data objects incorrect |
| SW1 SW2 | Message |
|---|---|
| '6A 00' | Bytes P1 and/or P2 are incorrect. |
| '6A 80' | The parameters in the data field are incorrect |
| '6A 81' | Card is blocked or command not supported |
| '6A 82' | File not found |
| '6A 83' | Record not found |
| '6A 84' | There is insufficient memory space in record or file |
| '6A 85' | Lc inconsistent with TLV structure |
| '6A 86' | Incorrect parameters P1-P2 |
| '6A 87' | The P3 value is not consistent with the P1 and P2 values. |
| '6A 88' | Referenced data not found. |
| SW1 SW2 | Message |
|---|---|
| '6B 00' | Incorrect reference; illegal address; Invalid P1 or P2 parameter |
| '6C XX' | Incorrect P3 length. |
| '6D 00' | Command not allowed. Invalid instruction byte (INS) |
| '6E 00' | Incorrect application (CLA parameter of a command) |
| '6F 00' | Checking error |
| '90 00' | Command executed without error |
| '91 00' | Purse Balance error cannot perform transaction |
| '91 02' | Purse Balance error |
| SW1 SW2 | Message |
|---|---|
| '92 XX' | Memory error |
| '92 02' | Write problem / Memory failure |
| '92 40' | Error, memory problem |
| '94 XX' | File error |
| '94 04' | Purse selection error or invalid purse |
| '94 06' | Invalid purse detected during the replacement debit step |
| '94 08' | Key file selection error |
| SW1 SW2 | Message |
|---|---|
| '98 XX' | Security error |
| '98 00' | Warning |
| '98 04' | Access authorization not fulfilled |
| '98 06' | Access authorization in Debit not fulfilled for the replacement debit step |
| '98 20' | No temporary transaction key established |
| '98 34' | Error, Update SSD order sequence not respected (should be used if SSD Update commands are received out of sequence). |
| '9F XX' | Success, XX bytes of data available to be read via "Get_Response" task. |