18. Sep 2015

7 Min.

Smartcards

Es gibt verschiedene Wege, Daten und Zugänge vor unbefugten und ungewünschten Nutzern zu schützen. Am verbreitetsten ist wohl die Passwortabfrage. Längst haben wir in unserem digitalen Leben die richtige Zusammensetzung eines guten Passwortes erlernt.

  • Es ist mindestens 16 Zeichen lang.
  • Es setzt sich aus einer Kombination von Buchstaben, Zahlen, Sonderzeichen und den Tränen einer Jungfrau zusammen.
  • Es wird nur für einen Account verwendet.

Gerade der letzte Punkt wird auf Kosten der Sicherheit oft vernachlässigt. Abhilfe versprechen sogenannte Passwortmanager. Deren Kernfeature leider auch die Achillesferse darstellt: das Masterpasswort. Ein Schwachpunkt, den sich Passwörter mit SSH-Keys teilen, die im Keyring gespeichert werden.

Glücklicherweise hat sich in den letzten paar Jahren die Zwei-Faktor-Authentifizierung (kurz 2FA) für einige beliebte Dienste (Google, Facebook, GitHub, …) durchgesetzt, und die Situation etwas entschärft. Doch wie können wir andere kritische Bereiche, bei denen keine 2FA implementiert werden kann, absichern – z.B. unser Git-Repository?

Hier kommen Smartcards ins Spiel.

Was ist eine Smartcard?

Jeder hat schon einmal mit einer Smartcard bzw. Chipkarte hantiert. Praktisch alle aktuellen Bankomatkarten sind Chipkarten, ebenso wie zum Beispiel die österreichische e-card/Bürgerkarte.

Auf dem Chip befindet sich ein eigenes Betriebssystem (oftmals auf Java-Basis), und ein Speicherbereich, auf welchem ein oder mehrere Schlüsselpaare und andere Informationen gespeichert werden. Die Kommunikation mit Smartcards verläuft je nach Art und Einsatzzweck der Smartcard über unterschiedliche, standardisierte Schnittstellen (z.B. EMV bei Bankomat-Karten).

Smartcards, die wir für unseren Anwendungszweck verwenden können, implementieren die Standards PKCS #11 und PKCS #15 – wobei letzterer mittlerweile durch den ISO/IEC 7816-15-Standard abgelöst wurde:

  • PKCS #11 definiert standardisierte Schnittstellen für die Kommunikation mit Smartcards (z.B. um Daten mit dem Private-Key zu signieren).
  • PKCS #15 definiert die Datenstruktur auf der Smartcard (damit können wir unter anderem den Public-Key wieder auslesen).

Die besondere Eigenschaft einer Smartcard ist, dass ein dort gespeicherter Private-Key unter normalen Umständen nicht wieder ausgelesen werden kann. Zudem verlangt die Smartcard vor dem Durchführen einer Operation einen benutzerdefinierten PIN.

Anwendungen, welche den Private-Key für ihre Zwecke nutzen möchten, müssen dies über die PKCS #11-Schnittstelle durchführen. Dabei findet die eigentliche kryptographische Operation auf dem Chip statt. Die Anwendung bekommt nur das Ergebnis zurückgeliefert.

Konkrete Umsetzung: SSH

Für das Speichern von GnuPG-Schlüsselpaaren ist die OpenPGP-Card hervorragend geeignet. GnuPG-Schlüsselpaare können problemlos in SSH-Schlüsselpaare konvertiert werden. Die OpenPGP-Card implementiert bzw. emuliert beide oben genannte Standards und wird somit von OpenSC unterstützt. Das ist essentiell für die Verwendung mit SSH.

Ich persönlich verwende den Smartcard-Reader Identive SCR 3500 Smartfold mit einer „normalen“ OpenPGP-Card. Theoretisch kann ich somit auch andere Smartcards verwenden. Alternativ kann auch eine kompaktere OpenPGP-Card im SIM-Kartenformat mit einer Gemalto IDBridge K50 verwendet werden – dieses Setup kommt auch in diesem Blog-Post zum Einsatz.

Das Setup wurde mit Ubuntu 15.04 gestestet. Die Commands sollten sich bei anderen Linux-Distributionen aber (bis auf die Paketnamen) nicht unterscheiden.

Schritt 1: Initialisieren der OpenPGP-Card

Aus Sicherheitsgründen erzeugen wir den Private-Key nicht auf unserem PC, sondern direkt auf der Smartcard. Grundsätzlich kann die Smartcard auch mit GnuPG v1 initialisiert werden, allerdings kann diese nicht ordentlich mit Unicode-Zeichen in Namen umgehen. Ich installiere daher GnuPG v2 und notwendige Tools, um mit der Smartcard kommunizieren zu können:

root@fallgaeuer:~# apt-get install gnupg2 scdaemon pcscd

Anschließend den pcscd-Service starten und die Karte initialisieren. Aufgrund eines Bugs im pcscd-Paket kann die Karte zumindest mit GnuPG nur als root bearbeitet werden:

root@fallgaeuer:~# systemctl start pcscd
root@fallgaeuer:~# gpg2 --card-edit
[…]
gpg/card> admin
Admin commands are allowed
                
gpg/card> generate
[…]
public and secret key created and signed.
                
gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0  valid:   2  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 2u
pub   2048R/4D0E1092 2015-09-11
      Key fingerprint = CF0D A339 1CF2 C033 4816  146E DEB3 52C8 4D0E 1092
