Subgraph JavaCard Smartcard

OpenPGP on JavaCards

Everyone should be aware that their machine could be compromised. Keeping keys on your machine means that in the event of a compromise, your keys are compromised as well. At the same time, encryption is ever more relevant due to mass surveillance. The FSFE offers OpenPGP Smartcards based on the BASIC Card standard, however the source code for these cards is not available. In line with Subgraph's OpenSource/Libre policies on software security, we propose instead a solution based on JavaCards. While the crypto primitives are still closed source (since they are part of the ASIC chip itself), we can verify and modify the implementations to our liking. It should be noted that we do not recommend you generate any keys on the card itself. Instead you should use a trusted, air-gapped, machine (possibly with an entropykey) to generate trusted keys which we will load onto the card.

Building and flashing the JavaCard


Building for the JavaCards is very easy, assuming you are running Debian you will want to install a Java JRE and JDK, the ant build tools, and git:

# apt-get install openjdk-7-jre openjdk-7-jdk ant git-core

Now we will checkout the repositories. We need the Java Applets and the GlobalPlatform tools by martinpaljak.

$ mkdir ~/Documents/JCOP
$ cd ~/Documents/JCOP
$ git clone

$ git clone
# Alternatively you can also use this other applet:
$ svn checkout svn:// JavacardOpenPGP


Now that you have the repositories building is as simple as running ant in the top level of both repositories.

$ cd GlobalPlatform
$ ant
$ cd ..

$ cd AppletPlayground
# Or if you are using Joeri's applet:
$ cd JavacardOpenPGP

$ ant

You should end up with a lot of .cap files in the AppletPlayground, including the one we are interested in: FluffyPGPApplet.cap (or in bin/openpgpcard/javacard/openpgpcard.cap).

In the GlobalPlatform repository, we end up with the flashing tool called gp.jar.


Hopefully your reader is USB CCID/PCSC compatible and will not require any drivers for flash (note that it will still require some drivers to use the card later).

$ java -jar ~/Documents/GlobalPlatform/gp.jar --list

This should return:

AID: A000000003000000 (|........|)
    ISD INITIALIZED: Security Domain, Card lock, Card terminate, Default selected, CVM (PIN) management

AID: A0000000035350 (|.....SP|)
    ExM LOADED: (none)
    A000000003535041 (|.....SPA|)

Now we can flash our applet on the card as such:

$ java -jar ~/Documents/JCOP/GlobalPlatform/gp.jar --install ~/Documents/JCOP/AppletPlayground/FluffyPGPApplet.cap --default
# Or alternatively
$ java -jar ~/Documents/JCOP/GlobalPlatform/gp.jar --install ~/Documents/JCOP/JavacardOpenPGP/bin/openpgpcard/javacard/openpgpcard.cap --default

There is no output, so we run gp.jar --list again to see the result:

$ java -jar ~/Documents/GlobalPlatform/gp.jar --list

AID: A000000003000000 (|........|)
     ISD INITIALIZED: Security Domain, Card lock, Card terminate, CVM (PIN) management

AID: D2760001240102000000000000010000 (|.v..$...........|)
     App SELECTABLE: Default selected

AID: D27600012401 (|.v..$.|)
     ExM LOADED: (none)
     D2760001240102000000000000010000 (|.v..$...........|)

Changing the keys on the card

The card has its own set of default keys used to protect the applets. Until you are certain that you have the card configured and working it is not recommended that you change these as if you forget the new keys you will be unable to wipe the card and start over. However it is recommend that you do change the keys once the card is configured and working to your liking.

To do so we will use GlobalPlatform again, obviously you will want to change 010B0371D78377B801F2D62AFC671D95 to your own key. Make sure you store the key in a safe place if you want to be able to program the card again.

$ java -jar ~/Documents/JCOP/GlobalPlatform/gp.jar --lock 010B0371D78377B801F2D62AFC671D95


Our applet is now ready for use! However we most likely do not have the drivers necessary for our card reader to be used with GPG. If we did (or if your reader does not require any drivers - like some OmniKey CardMan) we would see something like this:

$ GPG_AGENT_INFO= /usr/bin/gpg --card-status

gpg: detected reader `ACS ACR 38U-CCID 00 00'
Application ID ...: D2760001240102000000000000010000
Version ..........: 2.0
Manufacturer .....: test card
Serial number ....: 00000001
Name of cardholder: [not set]
Language prefs ...: [not set]
Sex ..............: unspecified
URL of public key : [not set]
Login data .......: [not set]
Private DO 1 .....: [not set]
Private DO 2 .....: [not set]
Signature PIN ....: forced
Key attributes ...: 2048R 2048R 2048R
Max. PIN lengths .: 32 32 32
PIN retry counter : 3 0 3
Signature counter : 0
Signature key ....: [none]
Encryption key....: [none]
Authentication key: [none]
General key info..: [none]

Configuring and using your OpenPGP JavaCard

If you got a reader from Subgraph you will need to install the following drivers:

# apt-get install pcscd pcsc-tools libccid libacr38u libacr38ucontrol0

If you have another card reader you will likely need to replace the libacr38u and libacr38ucontrol0 libraries with the appropriate ones for your device. The pcsc-tools package is optional.

Until a more detailed howto is written here, you should follow RiseUp's OpenPGP smartcard guide, or the FSFE OpenPGP card howto.