JavaCard (erste Schritte): Difference between revisions
No edit summary |
|||
Line 11: | Line 11: | ||
</code> |
</code> |
||
Angesprochen wird die Karte durch APDU Kommandos. Vor jeder Operation wird das Simple Wallet Applet mit ihrer AID <code>F000A0000E00</code> ausgewählt. |
Angesprochen wird die Karte durch APDU Kommandos[https://de.wikipedia.org/wiki/Application_Protocol_Data_Unit][https://stackoverflow.com/questions/30550899/what-is-the-structure-of-an-application-protocol-data-unit-apdu-command-and-re/30679558#30679558]. Vor jeder Operation wird das Simple Wallet Applet mit ihrer AID <code>F000A0000E00</code> ausgewählt. |
||
===Guthaben verändern=== |
===Guthaben verändern=== |
Revision as of 10:40, 10 October 2022
Erste Schritte: Installation einer Beispielanwendung
Hier erfolgt zunächst der erste Test der Funktionalität der SmartCard durch Installation eines Applets, das eine einfache Guthabenkarte implementiert, hier Simple Wallet[1].
Installiert und angesprochen kann die JavaCard mittels GlobalPlatformPro[2].
Installiert wird die Applikation durch:
java -jar gp.jar -install simplewallet.cap -default
Angesprochen wird die Karte durch APDU Kommandos[3][4]. Vor jeder Operation wird das Simple Wallet Applet mit ihrer AID F000A0000E00
ausgewählt.
Guthaben verändern
Das Guthaben kann beispielsweise mit der APDU B040000001[AMOUNT, 1 Bytes]
erhöht werden:
java -jar gp.jar -a "00A4040006F000A0000E0000" -a "B04000000105" -debug -verbose
Ausgabe:
GlobalPlatformPro v20.01.23-0-g5ad373b Running on Linux 5.15.0-48-generic amd64, Java 17.0.4 by Private Build # Detected readers from JNA2PCSC [*] REINER SCT cyberJack RFID basis 00 00 SCardConnect("REINER SCT cyberJack RFID basis 00 00", T=*) -> T=1, 3B80800101 SCardBeginTransaction("REINER SCT cyberJack RFID basis 00 00") Reader: REINER SCT cyberJack RFID basis 00 00 ATR: 3B80800101 More information about your card: http://smartcard-atr.appspot.com/parse?ATR=3B80800101 A>> T=1 (4+0006) 00A40400 06 F000A0000E00 00 A<< (0000+2) (33ms) 9000 A>> T=1 (4+0001) B0400000 01 05 A<< (0000+2) (25ms) 9000 A>> T=1 (4+0000) 00A40400 00 A<< (0018+2) (19ms) 6F108408A000000151000000A5049F6501FF 9000 [TRACE] GPSession - [6F] [TRACE] GPSession - [84] A000000151000000 [TRACE] GPSession - [A5] [TRACE] GPSession - [9F65] FF [DEBUG] GPSession - Auto-detected ISD: A000000151000000 SCardEndTransaction("REINER SCT cyberJack RFID basis 00 00") SCardDisconnect("REINER SCT cyberJack RFID basis 00 00", true) tx:23/rx:24
Alternativ kann das Guthaben auch mit B030000001[AMOUNT, 1 Bytes]
reduziert werden. Die Antwort 0x9000
steht hier für "Erfolgreich".
Guthaben auslesen
Das Guthaben kann dann mit der APDU B050000002
ausgelesen werden:
java -jar gp.jar -a "00A4040006F000A0000E0000" -a "B050000002" -debug -verbose
Ausgabe:
GlobalPlatformPro v20.01.23-0-g5ad373b Running on Linux 5.15.0-48-generic amd64, Java 17.0.4 by Private Build # Detected readers from JNA2PCSC [*] REINER SCT cyberJack RFID basis 00 00 SCardConnect("REINER SCT cyberJack RFID basis 00 00", T=*) -> T=1, 3B80800101 SCardBeginTransaction("REINER SCT cyberJack RFID basis 00 00") Reader: REINER SCT cyberJack RFID basis 00 00 ATR: 3B80800101 More information about your card: http://smartcard-atr.appspot.com/parse?ATR=3B80800101 A>> T=1 (4+0006) 00A40400 06 F000A0000E00 00 A<< (0000+2) (28ms) 9000 A>> T=1 (4+0000) B0500000 02 A<< (0002+2) (15ms) 0005 9000 A>> T=1 (4+0000) 00A40400 00 A<< (0018+2) (23ms) 6F108408A000000151000000A5049F6501FF 9000 [TRACE] GPSession - [6F] [TRACE] GPSession - [84] A000000151000000 [TRACE] GPSession - [A5] [TRACE] GPSession - [9F65] FF [DEBUG] GPSession - Auto-detected ISD: A000000151000000 SCardEndTransaction("REINER SCT cyberJack RFID basis 00 00") SCardDisconnect("REINER SCT cyberJack RFID basis 00 00", true) tx:22/rx:26
Das Guthaben wird hier mit 0x0005
vor dem Returncode 0x9000
(Erfolgreich) zurückgegeben.
Erstellen eines Hello World Applet
Das Erstellen eines Builds erfolgt mit Ant für JavaCards[5], dessen .jar im Projektverzeichnis platziert wird. Außerdem wird eine SDK benötigt. Hier wird die SDK Version 3.0.4 (hier[6]) und die Java Version 8 verwendet.
Projektdateien
Die build.xml
für den Ant-Task sieht dann wiefolgt aus:
<project name="JavaCardHelloWorld" basedir=".">
<taskdef name="javacard" classname="pro.javacard.ant.JavaCard" classpath="ant-javacard.jar"/>
<javacard>
<cap jckit="./sdks/jc304_kit" aid="0102030405" package="main" output="SimpleHello.cap" sources="src/main/">
<applet class="main.SimpleHello" aid="0102030405060708"/>
</cap>
</javacard>
</project>
Und das HelloWorld SimpleHello.java
:
package main;
import javacard.framework.*;
public class SimpleHello extends Applet {
final static byte HELLO_CLA = (byte)0xb0;
private static final byte[] helloWorld = { 'H' };
private SimpleHello() {
register();
}
public static void install(byte bArray[], short bOffset, byte bLength) throws ISOException {
new SimpleHello();
}
@Override
public void process(APDU apdu) throws ISOException {
byte[] buf = apdu.getBuffer();
if ((buf[ISO7816.OFFSET_CLA] == 0) && (buf[ISO7816.OFFSET_INS] == (byte)0xa4)) {
return;
}
if (buf[ISO7816.OFFSET_CLA] != HELLO_CLA) {
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
}
sendHelloWorld(apdu);
}
private void sendHelloWorld(APDU apdu) {
byte[] buffer = apdu.getBuffer();
short length = (short) helloWorld.length;
Util.arrayCopyNonAtomic(helloWorld, (short) 0, buffer, (short) 0, length);
apdu.setOutgoingAndSend((short) 0, length);
}
}
Das Projektverzeichnis:
. |------ src/ | |------ main/ | |------ SimpleHello.java |------ sdks/ | |------ jc304_kit/ |------ ant-javacard.jar |------ gp.jar |------ build.xml |------ SimpleHello.cap
Auf die Karte bringen
Schließlich wird für den Build die Java-Homevariable auf Version 8 gesetzt:
export JAVA_HOME="/usr/lib/jvm/java-8-openjdk-amd64/"
...Der Ant-Build ausgeführt:
ant
...Und das Applet installiert:
java -jar gp.jar -install SimpleHello.cap -default
Der Aufruf mit java -jar gp.jar -d -applet 0102030405060708 --apdu B0000000
liefert nun den Buchstaben H als Hexcode 0x48
zurück.