Nitrokey Start in der Praxis unter ArchLinux
In diesem Kapitel befassen wir uns eingehend mit dem Nitrokey Start (Daten-/Infoblatt) unter Arch Linux. Weitere Informationen zu den Nitrokey-Sticks findet man auch hier bzw. im Support Forum.
Der sichere Schlüssel zu Ihrem digitalen Leben.
Verschlüsselt Ihre E-Mails, Dateien und Server/SSH-Zugriffe. Schützt gegen Hacker und Spionage – privat und beruflich.
Dabei wird der kryptografische Schlüssel sicher im Nitrokey gespeichert und ist gegen Verlust, Diebstahl und Computerviren geschützt. Mit starker Hardware-Verschlüsselung, vertrauenswürdig dank Open Source, Qualität made in Germany.
Anwendungsfälle sind z.B. für jeden als Schutz gegen Massenüberwachung und Hacker, für Unternehmen, Kanzleien und Selbstständige, sowie für IT-Administratoren und Sicherheitsexperten, die jeweils kritische Infrastruktur schützen, wollen und müssen.
Die Firmware und der Software SourceCode der Nitrokey-Familie in Github hinterlegt, einsehbar und somit überprüfbar.
Quelle: https://shop.nitrokey.com/de_DE/shop/product/nk3cn-nitrokey-3c-nfc-148
Mit Hilfe von asymmetrischen Schlüsselmaterials (PGP und S/MIME) können eMails sowie Dateien und ganze Festplatten verschlüsselt und natürlich auch wieder entschlüsselt werden. Hierzu verwenden wir den Nitrokey Start welcher hier für einen überschaubaren Betrag von gerade mal 29€ erstanden werden kann. In dem folgenden Beitrag gehen wir auf die Verwendung unter Arch Linux ein.
Informationen von Hard- und Software
Hardwareinformationen
Informationen über den Stick können wir z.B. mit Hilfe des Befehls usb-devices
aus dem ArchLinux-Paket usbutils dem System abverlangen.
# usb-devices
T: Bus=02 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 20 Spd=12 MxCh= 0
D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
P: Vendor=20a0 ProdID=4211 Rev=02.00
S: Manufacturer=Nitrokey
S: Product=Nitrokey Start
S: SerialNumber=FSIJ-1.2.19-43243711
C: #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=100mA
I: If#= 0 Alt= 0 #EPs= 3 Cls=0b(scard) Sub=00 Prot=00 Driver=usbfs
E: Ad=01(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
E: Ad=81(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
E: Ad=82(I) Atr=03(Int.) MxPS= 4 Ivl=255ms
Mit dem Befehl lshw
aus dem gleichnamigen ArchLinux-Paket lshw können wir uns ebenso anzeigen lassen, ob der Stick angesteckt und erkannt wird. Da der USB-Stick unter die Klasse generic
fällt suchen wir gezielt nach diesen Geräte-Typus.
# lshw -short -C generic
H/W path Device Class Description
===================================================
/0/100/14/0/2 generic Nitrokey Start
/0/100/14/0/6 generic VFS 5011 fingerprint sensor
/0/100/1f/3 generic PnP device LEN0071
/0/100/1f/4 generic PnP device LEN200e
/0/100/1f/5 generic PnP device SMO1200
/0/100/1f.6 generic Wildcat Point-LP Thermal Management Controller
Mit Hilfe des Befehls lsusb
aus dem Arch-Linux-Paket usbutils können wir auch die Produkt- und Hersteller-Identifikationsnummer des Nitrokey-Sticks ermitteln.
# lsusb | grep Nitrokey Bus 002 Device 020: ID 20a0:4211 Clay Logic Nitrokey Start
Im Journal wird uns beim Anstecken des Sticks dies entsprechend protokolliert:
# journalctl -f
May 30 11:19:59 pml010081 kernel: usb 2-2: new full-speed USB device number 21 using xhci_hcd
May 30 11:19:59 pml010081 kernel: usb 2-2: New USB device found, idVendor=20a0, idProduct=4211, bcdDevice= 2.00
May 30 11:19:59 pml010081 kernel: usb 2-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
May 30 11:19:59 pml010081 kernel: usb 2-2: Product: Nitrokey Start
May 30 11:19:59 pml010081 kernel: usb 2-2: Manufacturer: Nitrokey
May 30 11:19:59 pml010081 kernel: usb 2-2: SerialNumber: FSIJ-1.2.19-43243711
May 30 11:19:59 pml010081 mtp-probe[27179]: checking bus 2, device 21: "/sys/devices/pci0000:00/0000:00:14.0/usb2/2-2"
May 30 11:19:59 pml010081 mtp-probe[27179]: bus: 2, device: 21 was not an MTP device
May 30 11:19:59 pml010081 systemd[977]: Reached target Smart Card.
May 30 11:19:59 pml010081 systemd[1]: Reached target Smart Card.
May 30 11:19:59 pml010081 mtp-probe[27181]: checking bus 2, device 21: "/sys/devices/pci0000:00/0000:00:14.0/usb2/2-2"
May 30 11:19:59 pml010081 mtp-probe[27181]: bus: 2, device: 21 was not an MTP device
udev-Regeln
Für den Betrieb unter Arch Linux müssen wir uns noch passende udev-Definitionen hier besorgen.
Ein manuelles Holen und Installieren ist unter Arch Linux nicht notwendig, die Installation des Paketes libnitrokey reicht hier aus!
# pacman -Sy libnitrokey
Bei Bedarf können wir uns hier geziel informieren woher das Paket kommt und was es beinhaltet.
# pacman -Qil libnitrokey
Paketinhalt und -info des Pakets libnitrokey
Die erforderliche udev-Regel findet sich also in der Datei /usr/lib/udev/rules.d/41-nitrokey.rules
*.
erster Test
Sobald wir nun unseren Nitrokey Start in einen USB-Port unseres Adminrechners stecken, können wir den Status der Karte z.B. mit der Option –card-status
beim Befehl gpg2
abfragen.
$ gpg2 --card-status
Reader ...........: Nitrokey Nitrokey Start (FSIJ-1.2.10-14081967) 00 00 Application ID ...: D276000124010200FFFE140819670000 Version ..........: 2.0 Manufacturer .....: unmanaged S/N range Serial number ....: 43243711 Name of cardholder: [not set] Language prefs ...: [not set] Sex ..............: unspecified URL of public key : [not set] Login data .......: [not set] Signature PIN ....: forced Key attributes ...: rsa2048 rsa2048 rsa2048 Max. PIN lengths .: 127 127 127 PIN retry counter : 3 3 3 Signature counter : 0 Signature key ....: [none] Encryption key....: [none] Authentication key: [none] General key info..: [none]
Anwendungsfälle - Software
Nitrokey Start und GnuPG
Da es sich bei der Chipkarte des Nitrokey Start um eine standardkompatible OpenPGP-Karte handelt, kann der Kryptostick mit Hilfe von GnuPG verwaltet werden.
Alle Sicherheitsfunktionen wie z.B. das Erzeugen/Speichern von PGP-Schlüsseln, das Verschlüsseln/Entschlüsseln einer Datei, das Signieren einer Nachricht, die auf der Hardware ausgeführt werden, können mit Hilfe des Befehls gpg bzw. gpg2 gesteuert werden.
card-status
Mit der Option card-status können wir uns mit dem Befehl gpg --card-status
den Kartenstatus ausgeben lassen.
$ gpg2 --card-status
Reader ...........: Nitrokey Nitrokey Start (FSIJ-1.2.10-43243711) 00 00 Application ID ...: D276000124010200FFFE140819670000 Version ..........: 2.0 Manufacturer .....: unmanaged S/N range Serial number ....: 14081967 Name of cardholder: [not set] Language prefs ...: [not set] Sex ..............: unspecified URL of public key : [not set] Login data .......: [not set] Signature PIN ....: forced Key attributes ...: rsa2048 rsa2048 rsa2048 Max. PIN lengths .: 127 127 127 PIN retry counter : 3 3 3 Signature counter : 0 Signature key ....: [none] Encryption key....: [none] Authentication key: [none] General key info..: [none]
Die einzelnen Datenfelder haben hierbei folgende Bedeutung:
Datenfeld | Beschreibung |
---|---|
Application ID | Individuelle (unique) KartenID, diese beinhaltet: ° den Kartentyp ° die Version der Spezifikation ° den Hersteller und ° die Seriennummer des Cryptosticks Diese Application ID ist einmalig und bei jeder Karte anders. |
Version | verwendete OpenPGP Version |
Manufacturer | Hersteller der Karte |
Serial number | Seriennummer der Karte, die vom Hersteller vergeben wurde. |
Name of cardholder | Vorname und Nachname des Karteninhabers ( Es sind hier derzeit nur reines ASCII erlaubt, also keine deutschen Umlaute). Dieses Feld wird von GPG nicht verwendet. |
Language prefs | Gewählte/bevorzugte Sprache (Muttersprache) des Karteninhabers. Dieses Feld wird von GPG nicht verwendet. |
Sex | Geschlecht des Karteninhabers.: (Männlich (M), Weiblich (F) oder Leerzeichen) |
URL of public key | Angabe einer URL, mit der der public-key mit Hilfe des Befehls fetch unter gpg --edit-card auf die Karte geladen werden kann. |
Login data | Bei diesem Feld kann der Account-Name des Karteninhabers abgelegt werden, der bei Anmeldeversuchen genutzt werden kann. GPG führt hier keinerlei Abgleiche zwischen diesem Namen und dem Namen der in einem Schlüssel angegeben und verwendet wird durch! |
Signature PIN | Hier kann über die beiden Schalter zwingend und nicht zwingend eingestellt werden, ob bei jedem Signatur-Vorgang die PIN abgefragt werden soll, oder nicht. Bei der Option nicht zwingend kann GPG die PIN zwischenspeichern, solange der Nitrokey-Stick angesteckt bleibt. |
Key attributes | Angaben über Art und Umfang der hinterlegten Schlüssel |
Max. PIN lengths | Maximale Länge der einzelnen PINs, kann nicht verändert werden! |
PIN retry counter | Zähler für die verbleibenden Versuche zur Eingabe der richtigen PIN. Der max. Zählwert von 3 wird bei jeder Falscheingabe um eins herunter gesetzt. Sobald die richtige Admin-PIN eingegeben wurde, wir der max. Wert von 3 wieder zurück gesetzt. Die beiden ersten Werte (von links gesehen) werden für die User-PIN verwendet. GPG stellt hierbei sicher, dass beide werde synchronisiert werden. Der zweite (mittlere) Wert wird lediglich für Besonderheiten aus dem ISO-Standard 7816 (https://de.wikipedia.org/wiki/ISO_7816) verwendet. Der dritte (rechte) Wert wird als Fehlversuchszähler für die Admin_PIN verwendet. |
Signature counter | Zähler der generierten Signaturen bzw. Signaturvorgänge mit der Karte. Der Zähler kann nicht manipuliert werden und wird lediglich zurückgesetzt, sobald ein neuer Signatur-Schlüssel erzeugt oder auf die Karte geladen wird. |
Signature key | Signatur-Schlüssel (primärer OpenPGP-Schlüssel) |
created | Datum und Uhrzeit an dem der Schlüssel erzeugt wurde |
Encryption key | Entschlüsselungs-Schlüssel (Unterschlüssel des primären (Signatur-)Schlüssels. |
created | Datum und Uhrzeit an dem der Schlüssel erzeugt wurde |
Authentication key | Authentifizierung-Schlüssel (Unterschlüssel des primären (Signatur-)Schlüssels. |
created | Datum und Uhrzeit an dem der Schlüssel erzeugt wurde |
General key info | Diese primäre User ID wird angezeigt, sobald ein entsprechender öffentlicher Schlüssel (public-key) verfügbar ist. |
card-edit
Mit Hilfe des Befehls gpg --card-edit
haben wir entsprechend umfangreiche Zugriffs-, Erstellungs- und Änderungsoptionen auf die Daten und das Schlüsselmaterial, welches auf der Smartcard gespeichert wurden und werden. Viele hilfreiche Informationen zum Umgang mit den Befehlen die uns das Programm gpg bietet, findet man in der zugehörigen Dokumentation auf der Projektseite von https://www.gnupg.org/.
$ gpg --card-edit
Reader ...........: Nitrokey Nitrokey Start (FSIJ-1.2.10-14081967) 00 00 Application ID ...: D276000124010200FFFE140819670000 Version ..........: 2.0 Manufacturer .....: unmanaged S/N range Serial number ....: 14081967 Name of cardholder: [not set] Language prefs ...: [not set] Sex ..............: unspecified URL of public key : [not set] Login data .......: [not set] Signature PIN ....: forced Key attributes ...: rsa2048 rsa2048 rsa2048 Max. PIN lengths .: 127 127 127 PIN retry counter : 3 3 3 Signature counter : 0 Signature key ....: [none] Encryption key....: [none] Authentication key: [none] General key info..: [none] gpg/card>
User-Befehle
Mit Hilfe des Befehls help können wir uns anzeigen lassen, welche Optionen im jeweiligen Modus Benutzer oder Admin zur Verfügung stehen.
gpg/card> help
quit quit this menu
admin show admin commands
help show this help
list list all available data
fetch fetch the key specified in the card URL
passwd menu to change or unblock the PIN
verify verify the PIN and list all data
unblock unblock the PIN using a Reset Code
Admin-Befehle
Mit dem Befehl admin können wir in den Admin-Modus/-Bereich wechseln und auch dort alle Befehle mit Hilfe von help anzeigen lassen.
gpg/card> admin
Admin commands are allowed
gpg/card> help
quit quit this menu
admin show admin commands
help show this help
list list all available data
name change card holder's name
url change URL to retrieve key
fetch fetch the key specified in the card URL
login change the login name
lang change the language preferences
sex change card holder's sex
cafpr change a CA fingerprint
forcesig toggle the signature force PIN flag
generate generate new keys
passwd menu to change or unblock the PIN
verify verify the PIN and list all data
unblock unblock the PIN using a Reset Code
factory-reset destroy all keys and data
RSA-Schlüssel generieren
Wir wollen uns nun einen neuen PGP-Schlüssel in der SmartCard erzeugen und rufen hierzu den Befehl generate auf. Der Nitrokey Start unterstützt RSA-Schlüssellängen von 1024 und maximal von 2048!
Mit Hinblick auf die möglichen Unsicherheiten im Bezug auf die RSA-Schlüssellänge werden wir uns später noch eingehend mit der Erstellung eines ED25519 beschäftigen!
Erst einmal befassen wir uns mit der Erzeugung eines RSA-Schlüsselpaaares. Wir werden dabei nun menügeführt durch eine Reihe von Standardfragen geführt, welche alle relevante Daten abfragen, die zur Generierung des Hauptschlüssels wie auch der Unterschlüssel die für die Aufgaben Signatur, Verschlüsselung und Authentifizierung benötigt werden. Hilfreiche Informationen zur Schlüsselerzeugung auf dem Kryptostick findet man in der offiziellen Doku auf der Nitrokey Webseite.
$ gpg --card-edit
gpg/card> admin
Admin commands are allowed
gpg/card> generate
Admin commands are allowed gpg/card> generate Make off-card backup of encryption key? (Y/n) n Please note that the factory settings of the PINs are PIN = '123456' Admin PIN = '12345678' You should change them using the command --change-pin Please specify how long the key should be valid. 0 = key does not expire <n> = key expires in n days <n>w = key expires in n weeks <n>m = key expires in n months <n>y = key expires in n years Key is valid for? (0) Key does not expire at all Is this correct? (y/N) y GnuPG needs to construct a user ID to identify your key. Real name: Django aka [BOfH] Email address: secmail@nausch.org Comment: Bastard Operator from Hell You selected this USER-ID: "Django aka [BOfH] (Bastard Operator from Hell) <secmail@nausch.org>" Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
Nun wird auf der Karte der gewählte Schlüssel erzeugt.
Die Erzeugung eines Schlüssels mit einer Länge von 2048 dauert ca. 5 Minuten, also keinesfalls den Nitrokey Start abziehen oder die Generierung abbrechen! Während der Erzeugung der Schlüssel leuchtet die rote LED im Stick.
gpg: key 2E22436430385B49 marked as ultimately trusted gpg: revocation certificate stored as '/home/django/.gnupg/openpgp-revocs.d/E65B2BDF79A2E2E4C28F6E062E22436430385B49.rev' public and secret key created and signed. gpg/card> quit pub rsa2048 2020-08-04 [SC] E65B2BDF79A2E2E4C28F6E062E22436430385B49 uid Django aka [BOfH] (Bastard Operator from Hell) <secmail@nausch.org> sub rsa2048 2020-08-04 [A] sub rsa2048 2020-08-04 [E]
ED25519-Schlüssel generieren
In dem Artikel Nitrokey Start unterstützt elliptische Kurven (ECC) wird sehr ausführlich das Zusammenspiel des Nitrokey Start und ECC beschrieben.
Damit auf einem Nitrokey Start Schlüssel auf Basis elliptischer Kurven generiert werden können, muss dieser mindestens die Firmware Version 1.2 verfügen. Dies kontrolliert man am einfachsten mi Folgendem Befehl.
$ gpg2 --card-status | grep Reader
Reader ...........: 20A0:4211:FSIJ-1.2.19-43243711:0
Ferner muss auf dem Rechner, an dem der Stick angesteckt und administriert werden soll, GnuPG in Version 2.1.16 oder höher installiert sein. Bei Arch Linux ist dies kein Problem da aktuell1) die Version 2.4.5 bereitgestellt wird. Bei Bedarf können wir die Version z.B. wie folgt abfragen.
$ gpg2 --version | grep gpg
gpg (GnuPG) 2.4.5
Nun werden wir uns Schlüsselpaar auf Basis elliptischer Kurven auf dem Nitrokey Start generieren. Bevor wir die eigentlichen ED25519-Schlüssel generieren können, müssen wir unseren Stick erst einmal von den vorbelegten RSA-Schlüssel auf ECC-Schlüssel umstellen.
Welcher Typ eingestellt ist können wir mit den Befehl gpg2 –card-status
erfragen; die definierten Werte finden wir dann beim Punkt Key attributes.
$ gpg2 --card-status | grep Key\ attributes
Key attributes ...: rsa2048 rsa2048 rsa2048
Zum Ändern der Vorgabewerte benutzen wir die Option --card-edit
beim Befehl gpg2
.
$ gpg2 --card-edit
Reader ...........: Nitrokey Nitrokey Start (FSIJ-1.2.10-14081967) 00 00 Application ID ...: D276000124010200FFFE140819670000 Version ..........: 2.0 Manufacturer .....: unmanaged S/N range Serial number ....: 14081967 Name of cardholder: [not set] Language prefs ...: [not set] Sex ..............: unspecified URL of public key : [not set] Login data .......: [not set] Signature PIN ....: forced Key attributes ...: rsa2048 rsa2048 rsa2048 Max. PIN lengths .: 127 127 127 PIN retry counter : 3 3 3 Signature counter : 0 Signature key ....: [none] Encryption key....: [none] Authentication key: [none] General key info..: [none] gpg/card>
Im Admin-Bereich finden wir den Befehl key-attr
mit Hilfe dessen wir die Definition des Schlüsseltyps definieren können. Wir wechseln also erst einmal in den Admin Bereich.
gpg/card> admin
Admin commands are allowed
Hier rufen wir dann den Befehl key-attr
auf.
gpg/card> key-attr
Im folgenden ändern wir dann für die drei (Unterschlüssel) die Schlüsselart von ECC und bei der Frage nach der elliptischer Kurve wählen wir dann die Option Curve 25519.
Changing card key attribute for: Signature key Please select what kind of key you want: (1) RSA (2) ECC Your selection? 2 Please select which elliptic curve you want: (1) Curve 25519 (4) NIST P-384 Your selection? 1 The card will now be re-configured to generate a key of type: ed25519 Note: There is no guarantee that the card supports the requested size. If the key generation does not succeed, please check the documentation of your card to see what sizes are allowed. Changing card key attribute for: Encryption key Please select what kind of key you want: (1) RSA (2) ECC Your selection? 2 Please select which elliptic curve you want: (1) Curve 25519 (4) NIST P-384 Your selection? 1 The card will now be re-configured to generate a key of type: cv25519 Changing card key attribute for: Authentication key Please select what kind of key you want: (1) RSA (2) ECC Your selection? 2 Please select which elliptic curve you want: (1) Curve 25519 (4) NIST P-384 Your selection? 1 The card will now be re-configured to generate a key of type: ed25519 gpg/card>
Zum Schluss verlassen wir das Programm gpg2 mit quit
.
gpg/card> quit
Fragen wir nun erneut mit den Befehl gpg2 --card-status
welcher Schlüssel-Typ eingestellt ist, finden wir unsere geänderten Werte.
$ gpg2 --card-status | grep Key\ attributes
Key attributes ...: ed25519 cv25519 ed25519
Nun erstellen wir uns unsere gewünschten Schlüssel auf der SmartCard der Nitrokey Start. Wie schon beim Gernerieren der RSA-Schlüssel werden wir dabei menügeführt durch eine Reihe von Standardfragen gelost, welche alle relevante Daten abfragen, die zur Generierung des Hauptschlüssels wie auch der Unterschlüssel die für die Aufgaben Signatur, Verschlüsselung und Authentifizierung benötigt werden.
$ gpg2 --card-edit
Reader ...........: Nitrokey Nitrokey Start (FSIJ-1.2.10-14081967) 00 00 Application ID ...: D276000124010200FFFE140819670000 Version ..........: 2.0 Manufacturer .....: unmanaged S/N range Serial number ....: 14081967 Name of cardholder: [not set] Language prefs ...: [not set] Sex ..............: unspecified URL of public key : [not set] Login data .......: [not set] Signature PIN ....: forced Key attributes ...: ed25519 cv25519 ed25519 Max. PIN lengths .: 127 127 127 PIN retry counter : 3 3 3 Signature counter : 0 Signature key ....: [none] Encryption key....: [none] Authentication key: [none] General key info..: [none] gpg/card>
Die Schlüsselgenerierung erfolgt im Admin-Menü, in welches wir nun erst einmal wechseln werden.
gpg/card> admin
Admin commands are allowed
Die Erzeugung der Schlüssel erfolgt wie immer mit dem Befehk generate
.
gpg/card> generate
Make off-card backup of encryption key? (Y/n) n
Please note that the factory settings of the PINs are
PIN = '123456' Admin PIN = '12345678'
You should change them using the command --change-pin
Please specify how long the key should be valid.
0 = key does not expire
<n> = key expires in n days
<n>w = key expires in n weeks
<n>m = key expires in n months
<n>y = key expires in n years
Key is valid for? (0) 0
Key does not expire at all
Is this correct? (y/N) y
GnuPG needs to construct a user ID to identify your key.
Real name: Django aka [BOfH]
Email address: secmail@nausch.org
Comment: Bastard Operator from Hell
You selected this USER-ID:
"Django (Bastard Operator from Hell [BOfH]) <django@nausch.org>"
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
gpg: key 9308FC78386863AC marked as ultimately trusted
gpg: revocation certificate stored as '/home/django/.gnupg/openpgp-revocs.d/3E61A50347B523824132EC069308FC78386863AC.rev'
public and secret key created and signed.
Fragen wir nun den Inhalt der SmartCard mit dem Befehl verify
ab, finden wir unsere gerade erstellten Schlüssel.
gpg/card> verify
Reader ...........: Nitrokey Nitrokey Start (FSIJ-1.2.10-14081967) 00 00 Application ID ...: D276000124010200FFFE140819670000 Version ..........: 2.0 Manufacturer .....: unmanaged S/N range Serial number ....: 14081967 Name of cardholder: [not set] Language prefs ...: [not set] Sex ..............: unspecified URL of public key : [not set] Login data .......: [not set] Signature PIN ....: forced Key attributes ...: ed25519 cv25519 ed25519 Max. PIN lengths .: 127 127 127 PIN retry counter : 3 3 3 Signature counter : 4 Signature key ....: 2C08 2445 CDFB 72DE CD65 0350 610E D9AE E553 353F created ....: 2024-01-03 21:17:32 Encryption key....: 9533 C548 589F F00B 8FFF C93B B5E5 4345 BDA2 92A0 created ....: 2024-01-03 21:17:32 Authentication key: D5AF 3627 1220 7A2A 54BD 6C47 C72E 74B8 1A5C 4549 created ....: 2024-01-03 21:17:32 General key info..: pub ed25519/610ED9AEE553353F 2024-01-03 Django (Bastard Operator from Hell [BOfH]) <django@nausch.org> sec> ed25519/610ED9AEE553353F created: 2024-01-03 expires: never card-no: FFFE 43243711 ssb> ed25519/C72E74B81A5C4549 created: 2024-01-03 expires: never card-no: FFFE 43243711 ssb> cv25519/B5E54345BDA292A0 created: 2024-01-03 expires: never card-no: FFFE 43243711
Wir verlassen nun das Programm gpg2
wieder und werden anschließend den Stick personalisieren.
gpg/card> quit
pub ed25519 2024-01-03 [SC] 2C082445CDFB72DECD650350610ED9AEE553353F uid Django aka [BOfH] (Bastard Operator from Hell) <django@nausch.org> sub ed25519 2024-01-03 [A] sub cv25519 2024-01-03 [E]
privaten Schlüsselbund
Fragen wir nun den privaten Schlüsselbund ab, finden wir den gerade angelegten Schlüssel bzw. den zugehörigen Proxy-Eintrag mit dem Verweis auf den Kryptostick. Dazu verwenden wir den Befehl gpg2 --list-secret-key
bzw. die Kurzform dieses Befehls gpg2 -K
.
$ gpg2 -K
sec> ed25519 2024-01-03 [SC] 2C082445CDFB72DECD650350610ED9AEE553353F Card serial no. = FFFE 43243711 uid [ultimate] Django (Bastard Operator from Hell [BOfH]) <django@nausch.org> ssb> ed25519 2024-01-03 [A] ssb> cv25519 2024-01-03 [E]
Öffentlichen Schlüssel ausgeben
Damit wir später unseren öffentlichen Schlüssel auch weitergeben oder zu einem Keyserver hoch laden, exportieren wir diesen in eine Datei.
$ gpg --export --armor django@nausch.org > ~/.gnupg/secmail@nausch.org.pubkey
Diese Datei enthält unseren Schlüssel in ASCII-lesbarer Form.
$ cat ~/.gnupg/secmail@nausch.org.pubkey
- secmail@nausch.org.pubkey
-----BEGIN PGP PUBLIC KEY BLOCK----- mDMEZZXO7BYJKwYBBAHaRw8BAQdA++J6Astvcm2DsHDnzXGHKujQiokCxG+F3qPy 1rPSUGy0PkRqYW5nbyAoQmFzdGFyZCBPcGVyYXRvciBmcm9tIEhlbGwgW0JPZkhd KSA8ZGphbmdvQG5hdXNjaC5vcmc+iJAEExYIADgWIQQsCCRFzfty3s1lA1BhDtmu 5VM1PwUCZZXO7AIbAwULCQgHAgYVCgkICwIEFgIDAQIeAQIXgAAKCRBhDtmu5VM1 P8eRAQCLsRNtgCWBVpvYkL/QgeYJ6rMVUBzwAPgM0W3zCzn+7QD/RK8ZJOCjLlc7 x/yBQ4e/+CO5ThvQsyvDGqXZs/KzmAG4MwRllc7sFgkrBgEEAdpHDwEBB0BzA+Dk r2200QLPPAuY0HlF+xzkdE2HfhCEC3CphggZZYh4BBgWCAAgFiEELAgkRc37ct7N ZQNQYQ7ZruVTNT8FAmWVzuwCGyAACgkQYQ7ZruVTNT+fBwD9FPXANGpY7ey0XvpR R2Xup+Kg4kAk/III/Q/I94BM6fcA/jyIau4jT+fjKjppijUNw54NG6MqIoBOGD+E savaGKcAuDgEZZXO7BIKKwYBBAGXVQEFAQEHQOYn/he3AiViwS3T9iNsiNm/5seO nFpfN/WyjY2kdqkaAwEIB4h4BBgWCAAgFiEELAgkRc37ct7NZQNQYQ7ZruVTNT8F AmWVzuwCGwwACgkQYQ7ZruVTNT8oqQEAniidTk7WOah+nIA6fbT+UIdeDsAUXn82 4QfpcWmZkHUA/1Wmr0wuGE9HbF/AP22rqDfM3RwP3mz1KkIO2A3YSyIF =c/Sd -----END PGP PUBLIC KEY BLOCK-----
card-edit - Stick personalisieren
Zunächst wollen wir unseren Stick personalisieren, also mit den Benutzerspezifischen Daten versorgen:
Name of cardholder | Vorname und Nachname des Karteninhabers (Es sind hier derzeit nur reines ASCII erlaubt, also keine deutschen Umlaute). Dieses Feld wird von GPG nicht verwendet. |
Language prefs | Gewählte/bevorzugte Sprache (Muttersprache) des Karteninhabers. Dieses Feld wird von GPG nicht verwendet. |
Sex | Geschlecht des Karteninhabers.: (Männlich (M), Weiblich (F) oder Leerzeichen) |
URL of public key | Angabe einer URL, mit der der public-key mit Hilfe des Befehls fetch unter gpg --edit-card auf die Karte geladen werden kann. |
Login data | Bei diesem Feld kann der Account-Name des Karteninhabers abgelegt werden, der bei Anmeldeversuchen genutzt werden kann. GPG führt hier keinerlei Abgleiche zwischen diesem Namen und dem Namen der in einem Schlüssel angegeben und verwendet wird durch! |
Zum Ändern dieser Daten müssen wir nach der Anmeldung an der Karte mit dem Befehl adminin den Admin Bereich wechseln.
$ gpg --card-edit
Reader ...........: 20A0:4211:FSIJ-1.2.19-43243711:0 Application ID ...: D276000124010200FFFE432437110000 Application type .: OpenPGP Version ..........: 2.0 Manufacturer .....: unmanaged S/N range Serial number ....: 43243711 Name of cardholder: Language prefs ...: Salutation .......: URL of public key : [not set] Login data .......: [not set] Signature PIN ....: forced Key attributes ...: ed25519 cv25519 ed25519 Max. PIN lengths .: 127 127 127 PIN retry counter : 3 3 2 Signature counter : 9 KDF setting ......: off UIF setting ......: Sign=off Decrypt=off Auth=off Signature key ....: 2C08 2445 CDFB 72DE CD65 0350 610E D9AE E553 353F created ....: 2024-01-03 21:17:32 Encryption key....: 9533 C548 589F F00B 8FFF C93B B5E5 4345 BDA2 92A0 created ....: 2024-01-03 21:17:32 Authentication key: D5AF 3627 1220 7A2A 54BD 6C47 C72E 74B8 1A5C 4549 created ....: 2024-01-03 21:17:32 General key info..: pub ed25519/610ED9AEE553353F 2024-01-03 Django (Bastard Operator from Hell [BOfH]) <django@nausch.org> sec> ed25519/610ED9AEE553353F created: 2024-01-03 expires: never card-no: FFFE 43243711 ssb> ed25519/C72E74B81A5C4549 created: 2024-01-03 expires: never card-no: FFFE 43243711 ssb> cv25519/B5E54345BDA292A0 created: 2024-01-03 expires: never card-no: FFFE 43243711
gpg/card> admin
Admin commands are allowed
Wir ändern zunächst den Namen des Karteninhabers Name of cardholder:
gpg/card> name
Cardholder's surname: Nausch Cardholder's given name: Michael
Als nächstes definieren wir die Sprache des Kartenbenutzers:
gpg/card> lang
Language preferences: de
Im nächsten Schritt setzen wir das Geschlecht des Karteninhabers:
gpg/card> sex
Sex ((M)ale, (F)emale or space): m
Nun setzen wir noch den Anmelde-/Loginnamen entsprechend unserer Umgebung:
gpg/card> login
Login data (account name): django
Zu guter Letzt setzen wir nun die URL, von der der public-key mit Hilfe des Befehls fetch unter gpg --edit-card
auf die Karte geladen werden kann.
gpg/card> url
URL to retrieve public key: https://keys.openpgp.org/search?q=get&search=0x074ECF6150A6BFED
Somit ergeben sich folgende benutzerindividuellen Daten auf der Karte:
gpg/card> verify
Application ID ...: D276000124010200FFFE140819670000 Version ..........: 2.0 Manufacturer .....: unmanaged S/N range Serial number ....: 14081967 Name of cardholder: Michael Nausch Language prefs ...: de Sex ..............: male URL of public key : [not set] Login data .......: django Signature PIN ....: forced Key attributes ...: 2048R 2048R 2048R Max. PIN lengths .: 127 127 127 PIN retry counter : 3 3 3 Signature counter : 4 Signature key ....: B9D7 123A 1FEF B68D B901 937C 4F5A E805 485F 5308 created ....: 2020-08-04 21:25:33 Encryption key....: 57E6 DB7D 7A1C 5CA8 5373 C448 499C 2669 B5F5 7A76 created ....: 2020-08-04 21:25:33 Authentication key: 40CB FA55 DC16 F513 B5F8 7F9C 79BA 5416 C05A DFEB created ....: 2020-08-04 21:25:33 General key info..: [none]
Nun können wir die Erstinitialisierung abschliessen und den Einstellungsdialog mit dem Befehl quit verlassen.
gpg/card> quit
change-pin
WICHTIG: Unbedingt vor dem ersten Ändern der PINs ist es notwendig, erst einmal Schlüssel zu generieren bzw. zu importieren! Denn sonst schlägt das Ändern der Benutzer-PIN fehl, bzw. wird die Benutzer-PIN beim Überschreiben von Schlüsseln auf den Default-Wert von 123456 zurückgesetzt. Die Default-PIN für den Admin lautet 12345678.
Es ist sehr wichtig dass als erstes die Admin-PIN und dann erst im Anschluss die Nutzer-PIN geändert wird! Denn sonst der admin-less mode aktiviert!
Mit Hilfe des Befehls gpg --change-pin
können wir die Benutzer- und die Admin-PIN, wie auch die PIN zum Zurücksetzen der Benutzer-PIN, ändern.
Die Benutzer-PIN (Menüpunkt 1) wird benötigt für den täglichen Betrieb wie z.B. zum Entsperren des Token, oder zum Signieren und Verschlüsseln. Die Mindestlänge für den User-Pin beträgt 6 Zeichen.
Die Admin-PIN (Menüpunkt 3) wird für die Karten-/Token-Verwaltung verwendet, so z.B. für das Laden von Schlüsseln auf den Krypto-Stick, das Erzeugen von Schlüsseln oder das Ändern von Informationen wie die Inhaberdaten auf der Karte. Die Mindestlänge für die Admin-PIN beträgt 8 Zeichen.
Wird die Benutzer-PIN 3x falsch eingeben, wird die Karte gesperrt und kann dann nur mit der Admin-PIN oder dem Reset-Code zurückgesetzt werden. Wenn Sie den falschen Admin-Pin dreimal eingeben, wird die Karte unbrauchbar und kann dann lediglich mit einem Factory-Reset (Verlußt aller Kartendaten!) zurück gesetzt werden!
Ferner ist darauf zu achten, dass zunächst die Admin-PIN und erst dann die Nutzer-PIN geändert. Ansonsten wird nämlich der admin-less mode aktiviert.
Die Reset-PIN (Menüpunkt 4) kann nur zum Zurücksetzen der Benutzer-PIN verwendet werden. Die Mindestlänge für den Reset-Code beträgt 8 Zeichen. Der Reset-Code Fehlerzähler kann wiederum mit der Admin-PIN zurückgesetzt werden. Wird nach zweimaliger Falscheingabe der Benutzer- wie auch der Admin-PIN und dann die richtige PIN eingeben, wird der Fehlerzähler zurückgesetzt.
Worin besteht nun aber der genaue Unterschied zwischen dem Reset-Code und der Admin-PIN? Möchte man in einer Organisation Nitrokey Start an seine Mitarbeiter ausgeben, werden bestimmte Daten, wie z.B. Namen, die Public Key URL oder auch das erzeugte Schlüsselmaterial zentral vorgegeben. Da der Benutzer selbst diese Daten nicht verändern können soll, wird dieser auch nicht Kenntnis von der Admin-PIN haben. Sperrt sich nun der Mitarbeiter aus, weil er die Benutzer-PIN 3x falsch eingegeben hat, kann der Neutzer natürlich nicht die Admin-PIN eingeben, da er diese nicht kennt. Hier kommt nun der Reset-Code ins Spiel. Mit Hilfe dieses Codes kann der Benutzer nun die Benutzer-PIN zurücksetzen.
$ gpg --change-pin
gpg: OpenPGP Karte Nr. D276000124010200FFFE432437110000 erkannt 1 - change PIN 2 - unblock PIN 3 - change Admin PIN 4 - set the Reset Code Q - quit Ihre Auswahl?
Wir ändern also zu erste die Admin-PIN durch Auswahl des Menüpunkts 3 aus und erst anschliessend die Benutzer-PIN mit 1. Wir werden dann nach der aktuellen PIN gefragt und müssen die neue PIN 2x eingeben zum Abändern.
gpg/card> passwd gpg: OpenPGP card no. D276000124010200FFFE432437110000 detected 1 - change PIN 2 - unblock PIN 3 - change Admin PIN 4 - set the Reset Code Q - quit Your selection? 3 gpg: 3 Admin PIN attempts remaining before card is permanently locked Please enter the Admin PIN New Admin PIN New Admin PIN PIN changed. 1 - change PIN 2 - unblock PIN 3 - change Admin PIN 4 - set the Reset Code Q - quit Your selection? 1 Please enter the PIN New PIN New PIN PIN changed. 1 - change PIN 2 - unblock PIN 3 - change Admin PIN 4 - set the Reset Code Q - quit Your selection? 4 gpg: 3 Admin PIN attempts remaining before card is permanently locked Please enter the Admin PIN New Reset Code New Reset Code gpg: Reset Code is too short; minimum length is 8 Error setting the Reset Code: bad passphrase 1 - change PIN 2 - unblock PIN 3 - change Admin PIN 4 - set the Reset Code Q - quit Your selection? q gpg/card> quit
Verschlüsseln und entschlüsseln
Nun werden wir kurz einmal testen, ob wir mit Hilfe der Hardware-Schlüssel-Karte eine Datei ver- und wieder entschlüsseln können.
- Zunächst Wir legen uns erst einmal ein beliebiges Testdokument an.
$ cat /etc/os-release > testdatei.txt
Die Datei hat nun folgenden Inhalt:
$ cat testdatei.txt
NAME="Arch Linux" PRETTY_NAME="Arch Linux" ID=arch BUILD_ID=rolling ANSI_COLOR="38;2;23;147;209" HOME_URL="https://archlinux.org/" DOCUMENTATION_URL="https://wiki.archlinux.org/" SUPPORT_URL="https://bbs.archlinux.org/" BUG_REPORT_URL="https://gitlab.archlinux.org/groups/archlinux/-/issues" PRIVACY_POLICY_URL="https://terms.archlinux.org/docs/privacy-policy/" LOGO=archlinux-logo"
- Nun verschlüsseln wir dieses Textdokument:
$ gpg2 -o testdatei.txt.pgp -a -r django@nausch.org -e testdatei.txt
Wir haben also nun zwei Dokumente auf der Platte liegen.
$ ll testdatei.txt*
-rw-r--r-- 1 django django 382 Jun 3 22:35 testdatei.txt -rw-r--r-- 1 django django 581 Jun 3 22:35 testdatei.txt.pgp
Die Datei testdatei.txt.pgp können wir nun soweit nicht mehr lesen.
$ cat testdatei.txt.pgp
-----BEGIN PGP MESSAGE----- hF4Dvx6j9wMgPYoSAQdAhvFZiNZWBjduajM7OWUr2yM2KC9jfzgvd0SEHael4zUw XXie4+DZ25g7urXNBfnbwiHOw3z5j8P3vcblM8rpzB/u6+DmbZFFkiY6H5cVsCcs 0sAxARxA2p4YtPLOKyfGmxHifk6JqM19iUk2mht1MM2WqNtYUDLXKtos/2a4l+Xa SPBwdilxMkMQ+jEfNI8t66a2FXcqucjrXPXhKiyZK8C+EJQyLZAbml5W00UKJZHI lXQHfh1HCU+h1aOtmHM0kQSzOMprXRiEgyrrlG1ab5lZKMeIo7V7jwkQCOafs+PO SXUm1Hq4KPwuPDsGjQ3sQo7ErQZFsiVrSWD67lXqtqNhg8a/0diRdSayYgQcAX1F Rj1weIqZroiOvBW/9tY7vNCHS13pMNyZknZBFp7Gx36YqCnWGLkX/0BXvB0KTrMz AQeUjQ== =9ebq -----END PGP MESSAGE-----
- Nun entschlüsseln wir unser Dokument wieder.
$ gpg2 --decrypt testdatei.txt.pgp > testdatei-entschlüsselt.txt
gpg: encrypted with cv25519 key, ID B5E54345BDA292A0, created 2024-01-03 "Django (Bastard Operator from Hell [BOfH]) <django@nausch.org>"
Den Inhalt dieser Datei können wir nun nach erfolgter Entschlüsselung natürlich wieder lesen.
$ cat testdatei-entschlüsselt.txt
>NAME="Arch Linux" PRETTY_NAME="Arch Linux" ID=arch BUILD_ID=rolling ANSI_COLOR="38;2;23;147;209" HOME_URL="https://archlinux.org/" DOCUMENTATION_URL="https://wiki.archlinux.org/" SUPPORT_URL="https://bbs.archlinux.org/" BUG_REPORT_URL="https://gitlab.archlinux.org/groups/archlinux/-/issues" PRIVACY_POLICY_URL="https://terms.archlinux.org/docs/privacy-policy/" LOGO=archlinux-logo"
Signieren
Nun werden wir kurz einmal testen, ob wir mit Hilfe der Hardware-Schlüssel-Karte eine Datei signieren und die Signatur auch wieder prüfen können.
- Zunächst Wir legen uns erst einmal ein beliebiges Testdokument an.
$ date > textdatei.txt
Die Datei hat nun folgenden Inhalt:
$ cat textdatei.txt
Mon Jun 3 10:49:04 PM CEST 2024
- Nun signieren wir dieses Textdokument:
$ gpg --sign textdatei.txt
Wir haben also nun zwei Dokumente auf der Platte liegen.
$ ll textdatei.txt*
-rw-r--r-- 1 django django 33 Jun 3 23:19 textdatei.txt -rw-r--r-- 1 django django 182 Jun 3 23:19 textdatei.txt.gpg
Die Datei textdatei.txt.pgp können wir nun soweit nicht mehr lesen.
$ cat textdatei.txt.gpg
������!6��O�EF���5I�%�%)�%��z%%��W�d*��)8��+X��[+8��yF\�,b �b�,v�K�ݷ*79��a����2���S&�����Gq��}���o������u��Ȗ_�Wu_����&����y��G�P�z����ۙ��(;xn��4
Die Datei beinhaltet die Signatur zu unserer Datei, also entsprechender Zahlensalat.
$ file textdatei.txt.gpg
textdatei.txt.gpg: data
Dieses Vorgehen macht jedoch nur Sinn, wenn mit der Option
--encrypt
gleichzeitig die Datei verschlüsselt werden soll. Wir signieren nun die Datei mit dem privat-key und verschlüsseln die Datei mit dem public-key unseres eigenen Schlüssels auf dem Nitrokey Start. So kann die Datei nur von uns selbst wieder aufgemacht werden, sofern man im Besitz des Nitrokey Start und der zugehörigen PIN ist!$ gpg --encrypt --sign -r django@nausch.org textdatei.txt
Wir haben nunmehr eine neue verschlüsselte und signierte Datei.
$ file textdatei.txt.gpg
- Im nun folgendem Beispiel signieren wir unsere Datei und konvertieren sie so, dass wir sie einfach per eMail verschicken können. Hierzu nutzen wir die Option
--armor
.$ gpg --sign --armor textdatei.txt
Nun können wir uns die erstellte signierte Datei ansehen.
$ cat textdatei.txt.asc
-----BEGIN PGP MESSAGE----- owGbwMvMwCGWyHdz3dNgU3vGNSZJvCWpFSUpiSWpmXolFSVp8QnSIaWpCl6leQoK JgoGFlbG5laG5goBvgrOrsEhCkYGRiZcHaUsDGIcDLJiiiw6HCquZ38X3TubyhwA M5WVCWQKAxenAEzEYwXDPw0/ninLX283e//2sv+yjg/r9/lOPLKmI9zccMYltuJT FxUZ/pfN2Ddbnan3h5nysoDTVdK2k//GOnTeubN30pcUhwOynxkA =UkKj -----END PGP MESSAGE-----
Soll die Originaldatei zusammen mit der Signatur in der erzeugten Datei stehen, so verwendet man die Option
–-clearsign
.$ gpg --clearsign --armor textdatei.txt
Die erzeugte Testdatei.asc enthält dann sowohl den Originaltext, wie auch die Dateisignatur:
$ cat textdatei.txt.asc
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 Tue Jun 4 08:37:17 PM CEST 2024 -----BEGIN PGP SIGNATURE----- iHUEARYIAB0WIQQsCCRFzfty3s1lA1BhDtmu5VM1PwUCZl9gfwAKCRBhDtmu5VM1 P3TcAQDTPio3kyse3A6orXygqr5hP9etL25Lpq6ySzTjIDRcKgEA3qT4h/I6zm+Y a1EoA/Azg/l0zEMxZlj2yzK7Omxczw4= =34mx -----END PGP SIGNATURE-----
Mit der Option
-–verify
können wir die Signatur der Datei überprüfen:$ gpg --verify textdatei.txt.asc
gpg: Signature made Tue 04 Jun 2024 08:44:15 PM CEST gpg: using EDDSA key 2C082445CDFB72DECD650350610ED9AEE553353F gpg: Good signature from "Django (Bastard Operator from Hell [BOfH]) <django@nausch.org>" [ultimate] gpg: WARNING: not a detached signature; file 'textdatei.txt' was NOT verified!
Wir verändern nun zu Testzwecken den Inhalt der Testdatei, in dem wir den Text verfälschen. (
2099
als Jahresangabe)$ vim textdatei.txt.asc
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 Tue Jun 4 08:37:17 PM CEST 2099 -----BEGIN PGP SIGNATURE----- iHUEARYIAB0WIQQsCCRFzfty3s1lA1BhDtmu5VM1PwUCZl9gfwAKCRBhDtmu5VM1 P3TcAQDTPio3kyse3A6orXygqr5hP9etL25Lpq6ySzTjIDRcKgEA3qT4h/I6zm+Y a1EoA/Azg/l0zEMxZlj2yzK7Omxczw4= =34mx -----END PGP SIGNATURE-----
Nun überprüfen wir die Signatur der Testdatei, was natürlich postwendend als BAD signature angeprangert wird.
$ gpg --verify textdatei.txt.asc
gpg: Signature made Tue 04 Jun 2024 08:44:15 PM CEST gpg: using EDDSA key 2C082445CDFB72DECD650350610ED9AEE553353F gpg: BAD signature from "Django (Bastard Operator from Hell [BOfH]) <django@nausch.org>" [ultimate]
Nitrokey Start und Thunderbird
Nachdem wir nun unsere Schlüssel auf dem Kryptografie-Stick erstellt haben, wollen wir diesen nun verwenden um bei Thunderbird unsere elektronische Kommunikation per eMail abzusichern.
Thunderbird bringt mittlerweile die PGP-Unterstützung mit, so dass kein addon, wie enigmail
es früher noch noch notwendig war, zusätzlich installiert werden muss!
Lediglich die Unterstützung externer Smart-Cards wie unseres Nitrokey Start müssen wir in Thunderbird aktivieren.
Über das „Hamburger-Menü“ in der oberen Fensterleiste erreichen wir den Menüpunkt Einstellungen.
Hier scrollen wir ganz nach unten und wählen den Menüpunkt [ Konfiguration bearbeiten… ] aus.
Hier suchen wir nach der Option mail.openpgp.allow_external_gnupg
. Über die Schaltfläche rechts mit den zwei Pfeilen aktivieren wir diese Option.
Damit wir nun unseren Signature-Key mit unserem Thunderbird-Konto verbinden können benötigen wir natürlich die entsprechende Key-ID. Diese ermitteln wir nun mit folgendem Aufruf:
$ gpg2 --card-status | grep Signature\ key
Signature key ....: 2C08 2445 CDFB 72DE CD65 0350 610E D9AE E553 353F
Die vier letzten 4er-Blöcke merken wir uns nun entsprechend: 610E D9AE E553 353F
, in Kurzform entsprechend 610ED9AEE553353F
Über das „Hamburger-Menü“ in der oberen Fensterleiste erreichen wir den Menüpunkt Konten-Einstellungen.
Hier wählen wir dann den Menüpunkt [ Schlüssel hinzufügen ] aus.
Da wir den zuvor erzeugten PGP-Schlüssel auf unserem Nitrokey verwenden möchten, wählen wir hier letzten den Menüpunkt [ Externen Schlüssel mittels GnuPG benutzen. (z.B. von einer SmartCard aus) ].
… und klicken anschließen auf die Schaltfläche [ Fortfahren }.
Hier geben wir nun unsere zuvor ermittelte Key-ID ein und bestätigen anschliessend unsere Eingabe mit einem Klick auf die Schaltfläche [ Schlüssel-ID speichern ].
Nitrokey Start und Secure Shell
Ob man in Zeiten von Überwachungsphantasten in Unternehmen und vor allem auch bei einer NSA oder BND, noch RSA-Schlüssel einsetzen kann und mag, muss natürlich jeder verantwortungsbewusste Administrator für sich selbst entscheiden.
Der Sicherheitsguru Bruce Schneier hat in seinem Blog hierzu eine eindeutige Aussage getätigt:
„On the crypto bits in your guardian piece, I found especially interesting that you suggest classic discrete log crypto over ecc. I want to ask if you could elaborate more on that.“ I no longer trust the constants. I believe the NSA has manipulated them through their relationships with industry.
EED25519 ist ein Elliptic Curve Signature Schema, welches beste Sicherheit bei vertretbaren Aufwand verspricht, als ECDSA oder DSA dies der Fall ist. Detaillierte Informationen zur Implementierung von Curve25519/X25519: Ein Tutorial zur elliptischen Kurvenkryptografie finden sich in dem verlinktem Dokument von Martin Kleppmann. Zur Auswahl sicherer kryptografischer Kurven bei der Elliptic-Curve Cryptography findet man auf der Seite hier hilfreiche Erklärungen und eine Gegenüberstellung der möglichen verschiedenen Alternativen.
Auf RSA Schlüssel muss man aber nicht mehr zwingend zurückgreifen, stehen doch aktuellere und zeitgemässere Cipher, MACs, Schlüssel Typen und Key Exchange Algorithmen zur Verfügung. Als Alternative zu einem RSA-Keys haben wir uns bereits im Abschnitt Nitrokey Start und GnuPG - ED25519-Schlüssel generieren Schlüsselmaterial auf Basis elliptischer Kurven erstellt, unter anderem auch einen Authentication Key erstellt. Diesen Schlüssel wollen wir nun auch zur Serveradministration verwenden.
SSH Client vorbereiten
Damit wir beim Verbindungsaufbau auf den Authentication Key zugreifen können, müssen wir unseren Client entsprechend vorbereiten.
In der Konfigurationsdatei ~/.gnupg/gpg.conf setzen wir als erstes die Option use-agent
.
$ vim ~/.gnupg/gpg.conf
- ~/.gnupg/gpg.conf
# File re-created by pEp # See backup in '/home/django/.gnupg/gpg.conf.1.pep.bkp' # File re-created by pEp # See backup in '/home/django/.gnupg/gpg.conf.0.pep.bkp' # Created by pEpEngine keyserver hkp://keys.gnupg.net cert-digest-algo SHA256 no-emit-version no-comments personal-cipher-preferences AES AES256 AES192 CAST5 personal-digest-preferences SHA256 SHA512 SHA384 SHA224 ignore-time-conflict allow-freeform-uid # Ansible generated, do not edit manual! # Option use-agent für Authentication Key Nutzung des Nitrokey Start bei SSH use-agent
Im nächsten Schritt aktivieren wir die Option enable-ssh-support
in der Konfigurationsdatei ~/.gnupg/gpg-agent.conf
des GPG-Agenten.
$ vim ~/.gnupg/gpg-agent.conf
- ~/.gnupg/gpg-agent.conf
# File re-created by pEp # See backup in '/home/django/.gnupg/gpg-agent.conf.1.pep.bkp' # File re-created by pEp # See backup in '/home/django/.gnupg/gpg-agent.conf.0.pep.bkp' default-cache-ttl 300 max-cache-ttl 999999 # Ansible generated, do not edit manual! # SSH-Support activated for gnupg-agent enable-ssh-support
Nun werden wir noch die Datei ~/.bashrc erweitern, damit der SSH_AUTH_SOCK für den Zugriff des SSH-Schlüssels auf dem Nitrokey Start genutzt werden kann.
$ vim ~/.bashrc
- ~/.bashrc
# .bashrc # Source global definitions if [ -f /etc/bashrc ]; then . /etc/bashrc fi # User specific environment PATH="$HOME/.local/bin:$HOME/bin:$PATH" export PATH # Uncomment the following line if you don't like systemctl's auto-paging feature: # export SYSTEMD_PAGER= # User specific aliases and functions # Django : 2024-05-25 # Definition des SSH_AUTH_SOCK für den Zugriff des SSH-Schlüssels auf dem Nitrokey Start unset SSH_AGENT_PID if [ "${gnupg_SSH_AUTH_SOCK_by:-0}" -ne $$ ]; then export SSH_AUTH_SOCK="$(gpgconf --list-dirs agent-ssh-socket)" fi
Damit unsere Änderungen aktiv werden, müssen wir nun zum Schluss noch den pgp-agent restarten bzw. einen Neustart des Clients erwirken. Wir entscheiden uns der Einfachheit halber von einen Neustart des Agenten mit Hilfe des Befehls pkill gpg-agent
.
$ pkill gpg-agent
Ein Blick in die Prozessliste zeigt, dass der Agent nicht mehr läuft.
$ ps aux | grep gpg-agent
django 8752 0.0 0.0 215740 820 pts/1 S+ 21:56 0:00 grep --color=auto gpg-agent
Nun stecken wir unseren Nitrokey Start an den USB-Port und fragen den Kartenstatus ab.
$ gpg2 --card-status
Reader ...........: 20A0:4211:FSIJ-1.2.19-43243711:0 Application ID ...: D276000124010200FFFE432437110000 Application type .: OpenPGP Version ..........: 2.0 Manufacturer .....: unmanaged S/N range Serial number ....: 43243711 Name of cardholder: Michael Nausch Language prefs ...: de Salutation .......: Mr. URL of public key : [not set] Login data .......: [not set] Signature PIN ....: forced Key attributes ...: ed25519 cv25519 ed25519 Max. PIN lengths .: 127 127 127 PIN retry counter : 3 3 2 Signature counter : 23 KDF setting ......: off UIF setting ......: Sign=off Decrypt=off Auth=off Signature key ....: 2C08 2445 CDFB 72DE CD65 0350 610E D9AE E553 353F created ....: 2024-01-03 21:17:32 Encryption key....: 9533 C548 589F F00B 8FFF C93B B5E5 4345 BDA2 92A0 created ....: 2024-01-03 21:17:32 Authentication key: D5AF 3627 1220 7A2A 54BD 6C47 C72E 74B8 1A5C 4549 created ....: 2024-01-03 21:17:32 General key info..: pub ed25519/610ED9AEE553353F 2024-01-03 Django (Bastard Operator from Hell [BOfH]) <django@nausch.org> sec> ed25519/610ED9AEE553353F created: 2024-01-03 expires: never card-no: FFFE 43243711 ssb> ed25519/C72E74B81A5C4549 created: 2024-01-03 expires: never card-no: FFFE 43243711 ssb> cv25519/B5E54345BDA292A0 created: 2024-01-03 expires: never card-no: FFFE 43243711
Ein erneuter Blick in die Prozessliste zeigt nun den neu gestarteten Agenten.
$ ps aux | grep gpg-agent
django 8766 0.0 0.0 364724 804 ? Ss 21:57 0:00 gpg-agent --homedir /home/django/.gnupg --use-standard-socket --daemon django 8853 0.0 0.0 215740 828 pts/1 S+ 22:00 0:00 grep --color=auto gpg-agent
Public-Key des ED25519 SSH exportieren
Für den Zugriff auf unser Ziel-System mit Hilfe der SSH benötigen wir noch den öffentlichen Schlüssel unseres Authentication Keys, den wir nun exportieren werden. Zunächst besorgen wir uns die betreffende Schlüsselkennung des Authentication Keys, genauer gesagt die 4 letzten Zahlenreihen des nachfolgenden Aufrufs.
$ gpg2 --card-status | grep Authentication\ key
Authentication key: D5AF 3627 1220 7A2A 54BD 6C47 C72E 74B8 1A5C 4549
In diesem Konfigurationsbeispiel ist die Schlüssel-ID des Autentication Keys also die Nummer C72E74B81A5C4549
.
Nun exportieren wir den öffentlichen Schlüssel und schreiben diesen in eine separate Datei.
$ gpg2 --export-ssh-key C72E74B81A5C4549 >> ~/.ssh/C72E74B81A5C4549.pub
Der Öffentliche Schlüssel in diesen Konfigurationsbeispiel lautet also:
$ cat ~/.ssh/C72E74B81A5C4549.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHMD4OSvbbTRAs88C5jQeUX7HOR0TYd+EIQLcKmGCBll openpgp:0x1A5C4549
Diesen Schlüssel kopieren wir nun auf das entsprechende Zielsystem an Ort und Stelle ~/.ssh/authorized_keys
.
$ scp ~/.ssh/C72E74B81A5C4549.pub zielhost.dmz.nausch.org: && ssh zielhost.dmz.nausch.org 'cat authorized_keys >> ~/.ssh/authorized_keys'
SSH-Verbindung aufbauen
Nun können wir wie gewohnt eine Verbindung zu unserem entfernten System aufbauen, sofern der GPG-Agent am laufen ist. Wir können dazu entweder erst einmal abfragen, ob dieser gestartet wurde, mit Hilfe des folgenden Aufrufs:
$ ps -aux | grep gpg-agent
django 1430 0.0 0.0 376092 3636 ? SLsl 20:32 0:00 /usr/bin/gpg-agent --supervised
Oder wir fragen einfach den Karten-Status ab, was unweigerlich den Neustart des GPG-Agenten nach sich zieht.
$ gpg2 --card-status
Nun können wir die gewünschte Verbindung zum Zielsystem aufbauen.
$ ssh zielhost.dmz.nausch.org
Da der SSH-Key zur Authentication nicht im Dateisystem liegt, sondern auf der SmartCard des Nitrokey werden wir nun nach der User-PIN gefragt, damit auf den privaten Schlüssel der Karte zugegriffen werden kann.
Der entsperrte Schlüssel der SmartCard des Nitrokey Start wird nun im Speicher gehalten solange wir den USB-Hardwareschlüssel nicht abziehen.
WICHTIG:
Da wir den Schlüssel nicht aus einer Datei geladen hatten, können wir diese auch nicht mit Hilfe von ssh-add
wieder entladen! Wollen wir verhindern, dass auf den im Speicher vorgehaltenen Schlüssel zugegriffen wird, müssen wir manuell den GPG-Agenten beenden.
$ pkill gpg-agent
Anschliessend lassen sich Verbindungen zu unseren Remote-Systemen erst wieder aufbauen, wenn der GPG-Agent geladen und die Karte nach Eingabe der PIN entsperrt wurde!