Smartcard Based Authentication: Difference between revisions
No edit summary |
Fbechstein (talk | contribs) |
||
(109 intermediate revisions by 11 users not shown) | |||
Line 1: | Line 1: | ||
TODO: |
|||
-CRL |
|||
-Smartcard entsperren |
|||
'''Lizenz'''<br> |
|||
Copyright (c) Esther Fuhrmann, Carsten Krüger, Henryk Plötz<br> |
|||
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; |
|||
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. |
|||
A copy of the license is included in the section entitled "GNU Free Documentation License". |
|||
'''Einleitung''' |
'''Einleitung''' |
||
Es gibt viele Anwendungsfälle, bei denen man sich authentifizieren muss, zum Beispiel gegenüber Webseiten oder Rechnern. Dabei kommen meist Kombinationen aus Nutzername und Passwort zum Einsatz. Dieses Verfahren bietet zahlreiche Angriffspunkte |
Es gibt viele Anwendungsfälle, bei denen man sich authentifizieren muss, zum Beispiel gegenüber Webseiten oder Rechnern. Dabei kommen meist Kombinationen aus Nutzername und Passwort zum Einsatz. Dieses Verfahren bietet zahlreiche Angriffspunkte: schwache Passwörter können schnell erraten werden, Nutzer schreiben ihre Passwörter auf Zettel, die an den Monitor geklebt werden usw. Smartcards umgehen viele dieser Probleme, da sie die Authentifizierung per Passwort durch ein zertifikatsbasiertes Anmeldeverfahren ersetzen können. Dadurch braucht man nicht mehr viele verschiedene Passwörter, sondern nur noch eine Karte und eine PIN. Außerdem kann eine Smartcard im Gegensatz zu einem Passwort oder einem Fingerabdruck nicht, oder nur mit sehr großem Aufwand, kopiert werden, so dass ein Verlust des Authentifizierungsmerkmals dem Benutzer sofort auffällt. |
||
=Hintergründe= |
=Hintergründe= |
||
Line 17: | Line 7: | ||
==Überblick über den Software-Stack== |
==Überblick über den Software-Stack== |
||
[[Image:Stack.png|Software-Stack]]<br> |
|||
<pre> |
|||
[[Software-Stack-ASCII|ASCII-Version]] |
|||
+----------------------------------------+ |
|||
| Applikation (z.B. PAM) | |
|||
+------------------pkcs11----------------+ |
|||
| OpenSC (PKCS#11) | |
|||
+-----------------PC/SC------------------+ |
|||
| PC-SC-Lite | |
|||
+---------------ifdhandler---------------+ |
|||
| Treiber (z.B. omnikey) | |
|||
+----------------------------------------+ |
|||
| Linux-Kernel | |
|||
+----------------------------------------+ |
|||
</pre> |
|||
==Was ist PAM?== |
==Was ist PAM?== |
||
Ein PAM |
Ein PAM kapselt die Authentifizierung und stellt Applikationen (z.B. login, ftpd, screensaver) eine einheitliche Schnittstelle bereit, so dass man die Authentifizierungsmethode (z.B. Passwort, Biometrie, Smartcard) flexibel auswechseln kann, ohne dass Applikationen daran angepasst werden müssen.<br> |
||
Für jede Applikation bestimmt eine Konfigurationsdatei in /etc/pam.d/, welche Authentifizierungsmethoden sie akzeptiert. Die Konfigurationsdateien enthalten mindestens 3 Spalten. In der ersten steht der Modultyp (auth, account, password, session), in der zweiten steht die Modulsteuerung (required, requisite, sufficient, optional) und in der dritten der Name des Moduls. Es können weitere Spalten mit Modulparametern folgen. |
|||
==Was ist OpenSC?== |
==Was ist OpenSC?== |
||
OpenSC ist eine Sammlung von Bibliotheken, die der |
OpenSC ist eine Sammlung von Bibliotheken, die der Kommunikation mit Smartcards dient. Unter anderem werden die Standards PKCS#11 (Cryptoki) und PKCS#15 implementiert. |
||
PKCS#15 |
|||
==Was ist |
==Was ist PKCS#11?== |
||
PKCS#11 ist ein Standard, der eine Programmierschnittstelle für Security Tokens wie z.B. Smartcards definiert.<br> |
|||
Aus Sicht von PKCS#11 ist solch ein Token ein Gerät, das Objekte speichert und darauf kryptografische Funktionen ausführen kann. Solche Objekte können Daten, Zertifikate oder Schlüssel sein und Objekte können privat oder öffentlich sein.<br> |
|||
[[Image:Pkcs11.png|PKCS#11]]<br> |
|||
2 Arten von Nutzern können mit den Token umgehen, der normale Nutzer und der sogenannte Security Officer (SO). Der normale Benutzer ist der, der die Karte benutzen soll, nur er hat z.B. Zugriff auf private Objekte. Der SO ist für die Initialisierung der Karte zuständig und hat nur Zugriff auf öffentliche Objekte.<br> |
|||
Applikationen kommunizieren mit dem Token über Sessions, wobei es sowohl read/write-Sessions als auch read-only-Sessions gibt. Eine Session kann sich als SO oder Nutzer einloggen und je nach Berechtigung Objekte lesen, erzeugen oder manipulieren oder sie kann kryptografische Operationen ausführen. Die Applikation führt den Zugriff auf das Token über Handles (vergleichbar Filehandles) aus, wobei man Session-Handles, die die jeweilige Session identifizieren, und Object-Handles, mit denen man auf Objekte zugreifen kann, unterscheidet. Eine Applikation kann gleichzeitig mehrere Sessions für ein Token offen haben, wobei diese sich immer im gleichen Zustand befinden (z.B. alle public, user oder SO). |
|||
Man kann Objekte so markieren, dass man sie nicht mehr von der Karte exportieren kann (z.B. den privaten Schlüssel). |
|||
==Was ist |
==Was ist PKCS#12?== |
||
PKCS#12 ist ein Containerformat, mit dem man Zertifikate und Schlüssel in eine Datei bringen kann, um diese dann zum Beispiel auf eine Smartcard oder ein Backupmedium zu kopieren. |
|||
==Was ist PKCS#15?== |
|||
PKCS#15 ist ein Standard, der definiert, wie man Zertifikate, Schlüssel und andere Daten auf Smartcards speichert. |
|||
==Was ist PCSC-Lite?== |
|||
PCSC-Lite ist eine Implementierung von PC/SC. PC/SC abstrahiert den Card Reader, so dass eine Applikation, die auf einen Card Reader zugreifen will, dessen Details nicht kennen muss. |
|||
==Was ist ein IFD-Handler?== |
|||
Der IFD-Handler ist eine Low-Level-Software, die den Zugriff auf die I/O-Channels des Smart Card Readers unterstützt. |
|||
==Was sind CAs?== |
|||
Eine CA (Certification Authority) ist eine Stelle, die digitale Zertifikate ausstellt. Ein solches Zertifikat ist eine durch die digitale Signatur der CA beglaubigte Zuordnung von einem öffentlichen Schlüssel zu einer Person oder Organisation.<br> |
|||
Dabei bilden verschiedene CAs eine baumartige Hierarchie. Die Root-CA bildet die Wurzel, die ihr Zertifikat als einzige Stelle selbst signiert, da es keine übergeordnete Stelle gibt. Für die CAs auf den Stufen darunter signiert jeweils die nächsthöhere Stelle das CA-Zertifikat. Die Blätter des Baums bilden die Nutzerzertifikate, die ihrerseits keine Zertifikate mehr ausstellen können. Auf diese Weise bilden sich sogenannte Chains of Trust. |
|||
==Was passiert beim Login?== |
|||
# pam_modul sucht nach Smartcard |
|||
# PIN wird an Karte übergeben (Login auf Karte) |
|||
# Private Key wird gesucht |
|||
# X509 Zertifikat wird gesucht |
|||
# Zertifikat wird verifiziert |
|||
# prüfen auf zurückgezogenes Zertifikat |
|||
# Mapping von Zertifikat auf User |
|||
# auf dem PC wird eine 128 Byte Zufallszahl erzeugt (diese wird gehashed) |
|||
# die Karte signiert den Hash |
|||
# Die Signatur wird durch den PC verifiziert |
|||
# Logout auf Karte |
|||
# User auf PC erfolgreich eingeloggt |
|||
=Was wird gebraucht?= |
=Was wird gebraucht?= |
||
==Hardware== |
==Hardware== |
||
* Cardreader (z.B. Omnikey Cardman 2020 USB, http://www.omnikey.com/) |
* Cardreader (z.B. Omnikey Cardman 2020 USB, [http://www.omnikey.com/ http://www.omnikey.com/]) <!-- Dieser 'lustige' Linkstil ist nötig, damit das ) kein Teil des Links wird --> |
||
* Smartcard (z.B. Schlumberger Cryptoflex 32k e-gate, http://www.axalto.com/) |
* Smartcard (z.B. Schlumberger Cryptoflex 32k e-gate, [http://www.axalto.com/ http://www.axalto.com/]) |
||
==Software== |
==Software== |
||
Line 85: | Line 98: | ||
==omnikey== |
==omnikey== |
||
* Download: http://www.omnikey.com/ - Support - Downloads |
* Download: http://www.omnikey.com/ - Support - Downloads |
||
* Installation mit Parameter - |
* Installation mit Parameter --nopcscd, da die Prüfung, ob PCSC schon enthalten ist, bei beta6 fehlschlägt |
||
cd |
cd |
||
tar xfz cm2020_installer_v2_4_0_src.tar.gz |
tar xfz cm2020_installer_v2_4_0_src.tar.gz |
||
Line 126: | Line 139: | ||
basicConstraints = critical,CA:FALSE |
basicConstraints = critical,CA:FALSE |
||
=Anwendungen= |
|||
==pam_PKCS11== |
==pam_PKCS11== |
||
cd |
cd |
||
Line 140: | Line 154: | ||
pam_pkcs11.conf editieren und alle Pfade anpassen: '''/usr/ -> /usr/local/''' |
pam_pkcs11.conf editieren und alle Pfade anpassen: '''/usr/ -> /usr/local/''' |
||
use_first_pass = true; |
use_first_pass = true; |
||
ca_dir = /etc/openssl |
ca_dir = /etc/openssl; |
||
crl_dir = /etc/openssl/crl; |
|||
crl_policy = offline; |
|||
'''Debugging:'''<br> |
|||
Wenn das Login funktioniert debug auf false setzen |
|||
wenig Debug (Debugging des PAM-Moduls):<br> |
|||
/etc/pkcs11/pam_pkcs11.conf |
|||
debug = true |
|||
starkes Debug (Debugging mit Hilfe von pkcs11-spy):<br> |
|||
/etc/pkcs11/pam_pkcs11.conf |
|||
<pre> |
|||
pkcs11_module opensc { |
|||
#module = /usr/local/lib/pkcs11/opensc-pkcs11.so; |
|||
module = /usr/local/lib/pkcs11/pkcs11-spy.so; |
|||
. |
|||
. |
|||
. |
|||
</pre> |
|||
/etc/opensc.conf |
|||
<pre> |
|||
app pkcs11-spy { |
|||
spy { |
|||
output = /root/pkcs11-spy.log; |
|||
module = /usr/lib/pkcs11/opensc-pkcs11.so; |
|||
} |
|||
} |
|||
</pre> |
|||
===optional: pkcs11_eventmgr=== |
|||
automatisches screen locken mit xscreensaver |
|||
/etc/pam_pkcs11/pkcs11_eventmgr.conf |
|||
<pre> |
|||
pkcs11_eventmgr { |
|||
# Run in background? Implies debug=false if true |
|||
daemon = true; |
|||
# show debug messages? |
|||
debug = false; |
|||
# polling time in seconds |
|||
polling_time = 1; |
|||
# expire time in seconds |
|||
# default = 0 ( no expire ) |
|||
expire_time = 0; |
|||
# pkcs11 module to use |
|||
pkcs11_module = /usr/local/lib/opensc-pkcs11.so; |
|||
# |
|||
# list of events and actions |
|||
# Card inserted |
|||
event card_insert { |
|||
# what to do if an action fail? |
|||
# ignore : continue to next action |
|||
# return : end action sequence |
|||
# quit : end program |
|||
on_error = ignore ; |
|||
# You can enter several, comma-separated action entries |
|||
# they will be executed in turn |
|||
action = "screensaver-command -deactivate"; |
|||
} |
|||
# Card has been removed |
|||
event card_remove { |
|||
on_error = ignore; |
|||
action = "xscreensaver-command -lock"; |
|||
} |
|||
# Too much time card removed |
|||
event expire_time { |
|||
on_error = ignore; |
|||
action = "/bin/false"; |
|||
} |
|||
} |
|||
</pre> |
|||
==apache2== |
|||
<pre> |
|||
makeclient.sh server |
|||
a2enmod ssl |
|||
</pre> |
|||
/etc/apache2/ports.conf |
|||
<pre> |
|||
Listen 80 |
|||
Listen 443 |
|||
</pre> |
|||
/etc/apache2/sites-enabled/default-ssl |
|||
<pre> |
|||
NameVirtualHost *:443 |
|||
<VirtualHost 127.0.0.1:443> |
|||
SSLEngine on |
|||
SSLVerifyClient require |
|||
SSLVerifyDepth 2 |
|||
SSLCACertificateFile /etc/openssl/cacert.crt |
|||
SSLCertificateFile /etc/apache2/ssl/servercacert.pem |
|||
SSLCertificateKeyFile /etc/apache2/ssl/serverkey.pem |
|||
SSLOptions +StdEnvVars |
|||
ServerName localhost |
|||
DocumentRoot /var/www/ |
|||
CustomLog /var/log/apache2/ssl.log "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x %{SSL_CLIENT_S_DN}x \"%r\" %b" |
|||
</VirtualHost> |
|||
</pre> |
|||
==firefox== |
|||
lade unter edit/preferences/advanced/security devices das modul /usr/local/lib/opensc-pkcs11.so |
|||
==openssh== |
|||
* openssh-quellen patchen ..opensc/src/openssh/ask-for-pin.diff |
|||
* configure mit --with-opensc=/usr/local aufrufen |
|||
* openssh bauen |
|||
* mit pkcs15-tool --read-ssh-key <num> den publickey auslesen und auf dem zielhost installieren |
|||
* ./ssh -I 0 <host> |
|||
==Generierung von Schlüsseln auf einer Smartcard== |
|||
Einige Smardcards verfügen über einen eigenen Zufallszahlengenerator und sind in der Lage |
|||
Public-/Privatekeypaare zu erzeugen. Der private Schlüssel muß also nie auf einem anderen |
|||
Gerät gespeichert werden. Im Folgenden wird ein Zertifikat unter Ausnutzung dieser Fähigkeit erstellt. |
|||
verwendete Smartcard: Starcos SPK 2.3 |
|||
* Initialisieren der Karte: |
|||
: pkcs15-init -E -C -p pkcs15+onepin |
|||
* Erzeugen eines RSA-Schlüssels auf der Karte: |
|||
: pkcs15-init -G rsa/1024 -a 1 |
|||
* Starten einer openssl-Shell |
|||
* Laden der pkcs11 engine in openssl |
|||
: OpenSSL> engine dynamic -pre SO_PATH:/usr/lib/engines/engine_pkcs11.so -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD -pre MODULE_PATH:/usr/local/lib/opensc-pkcs11.so |
|||
* Erzeugen einer Zertifikatsanforderung für den auf der Karte generierten Schlüssel |
|||
: OpenSSL> req -engine pkcs11 -new -key id_45 -keyform engine -out req.pem \ |
|||
::: -text -subj '/C=DE/ST=Berlin/L=Berlin/O=Humboldt-Universitaet zu Berlin/OU=Informatik/OU=ca-test/CN=Max Mustermann' |
|||
* Austellen des Zertifikates |
|||
: openssl x509 -req -in req.pem -out "cert.pem" -CA /etc/ssl/cacert.pem -CAkey /etc/ssl/private/cakey.pem -CAserial /etc/ssl/serial |
|||
* Kopieren des Zertifikates auf die Smartcard |
|||
: pkcs15-init -X cert.pem |
|||
Weitere Infos unter http://www.opensc-project.org/opensc/wiki/QuickStart |
|||
=Skripte= |
=Skripte= |
||
Die folgenden Skripte erzeugen eine CA bzw. Clientzertifikate und schreiben letztere auf die Karte. |
|||
Die privaten Schlüssel und die CSRs könnten auch direkt auf den Karten generiert werden, |
|||
bei unseren Tests hängte sich aber das komplette System auf. |
|||
Auf den Rechnern an denen man sich anmelden will muss und sollte nur das cacert vorhanden sein. |
|||
==makeca.sh== |
==makeca.sh== |
||
===Code=== |
|||
#!/bin/sh |
|||
<pre> |
|||
rm -rf /etc/openssl |
|||
#!/bin/sh |
|||
echo "Erzeuge Verzeichnisse..." |
|||
echo "Lösche /etc/openssl ..." |
|||
rm -rf /etc/openssl |
|||
echo "Erzeuge Verzeichnisse..." |
|||
mkdir certs crl private pkcs12 |
|||
mkdir /etc/openssl |
|||
chmod 700 private/ |
|||
cd /etc/openssl |
|||
chmod 700 pkcs12/ |
|||
mkdir certs crl private pkcs12 |
|||
echo "Erzeuge CAkey..." |
|||
chmod 700 private/ |
|||
openssl genrsa -aes256 -out private/cakey.pem 2048 |
|||
chmod 700 pkcs12/ |
|||
echo "Erzeuge CAcert..." |
|||
echo "Erzeuge CAkey..." |
|||
openssl req -new -x509 -days 3650 -key private/cakey.pem -out cacert.pem -set_serial 1 \ |
|||
openssl genrsa -aes256 -out private/cakey.pem 2048 |
|||
-subj '/C=DE/ST=Berlin/L=Berlin/O=Humboldt-Universitaet zu Berlin/OU=Informatik/OU=ca-test/CN=ca' |
|||
echo "Erzeuge CAcert..." |
|||
touch index.txt |
|||
openssl req -new -x509 -days 3650 -key private/cakey.pem -out cacert.pem -set_serial 1 \ |
|||
echo 01 > serial |
|||
-subj '/C=DE/ST=Berlin/L=Berlin/O=Humboldt-Universitaet zu Berlin/OU=Informatik/OU=ca-test/CN=ca' |
|||
make_hash_link.sh /etc/openssl/ |
|||
touch index.txt |
|||
echo 01 > serial |
|||
make_hash_link.sh /etc/openssl/ |
|||
echo "Erzeuge Certificate Revocation List..." |
|||
openssl ca -gencrl -out /etc/openssl/crl/crl.pem |
|||
make_hash_link.sh /etc/openssl/crl/ |
|||
</pre> |
|||
===Erläuterung=== |
|||
<pre> |
|||
openssl genrsa -aes256 -out private/cakey.pem 2048 |
|||
</pre> |
|||
'''genrsa''' generiert einen privaten RSA-Schlüssel<br> |
|||
'''-aes256''' verschlüsselt den Schlüssel mit AES 256 Bit<br> |
|||
'''-out''' schreibt den Schlüssel in eine Datei<br> |
|||
'''2048''' ist die Größe des Schlüssels in Bit<br> |
|||
<pre> |
|||
openssl req -new -x509 -days 3650 -key private/cakey.pem -out cacert.pem -set_serial 1 \ |
|||
-subj '/C=DE/ST=Berlin/L=Berlin/O=Humboldt-Universitaet zu Berlin/OU=Informatik/OU=ca-test/CN=ca' |
|||
</pre> |
|||
'''req''' stellt einen Request für ein Zertifikat<br> |
|||
'''-new''' zeigt an, dass es sich um einen Request für ein neues Zertifikat handelt<br> |
|||
'''-x509''' sorgt dafür, dass statt einem Request ein selbstsigniertes Zertifikat erzeugt wird<br> |
|||
'''-days''' Gültigkeit des Zertifikats in Tagen<br> |
|||
'''-key''' der Schlüssel, mit dem das Zertifikat signiert wird<br> |
|||
'''-out''' Datei, in die das Zertifikat geschrieben wird<br> |
|||
'''-set_serial''' Seriennummer für das Zertifikat<br> |
|||
'''-subj''' Subject für das Zertifikat<br> |
|||
<pre> |
|||
make_hash_link.sh /etc/openssl/ |
|||
</pre> |
|||
Erzeugt ein Hashfile für pam_pkcs11 |
|||
<pre> |
|||
openssl ca -gencrl -out /etc/openssl/crl/crl.pem |
|||
</pre> |
|||
'''ca''' |
|||
'''-gencrl''' generiert eine CRL auf Basis der index.txt |
|||
==makeclient.sh== |
==makeclient.sh== |
||
===Code=== |
|||
#!/bin/sh |
|||
<pre> |
|||
if [ "x"$1 == "x" ]; then |
|||
#!/bin/sh |
|||
echo "Bitte einen Clientparameter angeben." |
|||
. sslinit.sh |
|||
else |
|||
if [ "x$1" == "x" ]; then |
|||
cd /etc/openssl |
|||
echo "Bitte einen Clientparameter angeben." |
|||
else |
|||
openssl req -new -newkey rsa:1024 -out certs/${1}csr.pem -nodes -keyout private/${1}key.pem -days 365 -subj '/C=DE/ST=Berlin/L=Berlin/O=Humboldt-Universitaet zu Berlin/OU=Informatik/OU=ca-test/CN='${1} |
|||
MAILSTR="" |
|||
echo "Erzeuge Client-Cert..." |
|||
if [ "y$2" != "y" ]; then |
|||
openssl x509 -req -in certs/${1}csr.pem -out certs/${1}cert.pem -CA cacert.pem -CAkey private/cakey.pem -CAserial /etc/openssl/serial |
|||
MAILSTR="/emailAddress=${2}" |
|||
rm certs/${1}csr.pem |
|||
echo "PKCS#12-File erzeugen..." |
|||
openssl pkcs12 -export -chain -out pkcs12/${1}.pkcs12 -in certs/${1}cert.pem -inkey private/${1}key.pem -CAfile cacert.pem -passout pass: |
|||
fi |
fi |
||
cd $SSLPATH |
|||
echo "Erzeuge Client-Key und CSR..." |
|||
openssl req -new -newkey rsa:1024 -out "certs/${1}csr.pem" -nodes -keyout "private/${1}key.pem" \ |
|||
-days 365 -subj \ |
|||
'/C=DE/ST=Berlin/L=Berlin/O=Humboldt-Universitaet zu Berlin/OU=Informatik/OU=ca-test/CN='"${1}$MAILSTR" |
|||
echo "Erzeuge Client-Cert..." |
|||
openssl x509 -req -in "certs/${1}csr.pem" -out "certs/${1}cert.pem" -CA cacert.pem \ |
|||
-CAkey private/cakey.pem -CAserial $SSLPATH/serial |
|||
rm "certs/${1}csr.pem" |
|||
echo "PKCS#12-File erzeugen..." |
|||
openssl pkcs12 -export -chain -out "pkcs12/${1}.pkcs12" -in "certs/${1}cert.pem" \ |
|||
-inkey "private/${1}key.pem" -CAfile cacert.pem -passout pass: |
|||
fi |
|||
</pre> |
|||
== |
===Erläuterung=== |
||
openssl req -new -newkey rsa:1024 -out certs/${1}csr.pem -nodes -keyout private/${1}key.pem \ |
|||
-days 365 -subj \ |
|||
'/C=DE/ST=Berlin/L=Berlin/O=Humboldt-Universitaet zu Berlin/OU=Informatik/OU=ca-test CN='${1} |
|||
'''-newkey''' erzeugt einen neuen privaten Schlüssel<br> |
|||
'''-nodes''' erzeugten Schlüssel nicht symmetrisch verschlüsseln<br> |
|||
'''-keyout''' Datei, in die der neu erzeugte Schlüssel geschrieben wird<br> |
|||
openssl x509 -req -in certs/${1}csr.pem -out certs/${1}cert.pem -CA cacert.pem \ |
|||
-CAkey private/cakey.pem -CAserial /etc/openssl/serial |
|||
'''x509''' erzeugt ein Zertifikat gemäß Standard x509<br> |
|||
'''-req''' gibt an, dass man einen bestehenden Request angibt, der signiert und ausgegeben werden soll<br> |
|||
'''-in''' gibt den zu signierenden Request an<br> |
|||
'''-out''' Datei, in die das erzeugte Zertifikat ausgegeben werden soll<br> |
|||
'''-CA''' Zertifikat der CA, die das Zertifikat signiert<br> |
|||
'''-CAkey''' Schlüssel der CA, die das Zertifikat signiert<br> |
|||
'''-CAserial''' Seriennummerndatei<br> |
|||
openssl pkcs12 -export -chain -out pkcs12/${1}.pkcs12 -in certs/${1}cert.pem \ |
|||
-inkey private/${1}key.pem -CAfile cacert.pem -passout pass: |
|||
'''pkcs12''' erstellt eine Datei nach Standard PKCS#12<br> |
|||
'''-export''' gibt an, dass eine PKCS#12-Datei erzeugt werden soll (und nicht nur geparst)<br> |
|||
'''-chain''' es wird versucht, die gesamte Zertifikatskette einzubinden<br> |
|||
'''-out''' Dateiname für die PKCS#12-Datei<br> |
|||
'''-in''' Zertifikat, dass in den PKCS#12-Container geschrieben werden soll<br> |
|||
'''-inkey''' privater Schlüssel, der in den PKCS#12-Container geschrieben werden soll<br> |
|||
'''-CAfile''' CA-Zertifikat, das in den PKCS#12-Container geschrieben werden soll<br> |
|||
'''-passout''' Passphrase, mit der ausgegebene private Schlüssel verschlüsselt werden<br> |
|||
==Writecard== |
|||
===writecard.sh=== |
|||
Diese Variante des Skripts verwendet das onepin-Profil, so dass es für die Karte nur eine einzige PIN gibt, es findet keine Unterscheidung zwischen User-PIN und SO-PIN statt. |
|||
====Code==== |
|||
#!/bin/sh |
#!/bin/sh |
||
if [ "x |
if [ "x$1" == "x" ] || [ "x"$2 == "x" ]; then |
||
echo "usage: ./writecard.sh <username> <pin>" |
echo "usage: ./writecard.sh <username> <pin>" |
||
echo |
echo |
||
Line 190: | Line 432: | ||
pkcs15-init -S pkcs12/${1}.pkcs12 -f PKCS12 -a 1 --pin ${2} -T |
pkcs15-init -S pkcs12/${1}.pkcs12 -f PKCS12 -a 1 --pin ${2} -T |
||
fi |
fi |
||
====Erläuterung==== |
|||
pkcs15-init -E -C -p pkcs15+onepin --pin ${2} --puk 4321 -T |
|||
'''-E''' Smartcard löschen<br> |
|||
'''-C''' bewirkt, dass auf der Smartcard eine PKCS#15-Struktur angelegt wird<br> |
|||
'''-p''' angeben eines Profils<br> |
|||
'''-pin''' PIN für die Smartcard<br> |
|||
'''-puk''' PUK für die Smartcard<br> |
|||
'''-T''' verwende Standard Transport Key<br> |
|||
pkcs15-init -S pkcs12/${1}.pkcs12 -f PKCS12 -a 1 --pin ${2} -T |
|||
'''-S''' lädt angegebenen privaten Schlüssel auf die Smartcard<br> |
|||
'''-f''' gibt das Key File Format an<br> |
|||
'''-a''' gibt die ID der zu erzeugenden PIN an<br> |
|||
===so_writecard.sh=== |
|||
Bei dieser Variante des Skripts wird zwischen User-PIN und SO-PIN entschieden. |
|||
====Code==== |
|||
<pre> |
|||
#!/bin/sh |
|||
if [ "x"$1 == "x" ] || [ "x"$2 == "x" ] || [ "x"$3 == "x" ] || [ "x"$4 == "x" ] || [ "x"$5 == "x" ]; then |
|||
echo "usage: ./writecard.sh <username> <so-pin> <so-puk> <pin> <puk>" |
|||
echo |
|||
else |
|||
cd /etc/openssl/ |
|||
pkcs15-init -E -C --so-pin ${2} --so-puk ${3} -T |
|||
pkcs15-init -P -l "User-PIN" -a 1 --pin ${4} --puk ${5} -T --so-pin ${2} |
|||
pkcs15-init -S pkcs12/${1}.pkcs12 -f PKCS12 -a 1 --pin ${4} -T --so-pin ${2} |
|||
fi |
|||
</pre> |
|||
====Erläuterung==== |
|||
pkcs15-init -E -C --so-pin ${2} --so-puk ${3} -T |
|||
'''--so-pin''' SO-PIN, die verwendet werden soll<br> |
|||
'''--so-puk''' SO-PUK, die verwendet werden soll<br> |
|||
pkcs15-init -P -l "User-PIN" -a 1 --pin ${4} --puk ${5} -T --so-pin ${2} |
|||
'''-P''' neue PIN anlegen<br> |
|||
'''-l''' Label für die neue PIN<br> |
|||
'''-a''' ID für die zu erzeugende PIN<br> |
|||
==revokeclient.sh== |
|||
===Code=== |
|||
<pre> |
|||
#!/bin/sh |
|||
echo "Clientzertifikat zurückziehen..." |
|||
openssl ca -revoke /etc/openssl/certs/${1}cert.pem |
|||
echo "Erzeuge Certificate Revocation List..." |
|||
openssl ca -gencrl -out /etc/openssl/crl/crl.pem |
|||
make_hash_link.sh /etc/openssl/crl/ |
|||
</pre> |
|||
===Erläuterung=== |
|||
openssl ca -revoke /etc/openssl/certs/${1}cert.pem |
|||
Zieht ein Zertifikat zurück |
|||
openssl ca -gencrl -out /etc/openssl/crl/crl.pem |
|||
Neuerzeugen der CRL |
|||
make_hash_link.sh /etc/openssl/crl/ |
|||
Hash erzeugen |
|||
==changepin.sh== |
|||
===Code=== |
|||
#!/bin/sh |
|||
pkcs15-tool --change-pin |
|||
===Erläuterung=== |
|||
selbsterklärend |
|||
==makeclientwithkeyfromcard.sh== |
|||
===Code=== |
|||
<pre> |
|||
#!/bin/sh |
|||
# $1 - CN des zu erstellenden Zertifikats |
|||
# $2 (optional) - Emailadresse für das Zertifikat |
|||
set -e |
|||
. sslinit.sh |
|||
if [ "x$1" == "x" ]; then |
|||
echo "Bitte einen Clientparameter angeben." |
|||
else |
|||
MAILSTR="" |
|||
if [ "y$2" != "y" ]; then |
|||
MAILSTR="/emailAddress=${2}" |
|||
fi |
|||
cd $SSLPATH |
|||
echo "1. Initialisierung der Karte..." |
|||
pkcs15-init -E -C -p pkcs15+onepin |
|||
echo "2. Generiere RSA-Schlüssel auf Karte..." |
|||
pkcs15-init -G rsa/1024 -a 1 |
|||
echo "3. Erzeuge die Zertifikatsanforderung"... |
|||
cmd1="engine dynamic -pre SO_PATH:/usr/lib/engines/engine_pkcs11.so -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD -pre MODULE_PATH:/usr/local/lib/opensc-pkcs11.so" |
|||
cmd2="req -engine pkcs11 -new -key id_45 -keyform engine -out 'certs/${1}csr.pem' -text -subj '/C=DE/ST=Berlin/L=Berlin/O=Humboldt-Universitaet zu Berlin/OU=Informatik/OU=ca-test/CN=${1}$MAILSTR'" |
|||
echo -e "$cmd1\n$cmd2\n"|openssl |
|||
echo "4. Erzeuge Client-Cert..." |
|||
openssl x509 -req -in "certs/${1}csr.pem" -out "certs/${1}cert.pem" -CA cacert.pem -CAkey private/cakey.pem -CAserial $SSLPATH/serial |
|||
rm "certs/${1}csr.pem" |
|||
echo "5. Zertifikat auf Karte uebertragen..." |
|||
pkcs15-init --store-certificate "certs/${1}cert.pem" |
|||
echo "Inhalte auf der Karte:" |
|||
pkcs15-tool -D |
|||
fi |
|||
</pre> |
|||
==listcard.sh== |
|||
===Code=== |
|||
<pre> |
|||
#!/bin/sh |
|||
pkcs15-tool --list-pins -c -C -k --list-public-keys |
|||
</pre> |
|||
===Erläuterung=== |
|||
'''--listpins''' listet PINs auf<br> |
|||
'''-c''' liste Zertifikate auf<br> |
|||
'''-C''' liste Datenobjekte<br> |
|||
'''-k''' listet Private Keys<br> |
|||
'''--list-public-keys''' listet Public Keys<br> |
|||
==unblock.sh== |
|||
===Code=== |
|||
<pre> |
|||
#!/bin/sh |
|||
pkcs15-tool -u -a 1 |
|||
</pre> |
|||
===Erläuterung=== |
|||
'''-u''' PIN entsperren<br> |
|||
'''-a''' ID der zu entsperrenden PIN<br> |
|||
==pam== |
==pam== |
||
Line 197: | Line 568: | ||
und Ende folgende Zeile einfügen |
und Ende folgende Zeile einfügen |
||
auth required pam_deny.so |
auth required pam_deny.so |
||
=Glossar= |
|||
; CA : Certification Authority, Zertifizierungsstelle |
|||
; CRL : Certificate Revocation List |
|||
; Cryptoki : Cryptographic Token Interface |
|||
; CSR : Certificate Signing Request |
|||
; ICC : Integrated Circuit Card, z.B. Smartcard |
|||
; IDF : Interface Device, z.B. Smart Card Reader |
|||
; PAM : Pluggable Authentication Module |
|||
; PC/SC : Personal computer/Smart Card |
|||
; PIN : Personal Identification Number |
|||
; PKCS : Public-Key Cryptography Standards |
|||
; PUK : Pin Unlocking Key |
|||
; SO : Security Officer |
|||
=Quellen= |
=Quellen= |
||
Line 204: | Line 589: | ||
[ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-15/pkcs-15v1_1.pdf PKCS #15: Cryptographic Token Information Format Standard]<br> |
[ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-15/pkcs-15v1_1.pdf PKCS #15: Cryptographic Token Information Format Standard]<br> |
||
[http://www.opensc.org/ OpenSC]<br> |
[http://www.opensc.org/ OpenSC]<br> |
||
[http://www.openssl.org/ |
[http://www.openssl.org/ OpenSSL]<br> |
||
[http://www.gemplus.com/techno/pcsc/other/aboutpcsc.html Gemplus (PC/SC)]<br> |
|||
[http://www.pcscworkgroup.com/ PC/SC Workgroup]<br> |
|||
[http://www.amazon.de/exec/obidos/ASIN/3446220364/ Handbuch der Chipkarten von Wolfgang Rankl, Wolfgang Effing]<br> |
|||
[http://www.openca.org/ OpenCA Labs]<br> |
|||
=Vortragsfolien & Skripte= |
|||
=GNU Free Documentation License= |
|||
* https://www.informatik.hu-berlin.de/~cakruege/smartcard.tar.gz (2005) |
|||
http://www.gnu.org/licenses/fdl.html |
|||
* http://www2.informatik.hu-berlin.de/~bechstei/itsec2006_smartcars.pdf (2006) |
Latest revision as of 09:43, 2 October 2006
Einleitung
Es gibt viele Anwendungsfälle, bei denen man sich authentifizieren muss, zum Beispiel gegenüber Webseiten oder Rechnern. Dabei kommen meist Kombinationen aus Nutzername und Passwort zum Einsatz. Dieses Verfahren bietet zahlreiche Angriffspunkte: schwache Passwörter können schnell erraten werden, Nutzer schreiben ihre Passwörter auf Zettel, die an den Monitor geklebt werden usw. Smartcards umgehen viele dieser Probleme, da sie die Authentifizierung per Passwort durch ein zertifikatsbasiertes Anmeldeverfahren ersetzen können. Dadurch braucht man nicht mehr viele verschiedene Passwörter, sondern nur noch eine Karte und eine PIN. Außerdem kann eine Smartcard im Gegensatz zu einem Passwort oder einem Fingerabdruck nicht, oder nur mit sehr großem Aufwand, kopiert werden, so dass ein Verlust des Authentifizierungsmerkmals dem Benutzer sofort auffällt.
Hintergründe
Überblick über den Software-Stack
Was ist PAM?
Ein PAM kapselt die Authentifizierung und stellt Applikationen (z.B. login, ftpd, screensaver) eine einheitliche Schnittstelle bereit, so dass man die Authentifizierungsmethode (z.B. Passwort, Biometrie, Smartcard) flexibel auswechseln kann, ohne dass Applikationen daran angepasst werden müssen.
Für jede Applikation bestimmt eine Konfigurationsdatei in /etc/pam.d/, welche Authentifizierungsmethoden sie akzeptiert. Die Konfigurationsdateien enthalten mindestens 3 Spalten. In der ersten steht der Modultyp (auth, account, password, session), in der zweiten steht die Modulsteuerung (required, requisite, sufficient, optional) und in der dritten der Name des Moduls. Es können weitere Spalten mit Modulparametern folgen.
Was ist OpenSC?
OpenSC ist eine Sammlung von Bibliotheken, die der Kommunikation mit Smartcards dient. Unter anderem werden die Standards PKCS#11 (Cryptoki) und PKCS#15 implementiert.
Was ist PKCS#11?
PKCS#11 ist ein Standard, der eine Programmierschnittstelle für Security Tokens wie z.B. Smartcards definiert.
Aus Sicht von PKCS#11 ist solch ein Token ein Gerät, das Objekte speichert und darauf kryptografische Funktionen ausführen kann. Solche Objekte können Daten, Zertifikate oder Schlüssel sein und Objekte können privat oder öffentlich sein.
2 Arten von Nutzern können mit den Token umgehen, der normale Nutzer und der sogenannte Security Officer (SO). Der normale Benutzer ist der, der die Karte benutzen soll, nur er hat z.B. Zugriff auf private Objekte. Der SO ist für die Initialisierung der Karte zuständig und hat nur Zugriff auf öffentliche Objekte.
Applikationen kommunizieren mit dem Token über Sessions, wobei es sowohl read/write-Sessions als auch read-only-Sessions gibt. Eine Session kann sich als SO oder Nutzer einloggen und je nach Berechtigung Objekte lesen, erzeugen oder manipulieren oder sie kann kryptografische Operationen ausführen. Die Applikation führt den Zugriff auf das Token über Handles (vergleichbar Filehandles) aus, wobei man Session-Handles, die die jeweilige Session identifizieren, und Object-Handles, mit denen man auf Objekte zugreifen kann, unterscheidet. Eine Applikation kann gleichzeitig mehrere Sessions für ein Token offen haben, wobei diese sich immer im gleichen Zustand befinden (z.B. alle public, user oder SO).
Man kann Objekte so markieren, dass man sie nicht mehr von der Karte exportieren kann (z.B. den privaten Schlüssel).
Was ist PKCS#12?
PKCS#12 ist ein Containerformat, mit dem man Zertifikate und Schlüssel in eine Datei bringen kann, um diese dann zum Beispiel auf eine Smartcard oder ein Backupmedium zu kopieren.
Was ist PKCS#15?
PKCS#15 ist ein Standard, der definiert, wie man Zertifikate, Schlüssel und andere Daten auf Smartcards speichert.
Was ist PCSC-Lite?
PCSC-Lite ist eine Implementierung von PC/SC. PC/SC abstrahiert den Card Reader, so dass eine Applikation, die auf einen Card Reader zugreifen will, dessen Details nicht kennen muss.
Was ist ein IFD-Handler?
Der IFD-Handler ist eine Low-Level-Software, die den Zugriff auf die I/O-Channels des Smart Card Readers unterstützt.
Was sind CAs?
Eine CA (Certification Authority) ist eine Stelle, die digitale Zertifikate ausstellt. Ein solches Zertifikat ist eine durch die digitale Signatur der CA beglaubigte Zuordnung von einem öffentlichen Schlüssel zu einer Person oder Organisation.
Dabei bilden verschiedene CAs eine baumartige Hierarchie. Die Root-CA bildet die Wurzel, die ihr Zertifikat als einzige Stelle selbst signiert, da es keine übergeordnete Stelle gibt. Für die CAs auf den Stufen darunter signiert jeweils die nächsthöhere Stelle das CA-Zertifikat. Die Blätter des Baums bilden die Nutzerzertifikate, die ihrerseits keine Zertifikate mehr ausstellen können. Auf diese Weise bilden sich sogenannte Chains of Trust.
Was passiert beim Login?
- pam_modul sucht nach Smartcard
- PIN wird an Karte übergeben (Login auf Karte)
- Private Key wird gesucht
- X509 Zertifikat wird gesucht
- Zertifikat wird verifiziert
- prüfen auf zurückgezogenes Zertifikat
- Mapping von Zertifikat auf User
- auf dem PC wird eine 128 Byte Zufallszahl erzeugt (diese wird gehashed)
- die Karte signiert den Hash
- Die Signatur wird durch den PC verifiziert
- Logout auf Karte
- User auf PC erfolgreich eingeloggt
Was wird gebraucht?
Hardware
- Cardreader (z.B. Omnikey Cardman 2020 USB, http://www.omnikey.com/)
- Smartcard (z.B. Schlumberger Cryptoflex 32k e-gate, http://www.axalto.com/)
Software
- SuSE 9.3 Professional
http://www.novell.com/products/linuxprofessional/downloads/ftp/germ_mirrors.html - Treiber (Kernelmodul) für den SmartCard Reader
http://www.omnikey.com/ - Support - Downloads - PCSC-Lite 1.2.9 Beta 6 (schon enthalten)
- OpenCT 0.6.2-4 (schon enthalten)
- OpenSC 0.9.6 (das bei SuSE 9.3 enthaltene OpenSC 0.9.4-4 ist kaputt)
http://www.opensc.org/download.php - pam_PKCS11
http://www.opensc.org/pam_pkcs11/- pam-devel (schon enthalten)
- openldap2-devel (schon enthalten)
- openssl 0.9.7e-3 (schon enthalten)
- openssl-devel 0.9.7e-3
- Apt for SuSE (nicht notwendig, aber sehr praktisch)
http://linux01.gwdg.de/apt4rpm/ - stow (nicht notwendig, aber sehr praktisch)
http://www.gnu.org/software/stow/stow.html
Installation
SuSE
- SuSE 9.3 Standard-System mit KDE, C/C++ Compiler (komplett), kernel-sources, Erfahrener Benutzer (komplett)
- Onlineupdate
- Reboot (wg. Kernelupdate)
apt4suse
cd wget http://linux01.gwdg.de/~scorot/install-apt4suse.rpm rpm -Uvh install-apt4suse.rpm install-apt4suse
stow
Da wir keine aktuellen RPMs von OpenSC und pam_PKCS11 für SuSE gefunden haben und es uns auch nicht gelungen ist welche zu erzeugen, benutzten wir im folgenden Stow:
GNU Stow is a program for managing the installation of software packages, keeping them separate (/usr/local/stow/emacs vs. /usr/local/stow/perl, for example) while making them appear to be installed in the same place (/usr/local).[1]
apt-get install stow mkdir /usr/local/stow
omnikey
- Download: http://www.omnikey.com/ - Support - Downloads
- Installation mit Parameter --nopcscd, da die Prüfung, ob PCSC schon enthalten ist, bei beta6 fehlschlägt
cd tar xfz cm2020_installer_v2_4_0_src.tar.gz cd cm2020_installer_v2_4_0_src ./install --nopcscd ln -s /usr/local/pcsc/drivers/ifd-cm2020.bundle/ /usr/lib/readers/ mknod /dev/usb/cm0 c 180 224
opensc
apt-get install openssl-devel pam-devel openldap2-devel cd wget http://www.opensc.org/files/opensc-0.9.6.tar.gz tar xfz opensc-0.9.6.tar.gz cd opensc-0.9.6 ./configure --prefix=/usr/local/stow/opensc-0.9.6 make make install cp etc/opensc.conf /etc/opensc.conf cd /usr/local/stow/ stow opensc-0.9.6 mkdir /usr/local/stow/opensc-0.9.6/etc ln -s --backup /etc/opensc.conf /usr/local/stow/opensc-0.9.6/etc/opensc.conf
Pfad in /etc/opensc.conf wie folgt anpassen:
profile_dir = /usr/local/share/opensc
openssl
mkdir /etc/openssl /etc/openssl/certs /etc/openssl/crl /etc/openssl/private /etc/openssl/pkcs12 chmod 700 /etc/openssl/private/ /etc/openssl/pkcs12/
die Datei /etc/ssl/openssl.cnf anpassen
[ CA_default ] dir = /etc/openssl
[ req ] req_extensions = v3_req [ v3_req ] basicConstraints = critical,CA:FALSE
Anwendungen
pam_PKCS11
cd wget http://www.dit.upm.es/~jantonio/pam-pkcs11/downloads/pkcs11_login-0.5.1.tar.gz tar xfz pkcs11_login-0.5.1.tar.gz cd pkcs11_login-0.5.1 ./configure --prefix=/usr/local/stow/pkcs11_login-0.5.1 make make install mkdir /etc/pkcs11 cp etc/pam_pkcs11.conf.example /etc/pkcs11/pam_pkcs11.conf cd /usr/local/stow/ stow pkcs11_login-0.5.1
pam_pkcs11.conf editieren und alle Pfade anpassen: /usr/ -> /usr/local/
use_first_pass = true; ca_dir = /etc/openssl; crl_dir = /etc/openssl/crl; crl_policy = offline;
Debugging:
wenig Debug (Debugging des PAM-Moduls):
/etc/pkcs11/pam_pkcs11.conf
debug = true
starkes Debug (Debugging mit Hilfe von pkcs11-spy):
/etc/pkcs11/pam_pkcs11.conf
pkcs11_module opensc { #module = /usr/local/lib/pkcs11/opensc-pkcs11.so; module = /usr/local/lib/pkcs11/pkcs11-spy.so; . . .
/etc/opensc.conf
app pkcs11-spy { spy { output = /root/pkcs11-spy.log; module = /usr/lib/pkcs11/opensc-pkcs11.so; } }
optional: pkcs11_eventmgr
automatisches screen locken mit xscreensaver /etc/pam_pkcs11/pkcs11_eventmgr.conf
pkcs11_eventmgr { # Run in background? Implies debug=false if true daemon = true; # show debug messages? debug = false; # polling time in seconds polling_time = 1; # expire time in seconds # default = 0 ( no expire ) expire_time = 0; # pkcs11 module to use pkcs11_module = /usr/local/lib/opensc-pkcs11.so; # # list of events and actions # Card inserted event card_insert { # what to do if an action fail? # ignore : continue to next action # return : end action sequence # quit : end program on_error = ignore ; # You can enter several, comma-separated action entries # they will be executed in turn action = "screensaver-command -deactivate"; } # Card has been removed event card_remove { on_error = ignore; action = "xscreensaver-command -lock"; } # Too much time card removed event expire_time { on_error = ignore; action = "/bin/false"; } }
apache2
makeclient.sh server a2enmod ssl
/etc/apache2/ports.conf
Listen 80 Listen 443
/etc/apache2/sites-enabled/default-ssl
NameVirtualHost *:443 <VirtualHost 127.0.0.1:443> SSLEngine on SSLVerifyClient require SSLVerifyDepth 2 SSLCACertificateFile /etc/openssl/cacert.crt SSLCertificateFile /etc/apache2/ssl/servercacert.pem SSLCertificateKeyFile /etc/apache2/ssl/serverkey.pem SSLOptions +StdEnvVars ServerName localhost DocumentRoot /var/www/ CustomLog /var/log/apache2/ssl.log "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x %{SSL_CLIENT_S_DN}x \"%r\" %b" </VirtualHost>
firefox
lade unter edit/preferences/advanced/security devices das modul /usr/local/lib/opensc-pkcs11.so
openssh
- openssh-quellen patchen ..opensc/src/openssh/ask-for-pin.diff
- configure mit --with-opensc=/usr/local aufrufen
- openssh bauen
- mit pkcs15-tool --read-ssh-key <num> den publickey auslesen und auf dem zielhost installieren
- ./ssh -I 0 <host>
Generierung von Schlüsseln auf einer Smartcard
Einige Smardcards verfügen über einen eigenen Zufallszahlengenerator und sind in der Lage Public-/Privatekeypaare zu erzeugen. Der private Schlüssel muß also nie auf einem anderen Gerät gespeichert werden. Im Folgenden wird ein Zertifikat unter Ausnutzung dieser Fähigkeit erstellt.
verwendete Smartcard: Starcos SPK 2.3
- Initialisieren der Karte:
- pkcs15-init -E -C -p pkcs15+onepin
- Erzeugen eines RSA-Schlüssels auf der Karte:
- pkcs15-init -G rsa/1024 -a 1
- Starten einer openssl-Shell
- Laden der pkcs11 engine in openssl
- OpenSSL> engine dynamic -pre SO_PATH:/usr/lib/engines/engine_pkcs11.so -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD -pre MODULE_PATH:/usr/local/lib/opensc-pkcs11.so
- Erzeugen einer Zertifikatsanforderung für den auf der Karte generierten Schlüssel
- OpenSSL> req -engine pkcs11 -new -key id_45 -keyform engine -out req.pem \
- -text -subj '/C=DE/ST=Berlin/L=Berlin/O=Humboldt-Universitaet zu Berlin/OU=Informatik/OU=ca-test/CN=Max Mustermann'
- Austellen des Zertifikates
- openssl x509 -req -in req.pem -out "cert.pem" -CA /etc/ssl/cacert.pem -CAkey /etc/ssl/private/cakey.pem -CAserial /etc/ssl/serial
- Kopieren des Zertifikates auf die Smartcard
- pkcs15-init -X cert.pem
Weitere Infos unter http://www.opensc-project.org/opensc/wiki/QuickStart
Skripte
Die folgenden Skripte erzeugen eine CA bzw. Clientzertifikate und schreiben letztere auf die Karte. Die privaten Schlüssel und die CSRs könnten auch direkt auf den Karten generiert werden, bei unseren Tests hängte sich aber das komplette System auf. Auf den Rechnern an denen man sich anmelden will muss und sollte nur das cacert vorhanden sein.
makeca.sh
Code
#!/bin/sh echo "Lösche /etc/openssl ..." rm -rf /etc/openssl echo "Erzeuge Verzeichnisse..." mkdir /etc/openssl cd /etc/openssl mkdir certs crl private pkcs12 chmod 700 private/ chmod 700 pkcs12/ echo "Erzeuge CAkey..." openssl genrsa -aes256 -out private/cakey.pem 2048 echo "Erzeuge CAcert..." openssl req -new -x509 -days 3650 -key private/cakey.pem -out cacert.pem -set_serial 1 \ -subj '/C=DE/ST=Berlin/L=Berlin/O=Humboldt-Universitaet zu Berlin/OU=Informatik/OU=ca-test/CN=ca' touch index.txt echo 01 > serial make_hash_link.sh /etc/openssl/ echo "Erzeuge Certificate Revocation List..." openssl ca -gencrl -out /etc/openssl/crl/crl.pem make_hash_link.sh /etc/openssl/crl/
Erläuterung
openssl genrsa -aes256 -out private/cakey.pem 2048
genrsa generiert einen privaten RSA-Schlüssel
-aes256 verschlüsselt den Schlüssel mit AES 256 Bit
-out schreibt den Schlüssel in eine Datei
2048 ist die Größe des Schlüssels in Bit
openssl req -new -x509 -days 3650 -key private/cakey.pem -out cacert.pem -set_serial 1 \ -subj '/C=DE/ST=Berlin/L=Berlin/O=Humboldt-Universitaet zu Berlin/OU=Informatik/OU=ca-test/CN=ca'
req stellt einen Request für ein Zertifikat
-new zeigt an, dass es sich um einen Request für ein neues Zertifikat handelt
-x509 sorgt dafür, dass statt einem Request ein selbstsigniertes Zertifikat erzeugt wird
-days Gültigkeit des Zertifikats in Tagen
-key der Schlüssel, mit dem das Zertifikat signiert wird
-out Datei, in die das Zertifikat geschrieben wird
-set_serial Seriennummer für das Zertifikat
-subj Subject für das Zertifikat
make_hash_link.sh /etc/openssl/
Erzeugt ein Hashfile für pam_pkcs11
openssl ca -gencrl -out /etc/openssl/crl/crl.pem
ca -gencrl generiert eine CRL auf Basis der index.txt
makeclient.sh
Code
#!/bin/sh . sslinit.sh if [ "x$1" == "x" ]; then echo "Bitte einen Clientparameter angeben." else MAILSTR="" if [ "y$2" != "y" ]; then MAILSTR="/emailAddress=${2}" fi cd $SSLPATH echo "Erzeuge Client-Key und CSR..." openssl req -new -newkey rsa:1024 -out "certs/${1}csr.pem" -nodes -keyout "private/${1}key.pem" \ -days 365 -subj \ '/C=DE/ST=Berlin/L=Berlin/O=Humboldt-Universitaet zu Berlin/OU=Informatik/OU=ca-test/CN='"${1}$MAILSTR" echo "Erzeuge Client-Cert..." openssl x509 -req -in "certs/${1}csr.pem" -out "certs/${1}cert.pem" -CA cacert.pem \ -CAkey private/cakey.pem -CAserial $SSLPATH/serial rm "certs/${1}csr.pem" echo "PKCS#12-File erzeugen..." openssl pkcs12 -export -chain -out "pkcs12/${1}.pkcs12" -in "certs/${1}cert.pem" \ -inkey "private/${1}key.pem" -CAfile cacert.pem -passout pass: fi
Erläuterung
openssl req -new -newkey rsa:1024 -out certs/${1}csr.pem -nodes -keyout private/${1}key.pem \ -days 365 -subj \ '/C=DE/ST=Berlin/L=Berlin/O=Humboldt-Universitaet zu Berlin/OU=Informatik/OU=ca-test CN='${1}
-newkey erzeugt einen neuen privaten Schlüssel
-nodes erzeugten Schlüssel nicht symmetrisch verschlüsseln
-keyout Datei, in die der neu erzeugte Schlüssel geschrieben wird
openssl x509 -req -in certs/${1}csr.pem -out certs/${1}cert.pem -CA cacert.pem \ -CAkey private/cakey.pem -CAserial /etc/openssl/serial
x509 erzeugt ein Zertifikat gemäß Standard x509
-req gibt an, dass man einen bestehenden Request angibt, der signiert und ausgegeben werden soll
-in gibt den zu signierenden Request an
-out Datei, in die das erzeugte Zertifikat ausgegeben werden soll
-CA Zertifikat der CA, die das Zertifikat signiert
-CAkey Schlüssel der CA, die das Zertifikat signiert
-CAserial Seriennummerndatei
openssl pkcs12 -export -chain -out pkcs12/${1}.pkcs12 -in certs/${1}cert.pem \ -inkey private/${1}key.pem -CAfile cacert.pem -passout pass:
pkcs12 erstellt eine Datei nach Standard PKCS#12
-export gibt an, dass eine PKCS#12-Datei erzeugt werden soll (und nicht nur geparst)
-chain es wird versucht, die gesamte Zertifikatskette einzubinden
-out Dateiname für die PKCS#12-Datei
-in Zertifikat, dass in den PKCS#12-Container geschrieben werden soll
-inkey privater Schlüssel, der in den PKCS#12-Container geschrieben werden soll
-CAfile CA-Zertifikat, das in den PKCS#12-Container geschrieben werden soll
-passout Passphrase, mit der ausgegebene private Schlüssel verschlüsselt werden
Writecard
writecard.sh
Diese Variante des Skripts verwendet das onepin-Profil, so dass es für die Karte nur eine einzige PIN gibt, es findet keine Unterscheidung zwischen User-PIN und SO-PIN statt.
Code
#!/bin/sh if [ "x$1" == "x" ] || [ "x"$2 == "x" ]; then echo "usage: ./writecard.sh <username> <pin>" echo else cd /etc/openssl echo "Karte loeschen und neu anlegen..." pkcs15-init -E -C -p pkcs15+onepin --pin ${2} --puk 4321 -T echo "Daten auf Karte uebertragen..." pkcs15-init -S pkcs12/${1}.pkcs12 -f PKCS12 -a 1 --pin ${2} -T fi
Erläuterung
pkcs15-init -E -C -p pkcs15+onepin --pin ${2} --puk 4321 -T
-E Smartcard löschen
-C bewirkt, dass auf der Smartcard eine PKCS#15-Struktur angelegt wird
-p angeben eines Profils
-pin PIN für die Smartcard
-puk PUK für die Smartcard
-T verwende Standard Transport Key
pkcs15-init -S pkcs12/${1}.pkcs12 -f PKCS12 -a 1 --pin ${2} -T
-S lädt angegebenen privaten Schlüssel auf die Smartcard
-f gibt das Key File Format an
-a gibt die ID der zu erzeugenden PIN an
so_writecard.sh
Bei dieser Variante des Skripts wird zwischen User-PIN und SO-PIN entschieden.
Code
#!/bin/sh if [ "x"$1 == "x" ] || [ "x"$2 == "x" ] || [ "x"$3 == "x" ] || [ "x"$4 == "x" ] || [ "x"$5 == "x" ]; then echo "usage: ./writecard.sh <username> <so-pin> <so-puk> <pin> <puk>" echo else cd /etc/openssl/ pkcs15-init -E -C --so-pin ${2} --so-puk ${3} -T pkcs15-init -P -l "User-PIN" -a 1 --pin ${4} --puk ${5} -T --so-pin ${2} pkcs15-init -S pkcs12/${1}.pkcs12 -f PKCS12 -a 1 --pin ${4} -T --so-pin ${2} fi
Erläuterung
pkcs15-init -E -C --so-pin ${2} --so-puk ${3} -T
--so-pin SO-PIN, die verwendet werden soll
--so-puk SO-PUK, die verwendet werden soll
pkcs15-init -P -l "User-PIN" -a 1 --pin ${4} --puk ${5} -T --so-pin ${2}
-P neue PIN anlegen
-l Label für die neue PIN
-a ID für die zu erzeugende PIN
revokeclient.sh
Code
#!/bin/sh echo "Clientzertifikat zurückziehen..." openssl ca -revoke /etc/openssl/certs/${1}cert.pem echo "Erzeuge Certificate Revocation List..." openssl ca -gencrl -out /etc/openssl/crl/crl.pem make_hash_link.sh /etc/openssl/crl/
Erläuterung
openssl ca -revoke /etc/openssl/certs/${1}cert.pem
Zieht ein Zertifikat zurück
openssl ca -gencrl -out /etc/openssl/crl/crl.pem
Neuerzeugen der CRL
make_hash_link.sh /etc/openssl/crl/
Hash erzeugen
changepin.sh
Code
#!/bin/sh pkcs15-tool --change-pin
Erläuterung
selbsterklärend
makeclientwithkeyfromcard.sh
Code
#!/bin/sh # $1 - CN des zu erstellenden Zertifikats # $2 (optional) - Emailadresse für das Zertifikat set -e . sslinit.sh if [ "x$1" == "x" ]; then echo "Bitte einen Clientparameter angeben." else MAILSTR="" if [ "y$2" != "y" ]; then MAILSTR="/emailAddress=${2}" fi cd $SSLPATH echo "1. Initialisierung der Karte..." pkcs15-init -E -C -p pkcs15+onepin echo "2. Generiere RSA-Schlüssel auf Karte..." pkcs15-init -G rsa/1024 -a 1 echo "3. Erzeuge die Zertifikatsanforderung"... cmd1="engine dynamic -pre SO_PATH:/usr/lib/engines/engine_pkcs11.so -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD -pre MODULE_PATH:/usr/local/lib/opensc-pkcs11.so" cmd2="req -engine pkcs11 -new -key id_45 -keyform engine -out 'certs/${1}csr.pem' -text -subj '/C=DE/ST=Berlin/L=Berlin/O=Humboldt-Universitaet zu Berlin/OU=Informatik/OU=ca-test/CN=${1}$MAILSTR'" echo -e "$cmd1\n$cmd2\n"|openssl echo "4. Erzeuge Client-Cert..." openssl x509 -req -in "certs/${1}csr.pem" -out "certs/${1}cert.pem" -CA cacert.pem -CAkey private/cakey.pem -CAserial $SSLPATH/serial rm "certs/${1}csr.pem" echo "5. Zertifikat auf Karte uebertragen..." pkcs15-init --store-certificate "certs/${1}cert.pem" echo "Inhalte auf der Karte:" pkcs15-tool -D fi
listcard.sh
Code
#!/bin/sh pkcs15-tool --list-pins -c -C -k --list-public-keys
Erläuterung
--listpins listet PINs auf
-c liste Zertifikate auf
-C liste Datenobjekte
-k listet Private Keys
--list-public-keys listet Public Keys
unblock.sh
Code
#!/bin/sh pkcs15-tool -u -a 1
Erläuterung
-u PIN entsperren
-a ID der zu entsperrenden PIN
pam
/etc/pam.d/login und /etc/pam.d/xdm editieren am Anfang folgende 2 Zeilen einfügen
auth sufficient pam_unix2.so auth sufficient pam_pkcs11.so
und Ende folgende Zeile einfügen
auth required pam_deny.so
Glossar
- CA
- Certification Authority, Zertifizierungsstelle
- CRL
- Certificate Revocation List
- Cryptoki
- Cryptographic Token Interface
- CSR
- Certificate Signing Request
- ICC
- Integrated Circuit Card, z.B. Smartcard
- IDF
- Interface Device, z.B. Smart Card Reader
- PAM
- Pluggable Authentication Module
- PC/SC
- Personal computer/Smart Card
- PIN
- Personal Identification Number
- PKCS
- Public-Key Cryptography Standards
- PUK
- Pin Unlocking Key
- SO
- Security Officer
Quellen
RSA-Labs - PKCS
PKCS #11: Cryptographic Token Interface Standard
PKCS #12: Personal Information Exchange Syntax Standard
PKCS #15: Cryptographic Token Information Format Standard
OpenSC
OpenSSL
Gemplus (PC/SC)
PC/SC Workgroup
Handbuch der Chipkarten von Wolfgang Rankl, Wolfgang Effing
OpenCA Labs