JavaCard (erste Schritte): Difference between revisions

From
Jump to navigation Jump to search
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.

Key Unwrapping