uid                  Fabian Allgäuer <fabian.allgaeuer@fusonic.net>
sub   2048R/AE68653C 2015-09-11
sub   2048R/504E20A1 2015-09-11
                
gpg/card> quit

Schritt 2: SSH-Public-Key wieder auslesen

Für das Auslesen des Keys (und für die spätere Authentifizierung) benötigen wir GnuPG so gesehen nicht mehr; dies übernimmt OpenSC:

root@fallgaeuer:~# apt-get install opensc

Wie bereits erwähnt spezifiziert PKCS #15 die Datenstruktur auf der Smartcard. Bei der OpenPGP-Card befindet sich der Authentication-Key (d.h. unser SSH-Key) immer im Slot 3:

fallgaeuer@fallgaeuer:~$ pkcs15-tool -k
[…]
Private RSA Key [Authentication key]
    Object Flags   : [0x3], private, modifiable
    Usage          : [0x222], decrypt, unwrap, nonRepudiation
    Access Flags   : [0x1D], sensitive, alwaysSensitive, neverExtract, local
    ModLength      : 2048
    Key ref        : 2 (0x2)
    Native         : yes
    Auth ID        : 02
    ID             : 03
    MD:guid        : {903f854b-876d-9a89-214e-064e2918a164}
      :cmap flags  : 0x0
      :sign        : 0
      :key-exchange: 0
                
fallgaeuer@fallgaeuer:~$ pkcs15-tool --read-ssh-key 03
Using reader with a card: Gemalto USB Shell Token V2 (335D6102) 00 00
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCNHN8cWz7G/Gob6/cBAiiEJg86WBydpudom1SWe0wCZ82us/G6W8mrpzpxywEJj06FwNwC16gHx/2eO2cxCrnRE7h/K7rhKlkTMx6yXKxfwbRKcfq+epd6ifpxbzRIxv2+Ppta1k7A56PH47k4Pc4DMKOnh33dBa6Y5pi8anBDXaMahJthyhvnM3Q1BL6iVz/2lYR0YQYAESrZ23cdN2WqadGa7HgFUPyO1ygYlIfTAIvB2eywOdmAIWp1bgOeSWfFbpz8+U32YZrqwApjd+yVHnOFZdRxZtAu9GqLJvmJ8XC1PoUkwIhdcmd5k2yF0M19M+YWuI2FIbB1d4pGUgn1

Diesen Key können wir jetzt in die authorized_keys-Datei auf dem Server hinterlegen, oder einfach ssh-copy-id verwenden:

fallgaeuer@fallgaeuer:~$ pkcs15-tool --read-ssh-key 03 > /tmp/card.pub && touch /tmp/card && ssh-copy-id -i /tmp/card fallgaeuer@fe80::a00:27ff:fe61:a5ca%eth1
Using reader with a card: Gemalto USB Shell Token V2 (335D6102) 00 00
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
fallgaeuer@fe80::a00:27ff:fe61:a5ca%eth1's password:
                
Number of key(s) added: 1
                
Now try logging into the machine, with:   "ssh 'fallgaeuer@fe80::a00:27ff:fe61:a5ca%eth1'"
and check to make sure that only the key(s) you wanted were added

Anmerkung zum obigen Befehl: ssh-copy-id prüft vor dem Kopieren, ob tatsächlich ein Schlüsselpaar vorhanden ist. Leider aber versteht ssh-copy-id nicht die notwendige Konfigurations-Option, um mit der Smartcard kommunizieren zu können. Wir legen daher einfach eine leere Datei /tmp/card an, um ssh-copy-id zufrieden zu stellen.

Schritt 3: Testen

Wir müssen dem SSH-Client nun mitteilen, dass sich der Private-Key nicht auf der lokalen Festplatte bzw. im Keyring befindet, sondern via PKCS #11 angesprochen werden muss.

Die hierfür notwendige Library wird von OpenSC mitgeliefert und befindet sich – je nach Distribution – an unterschiedlichen Orten:

fallgaeuer@fallgaeuer:~$ find / -name opensc-pkcs11.so -ls 2>/dev/null
262023    0 lrwxrwxrwx   1 root     root           19 Feb  7  2015 /usr/lib/x86_64-linux-gnu/pkcs11/opensc-pkcs11.so -> ../opensc-pkcs11.so
133936  192 -rw-r--r--   1 root     root       195376 Feb  7  2015 /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so

Diesen Pfad können wir entweder

  • direkt an den SSH-Client übergeben:
ssh -I /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so
  • oder in die ~/.ssh/config eintragen:
Host *
PKCS11Provider /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so

Und wir haben es geschafft! – Wir haben das sicherste Kartenhaus der Welt errichtet.

fallgaeuer@fallgaeuer:~$ ssh fallgaeuer@fe80::a00:27ff:fe61:a5ca%eth1
Enter PIN for 'OpenPGP card (User PIN)':
Last login: Fri Sep 11 13:04:41 2015
[fallgaeuer@centos-vm ~]$

Wir können unsere Smartcard jetzt überall mitnehmen, und benötigen im Grunde genommen nur ein installiertes OpenSC, um die Smartcard verwenden zu können. Diesen Key können wir auch bei Github, Bitbucket und co. hinterlegen.

Spätestens jetzt sollte klar sein, warum Schlüsselkarten in Agentenfilmen immer so wichtig sind.