DIY Smartcard Authentication with SmartPGP

SECURITY DISCLAIMER: THE AUTHOR DOES IMPLY OR ENDORSE THAT THE PROCEDURES DEMONSTRATED IN THIS ARTICLE ARE SECURE AGAINS ATTACKS! Please do your own research whenever it comes to the security of your system!

What is a Smartcard

A smartcard is a portable device with a MCU (usually security-enhanced MCU) that can run programs stored in its secure memory, for example cryptographic algorithms. In other words, a smartcard is a "secure world" where you can store sensitive information, which systems outside of the card can use the information for authentication and encryption without revealing the secret stored.

What will you need

  • A Smartcard
    • JavaCard-based (Mine is JC30M48CR)
    • A guide can be found here
  • A Smartcard Reader
    • Any standard smartcard reader
    • Rule of thumb is to buy those can read SIM cards
    • Mine is Rocketek RT-SCR2 (Alcor Micro AU9560)
  • Latest GnuPG (GPG)

Great thanks to Fan Dang for kindly providing me with a card, you can visit his blog here.

Smartcard with Reader

Preparing the Card

First you need to install the following packages:

sudo pacman -S ant maven pcsclite pcsc-tools

Also make sure that you have OpenJDK 10 installed and selected with archlinux-java set java-10-openjdk

And install GlobalPlatformPro by Martin Paljak:

git clone https://github.com/martinpaljak/GlobalPlatformPro.git
cd GlobalPlatformPro
mvn package && ant

Now you can peek into your card with:

$ java -jar target/gp.jar -i
GlobalPlatformPro 19.01.22-3-g05a90c2
Running on Linux 5.0.9-arch1-1-ARCH amd64, Java 10.0.2 by Oracle Corporation
Reader: Alcor Micro AU9560 01 00
ATR: 3B90958011FE6A
More information about your card:
    http://smartcard-atr.appspot.com/parse?ATR=3B90958011FE6A

Card Data:
Card Capabilities:
Version: 255 (0xFF) ID:   1 (0x01) type: DES3 length:  16
Version: 255 (0xFF) ID:   2 (0x02) type: DES3 length:  16
Version: 255 (0xFF) ID:   3 (0x03) type: DES3 length:  16
Key version suggests factory keys

If you have multiple card readers, just add -r "Alcor Micro AU9560 01 00" to the command line (replace with your reader name).

> java -jar target/gp.jar -l
Warning: no keys given, using default test key 404142434445464748494A4B4C4D4E4F
ISD: A000000003000000 (OP_READY)
     Privs:   SecurityDomain, CardLock, CardTerminate, CardReset, CVMManagement

Now you can see that we have an empty card with default keys. Notice that this key is just like the root password of your system, so PLEASE CHANGE IT TO A SECURE ONE before using it as a secure device!

Now let's change the card key. Notice that this key is necessary for doing any administrative task on the card, so please keep it stored somewhere SAFE and DO NOT FORGET it.

First generate a true random secret with OpenSSL:

openssl rand --hex 16 | awk '{print toupper($0)}' > .card_secret

Now we can lock the card with this key:

cat .card_secret | xargs java -jar target/gp.jar -r "Alcor Micro AU9560 01 00" -lock
Warning: no keys given, using default test key 404142434445464748494A4B4C4D4E4F
Card locked with: D61B707C088B2F8829C7218FC839A664
Write this down, DO NOT FORGET/LOSE IT!

FROM THE POINT YOU LOCKED YOUR CARD, ALL COMMANDS MUST TAKE THE ARGUMENT -key {YOUR_SECRET} OR YOU MAY BRICK YOUR CARD!

However it is a great hassle if we need to add the key to our command each time, so we can first unlock the card, if we can remember to LOCK BEFORE USING THE CARD AS SECURE!

Now we unlock the card with:

cat .card_secret | xargs java -jar target/gp.jar -r "Alcor Micro AU9560 01 00" -unlock -key
Default type=DES3 bytes=404142434445464748494A4B4C4D4E4F kcv=8BAF47 set as master key for A000000003000000

Again, REMEMBER TO LOCK THE CARD BEFORE PRODUCTION!

Building SmartPGP

SmartPGP is an open-source implementation of the OpenPGP card specification, which works with GnuPG for secure signing and encryption.

To build SmartPGP, first clone the SmartPGP repository:

git clone https://github.com/ANSSI-FR/SmartPGP.git
git checkout javacard-3.0.1 # Only this version fits in 80K of memory
# If your card has larger Flash, just use the master branch
# If master fails to build, checkout this branch and retry

And add the JavaCard SDK:

git submodule add https://github.com/martinpaljak/oracle_javacard_sdks sdks

Now you need to change the config parameters for SmartPGP.

First specify the SDK path with jckit= in build.xml:

    <javacard jckit="./sdks/jc304_kit">
      <cap output="SmartPGPApplet.cap" sources="src" aid="d27600012401" version="1.0">
        <applet class="fr.anssi.smartpgp.SmartPGPApplet" aid="d276000124010303AFAF000000000000"/>
      </cap>
    </javacard>

The original SmartPGP requires too much on-card RAM, which will lead to errors when loading the applet. To reduce the RAM usage, change src/fr/anssi/smartpgp/Constants.java:

    protected static final short INTERNAL_BUFFER_MAX_LENGTH =
        (short)0x300;

Now we can start building the applet by:

ant

which will create the applet CAP file SmartPGPApplet.cap.

Installation of the Applet

Now it is time to install the applet to your card:

java -jar target/gp.jar -r "Alcor Micro AU9560 01 00" -install ../SmartPGP/SmartPGPApplet.cap
Warning: no keys given, using default test key 404142434445464748494A4B4C4D4E4F
CAP loaded

If it shows

Warning: no keys given, using default test key 404142434445464748494A4B4C4D4E4F
CAP loaded
INSTALL [for install and make selectable] failed: 0x6985 (Conditions of use not satisfied)

Your card do not have enough RAM and you need to decrease the INTERNAL_BUFFER_MAX_LENGTH parameter.

If it shows

Warning: no keys given, using default test key 404142434445464748494A4B4C4D4E4F
Loading failed. Are you sure the CAP file (JC version, packages, sizes) is compatible with your card?
LOAD failed: 0x6A80 (Wrong data/incorrect values in data)

Your card do not support the JavaCard SDK version. Please try a lower version of the SDK, e.g. jc304_sdk if you are using jc305u1_sdk or higher.

Now you should LOCK YOUR CARD by:

cat .card_secret | xargs java -jar target/gp.jar -r "Alcor Micro AU9560 01 00" -lock

Setting up the card

Just follow the Debian wiki at https://wiki.debian.org/Smartcards/OpenPGP.

If you want to use the card for system login, try Poldi.

If you have questions or problems, please ask in the comments area below.

Wish you a nice journey playing with smartcards!

Reference

A list of JavaCard goodies can be found at https://github.com/EnigmaBridge/javacard-curated-list