In diesem Kapitel befassen wir uns eingehend mit dem Nitrokey 3A Mini (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.
Der Nitrokey 3 vereint die Funktionen vorheriger Nitrokey Modelle: FIDO2, Einmalpasswörter, OpenPGP Chipkarte, Curve25519, Passwort-Manager, Common Criteria EAL 6+ zertifiziertes Secure Element, Firmware-Updates. Damit werden Ihre Accounts zuverlässig gegen Phishing und Passwort-Diebstahl geschützt und Ihre Kommunikation und Daten verschlüsselt. 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/shop/nk3am-nitrokey-3a-mini-149
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 ü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=01 Lev=03 Prnt=06 Port=01 Cnt=01 Dev#= 20 Spd=12 MxCh= 0 D: Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=20a0 ProdID=42b2 Rev=01.07 S: Manufacturer=Nitrokey S: Product=Nitrokey 3 C: #Ifs= 2 Cfg#= 1 Atr=80 MxPwr=100mA I: If#= 0 Alt= 0 #EPs= 2 Cls=0b(scard) Sub=00 Prot=00 Driver=(none) E: Ad=01(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms E: Ad=81(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms I: If#= 1 Alt= 0 #EPs= 2 Cls=03(HID ) Sub=00 Prot=00 Driver=usbhid E: Ad=02(O) Atr=03(Int.) MxPS= 64 Ivl=5ms E: Ad=82(I) Atr=03(Int.) MxPS= 64 Ivl=5ms
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/2/0 input7 input DP-2 /0/100/14/0/6/1/2 input Nitrokey 3 /0/100/14/0/6/1/3 input10 input USB OPTICAL MOUSE Keyboard /0/100/14/0/6/2 input1 input Das Keyboard Das Keyboard P13 Keyboard /0/100/1f.3/0 input15 input HDA Intel PCH Line Out /0/100/1f.3/1 input16 input HDA Intel PCH Headphone /0/100/1f.3/2 input17 input HDA Intel PCH HDMI/DP,pcm=3 /0/100/1f.3/3 input18 input HDA Intel PCH HDMI/DP,pcm=7 /0/100/1f.3/4 input19 input HDA Intel PCH HDMI/DP,pcm=8 /2 input0 input Power Button /3 input14 input PC Speaker
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 001 Device 022: ID 20a0:42b2 Clay Logic Nitrokey 3A Mini/3A NFC/3C NFC
Im Journal wird uns beim Anstecken des Sticks dies entsprechend protokolliert:
# journalctl -f
Dec 15 15:55:32 nitropc kernel: usb 1-6.1.2: new full-speed USB device number 23 using xhci_hcd Dec 15 15:55:33 nitropc kernel: usb 1-6.1.2: New USB device found, idVendor=20a0, idProduct=42b2, bcdDevice= 1.07 Dec 15 15:55:33 nitropc kernel: usb 1-6.1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=0 Dec 15 15:55:33 nitropc kernel: usb 1-6.1.2: Product: Nitrokey 3 Dec 15 15:55:33 nitropc kernel: usb 1-6.1.2: Manufacturer: Nitrokey Dec 15 15:55:33 nitropc kernel: hid-generic 0003:20A0:42B2.0011: hiddev99,hidraw7: USB HID v1.11 Device [Nitrokey Nitrokey 3] on usb-0000:00:14.0-6.1.2/input1 Dec 15 15:55:33 nitropc systemd[1]: Reached target Smart Card. Dec 15 15:55:33 nitropc systemd[1153]: Reached target Smart Card.
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 gezielt 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
*. Bei Bedarf können wir uns auch hier gezielt informieren welche Konfigurationsoptionen hier in der Datei definiert wurden.
# bat /usr/lib/udev/rules.d/41-nitrokey.rules
Konfigurationsdefinitionen in der Datei Datei 41-nitrokey.rules
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 ...........: 20A0:42B2:X:0 Application ID ...: D276000124010304000F6447F2530000 Application type .: OpenPGP Version ..........: 3.4 Manufacturer .....: Nitrokey Serial number ....: 6447F253 Name of cardholder: [not set] Language prefs ...: [not set] Salutation .......: 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 0 3 Signature counter : 0 KDF setting ......: off UIF setting ......: Sign=off Decrypt=off Auth=off Signature key ....: [none] Encryption key....: [none] Authentication key: [none] General key info..: [none]
# pacman -S python-pynitrokey
# nitropy --help
Usage: nitropy [OPTIONS] COMMAND [ARGS]... Options: -h, --help Show this message and exit. Commands: fido2 Interact with Nitrokey FIDO2 devices, see subcommands. list List Nitrokey devices (in firmware or bootloader mode) nethsm Interact with NetHSM devices, see subcommands. nk3 Interact with Nitrokey 3 devices, see subcommands. nkpk Interact with Nitrokey Passkey devices, see subcommands. pro Interact with Nitrokey Pro devices, see subcommands. start Interact with Nitrokey Start devices, see subcommands. storage Interact with Nitrokey Storage devices, see subcommands. version Version of pynitrokey library and tool.
# nitropy nk3 test
Command line tool to interact with Nitrokey devices 0.6.0 THIS COMMAND SHOULD NOT BE RUN AS ROOT! Please install udev rules and run `nitropy` as regular user (without sudo). We suggest using: https://raw.githubusercontent.com/Nitrokey/libnitrokey/master/data/41-nitrokey.rules For more information, see: https://docs.nitrokey.com/software/nitropy/linux/udev.html Set ALLOW_ROOT=1 environment variable to disable this warning. Found 1 NK3 device(s): - Nitrokey 3 at /dev/hidraw0 Running tests for Nitrokey 3 at /dev/hidraw0 [1/5] uuid UUID query SUCCESS 6447F2534D3A582D0000000000000000 [2/5] version Firmware version query SUCCESS v1.7.2 [3/5] status Device status SUCCESS Status(init_status=<InitStatus: 0>, ifs_blocks=241, efs_blocks=471, variant=<Variant.NRF52: 2>) Running SE050 test: | [4/5] se050 SE050 SUCCESS SE050 firmware version: 3.1.1 - 1.11, (persistent: (30140,), transient_deselect: (271,), transient_reset: (256,)) Please press the touch button on the device ... Please press the touch button on the device ... [5/5] fido2 FIDO2 SUCCESS 5 tests, 5 successful, 0 skipped, 0 failed Summary: 1 device(s) tested, 1 successful, 0 failed
Das Protokoll im Verzeichnis /tmp
von nitropy
zeigt im Zweifelsfall weitere Informationen die bei der weiteren Betrachtung oder Fehlereingrenzung wertvolle Informationen liefern kann.
# ls -al /tmp/nitropy.log.gkod8a3k
-rw-r--r-- 1 root root 5795 Dec 16 21:16 /tmp/nitropy.log.gkod8a3k
# cat /tmp/nitropy.log.gkod8a3k
368 INFO pynitrokey.cli Timestamp: 2024-12-16 21:16:27.120247 368 INFO pynitrokey.cli OS: uname_result(system='Linux', node='pml010074', release='6.6.65-1-lts', version='#1 SMP PREEMPT_DYNAMIC Wed, 11 Dec 2024 15:35:54 +0000', machine='x86_64') 368 INFO pynitrokey.cli Python version: 3.12.7 369 INFO pynitrokey.cli Cli arguments: ['nk3', 'test'] 372 INFO pynitrokey.cli pynitrokey version: 0.6.0 373 INFO pynitrokey.cli cryptography version: 43.0.3 374 INFO pynitrokey.cli ecdsa version: 0.19.0 374 INFO pynitrokey.cli fido2 version: 1.1.3 375 INFO pynitrokey.cli pyusb version: 1.2.1 376 INFO pynitrokey.cli.trussed.test platform: Linux-6.6.65-1-lts-x86_64-with-glibc2.40 376 INFO pynitrokey.cli.trussed.test uname: uname_result(system='Linux', node='pml010074', release='6.6.65-1-lts', version='#1 SMP PREEMPT_DYNAMIC Wed, 11 Dec 2024 15:35:54 +0000', machine='x86_64') 512 DEBUG root print: Found 1 NK3 device(s): 512 DEBUG root print: - Nitrokey 3 at /dev/hidraw0 512 DEBUG root print: Running tests for Nitrokey 3 at /dev/hidraw0 520 DEBUG root print: [1/5] uuid UUID query SUCCESS 6447F2534D3A582D0000000000000000 528 DEBUG root print: [2/5] version Firmware version query SUCCESS v1.7.2 536 INFO pynitrokey.cli.trussed.tests Device status: Status(init_status=<InitStatus: 0>, ifs_blocks=241, efs_blocks=471, variant=<Variant.NRF52: 2>) 536 DEBUG root print: [3/5] status Device status SUCCESS Status(init_status=<InitStatus: 0>, ifs_blocks=241, efs_blocks=471, variant=<Variant.NRF52: 2>) 669 DEBUG root print: [4/5] se050 SE050 SUCCESS SE050 firmware version: 3.1.1 - 1.11, (persistent: (30140,), transient_deselect: (271,), transient_reset: (256,)) 1782 DEBUG fido2.server Fido2Server initialized for RP: PublicKeyCredentialRpEntity(name='Example RP', id='example.com') 1782 DEBUG fido2.server Starting new registration, existing credentials: 1786 DEBUG root print: Please press the touch button on the device ... 1796 DEBUG fido2.client Register a new credential for RP ID: example.com 1838 DEBUG fido2.ctap2.base Calling CTAP2 make_credential 1996 DEBUG fido2.hid Got keepalive status: 01 2248 DEBUG fido2.hid Got keepalive status: 01 2496 DEBUG fido2.hid Got keepalive status: 01 2748 DEBUG fido2.hid Got keepalive status: 01 2996 DEBUG fido2.hid Got keepalive status: 01 3248 DEBUG fido2.hid Got keepalive status: 01 3496 DEBUG fido2.hid Got keepalive status: 01 3744 DEBUG fido2.hid Got keepalive status: 01 3996 DEBUG fido2.hid Got keepalive status: 01 4244 DEBUG fido2.hid Got keepalive status: 02 4496 DEBUG fido2.hid Got keepalive status: 01 4744 DEBUG fido2.hid Got keepalive status: 01 4996 DEBUG fido2.hid Got keepalive status: 01 5244 DEBUG fido2.hid Got keepalive status: 01 5492 DEBUG fido2.hid Got keepalive status: 01 5744 DEBUG fido2.hid Got keepalive status: 01 5992 DEBUG fido2.hid Got keepalive status: 01 6244 DEBUG fido2.hid Got keepalive status: 01 6492 DEBUG fido2.hid Got keepalive status: 01 6740 DEBUG fido2.hid Got keepalive status: 01 6992 DEBUG fido2.hid Got keepalive status: 01 7240 DEBUG fido2.hid Got keepalive status: 01 7492 DEBUG fido2.hid Got keepalive status: 01 7740 DEBUG fido2.hid Got keepalive status: 01 7992 DEBUG fido2.hid Got keepalive status: 01 8256 DEBUG fido2.hid Got keepalive status: 01 8512 DEBUG fido2.hid Got keepalive status: 01 8796 DEBUG fido2.hid Got keepalive status: 01 9056 DEBUG fido2.hid Got keepalive status: 01 9199 DEBUG fido2.server Verifying attestation of type packed 9200 INFO fido2.server New credential registered: a3005878bd496f7f5e7c10b12264abdc7274b8a2a8a1724eab6a6b2cf29737921dfb1c4793c1b3645547b7287ca5cd6087b3cd0c06e03c9115de4aeba206f2cfc14da879c4cf8c2045165008c9b3aa4591cee5b2cb825ee6c86f4ebe2f6bc8c4769902a550d389e11b235485931334234f15bf64de04d075aa27d394014c680a5adb95a30d02ed6d9e7f02505d85c63ba65a973e074ce94856cbb2a0 9201 DEBUG fido2.server Starting new authentication, for credentials: a3005878bd496f7f5e7c10b12264abdc7274b8a2a8a1724eab6a6b2cf29737921dfb1c4793c1b3645547b7287ca5cd6087b3cd0c06e03c9115de4aeba206f2cfc14da879c4cf8c2045165008c9b3aa4591cee5b2cb825ee6c86f4ebe2f6bc8c4769902a550d389e11b235485931334234f15bf64de04d075aa27d394014c680a5adb95a30d02ed6d9e7f02505d85c63ba65a973e074ce94856cbb2a0 9202 DEBUG root print: Please press the touch button on the device ... 9206 DEBUG fido2.client Assert a credential for RP ID: example.com 9237 DEBUG fido2.ctap2.base Calling CTAP2 get_assertion 9304 DEBUG fido2.hid Got keepalive status: 02 9552 DEBUG fido2.hid Got keepalive status: 01 9804 DEBUG fido2.hid Got keepalive status: 01 10052 DEBUG fido2.hid Got keepalive status: 01 10328 DEBUG fido2.hid Got keepalive status: 01 10588 DEBUG fido2.hid Got keepalive status: 01 10755 INFO fido2.server Credential authenticated: a3005878bd496f7f5e7c10b12264abdc7274b8a2a8a1724eab6a6b2cf29737921dfb1c4793c1b3645547b7287ca5cd6087b3cd0c06e03c9115de4aeba206f2cfc14da879c4cf8c2045165008c9b3aa4591cee5b2cb825ee6c86f4ebe2f6bc8c4769902a550d389e11b235485931334234f15bf64de04d075aa27d394014c680a5adb95a30d02ed6d9e7f02505d85c63ba65a973e074ce94856cbb2a0 10755 DEBUG root print: [5/5] fido2 FIDO2 SUCCESS 10756 DEBUG root print: 5 tests, 5 successful, 0 skipped, 0 failed 10756 DEBUG root print: Summary: 1 device(s) tested, 1 successful, 0 failed
Was ist WebAuthn?
Willkommen auf webauthn.io! Diese Website wurde von Duo Labs entwickelt, um WebAuthn und Passkeys zu testen. WebAuthn wird von allen gängigen Browsern, einschließlich Chrome, Safari und Firefox, sowie von allen modernen Betriebssystemen, einschließlich Android, iOS, macOS und Windows, unterstützt.
Eine Einführung in WebAuthn und seine Funktionen finden Sie unter webauthn.guide. Wenn Sie Ihre Website um WebAuthn-Unterstützung erweitern möchten, sind Sie bei passkeys.dev richtig. Der Code für diese Demo ist auf GitHub verfügbar.
Viele Informationen rund um den Nitrokey 3A Mini findet man auf der Nitrokey 3 Dokumentationsseite.
Da es sich bei der Chipkarte des Nitrokey 3A Mini 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.
Mit der Option card-status können wir uns mit dem Befehl gpg --card-status
den Kartenstatus ausgeben lassen.
$ gpg2 --card-status
Reader ...........: 20A0:42B2:X:0 Application ID ...: D276000124010304000F6447F2530000 Application type .: OpenPGP Version ..........: 3.4 Manufacturer .....: Nitrokey Serial number ....: 6447F253 Name of cardholder: [not set] Language prefs ...: [not set] Salutation .......: 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 0 3 Signature counter : 0 KDF setting ......: off UIF setting ......: Sign=off Decrypt=off Auth=off 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. |
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 ...........: 20A0:42B2:X:0 Application ID ...: D276000124010304000F6447F2530000 Application type .: OpenPGP Version ..........: 3.4 Manufacturer .....: Nitrokey Serial number ....: 6447F253 Name of cardholder: [not set] Language prefs ...: [not set] Salutation .......: 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 0 3 Signature counter : 0 KDF setting ......: off UIF setting ......: Sign=off Decrypt=off Auth=off Signature key ....: [none] Encryption key....: [none] Authentication key: [none] General key info..: [none] gpg/card>
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
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 openpgp switch to the OpenPGP app gpg/card>
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 salutation change card holder's salutation 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 kdf-setup setup KDF for PIN authentication (on/single/off) key-attr change the key attribute uif change the User Interaction Flag openpgp switch to the OpenPGP app gpg/card>
Wir wollen uns nun einen neuen PGP-Schlüssel in der SmartCard erzeugen und rufen hierzu den Befehl generate auf. Der Nitrokey 3A Mini unterstützt RSA-Schlüssellängen von 2048 und maximal von 4096!
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.
Bevor wir nun unser ersten Schlüsselpaar erzeugen, vergewissern wir uns nochmals kurz, welcher Schlüsseltyp und Schlüssellänge per Default beim Nitrokey 3A Mini denn voreingestellt sind.
$ gpg --card-status | grep Key
Key attributes ...: rsa2048 rsa2048 rsa2048
Der Schlüsseltyp RSA
passt soweit, aber wir möchten doch eher Ende 2024 auf einen 4k-Schlüssel zurückgreifen. Natürlich ist es ratsam hier genau auf den Einsatzzweck und der Zielsysteme bzw. Kommunikationspartner zu achten. Denn auch Ende 2024 gibt es durchaus noch Anwendungen die lediglich 2k-RSA-Schlüsselmaterial unterstützen!
Wir stellen nun als erstes mal die Schlüssellänge auf 4096
ein. Hierzu starten wir das Programm gpg
mit der Option --card-edit
.
$ gpg --card-edit
gpg/card> admin Admin commands are allowed gpg/card>
Mit dem Befehl key-attr
(change the key attribute) ändern wir nun die Schlüssel-Attribute. Die Admin-Pin lautet per Default 12345678
. Wir werden die Admin-PIN wie auch die User-PIN später noch ändern!
gpg/card> key-attr Changing card key attribute for: Signature key Please select what kind of key you want: (1) RSA (2) ECC Your selection? 1 What keysize do you want? (2048) 4096
Bei dem erscheinenden Eingabefeld zur PIN-Eingabe geben wir hier und bei den nachfolgenden Änderungen jeweils die Default-Admin-PIN 12345678>
ein.
The card will now be re-configured to generate a key of 4096 bits Changing card key attribute for: Encryption key Please select what kind of key you want: (1) RSA (2) ECC Your selection? 1 What keysize do you want? (2048) 4096
The card will now be re-configured to generate a key of 4096 bits Changing card key attribute for: Authentication key Please select what kind of key you want: (1) RSA (2) ECC Your selection? 1 What keysize do you want? (2048) 4096
The card will now be re-configured to generate a key of 4096 bits gpg/card>
Nun werden wir unsere 4k-RSA-Schlüsselmaterial erzeugen. Hierzu verwenden wir den Admin-Befehl generate
.
gpg/card> generate Make off-card backup of encryption key? (Y/n)
Da wir unseren private-key, der unter anderem zum Verschlüsseln verwendet wird, ausschliesslich in der Hardware-Schlüsselchips des Nitrokey 3A Mini vorhalten wollen bestätigen wir diese Frage hier mit der Eingabe von 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: Michael Nausch Email address: michael@nausch.org Comment: You selected this USER-ID: "Michael Nausch <michael@nausch.org>" Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o gpg: revocation certificate stored as '/home/django/.gnupg/openpgp-revocs.d/8B7A57A942EEB952543C3447381D2F43DC9CB69E.rev' public and secret key created and signed. pub rsa4096 2024-12-15 [SC] 8B7A57A942EEB952543C3447381D2F43DC9CB69E uid Michael Nausch <michael@nausch.org> sub rsa4096 2024-12-15 [A] sub rsa4096 2024-12-15 [E] gpg/card>
Die Erzeugung eines 4k-Schlüssels dauert einige Minuten, also keinesfalls den Nitrokey 3A Mini abziehen oder die Generierung abbrechen! Während der Erzeugung der Schlüssel leuchtet bzw. blinkt die LED im Stick.
gpg: revocation certificate stored as '/home/django/.gnupg/openpgp-revocs.d/8B7A57A942EEB952543C3447381D2F43DC9CB69E.rev' public and secret key created and signed. pub rsa4096 2024-12-15 [SC] 8B7A57A942EEB952543C3447381D2F43DC9CB69E uid Michael Nausch <michael@nausch.org> sub rsa4096 2024-12-15 [A] sub rsa4096 2024-12-15 [E]
Die OpenPGP-Karte kann mit Hilfe des Befehls gpg –card-edit
zurückgesetzt werden.
$ gpg2 --card-edit
Reader ...........: 20A0:42B2:X:0 Application ID ...: D276000124010304000F6447F2530000 Application type .: OpenPGP Version ..........: 3.4 Manufacturer .....: Nitrokey Serial number ....: 6447F253 Name of cardholder: [not set] Language prefs ...: [not set] Salutation .......: URL of public key : [not set] Login data .......: [not set] Signature PIN ....: forced Key attributes ...: rsa4096 rsa4096 rsa4096 Max. PIN lengths .: 127 127 127 PIN retry counter : 3 0 3 Signature counter : 4 KDF setting ......: off UIF setting ......: Sign=off Decrypt=off Auth=off Signature key ....: 8B7A 57A9 42EE B952 543C 3447 381D 2F43 DC9C B69E created ....: 2024-12-15 15:57:07 Encryption key....: A3C0 465D A803 2B0D 8698 45AF FDD8 A382 72CF C453 created ....: 2024-12-15 15:57:07 Authentication key: 1ECA 9914 E932 D485 061E 087A 035C E93F 4258 5E99 created ....: 2024-12-15 15:57:07 General key info..: pub rsa4096/381D2F43DC9CB69E 2024-12-15 Michael Nausch <michael@nausch.org> sec> rsa4096/381D2F43DC9CB69E created: 2024-12-15 expires: never card-no: 000F 6447F253 ssb> rsa4096/035CE93F42585E99 created: 2024-12-15 expires: never card-no: 000F 6447F253 ssb> rsa4096/FDD8A38272CFC453 created: 2024-12-15 expires: never card-no: 000F 6447F253 gpg/card>
Mit dem Befehl admin
wechseln wir in dern Admin-Menübereich.
gpg/card> admin Admin commands are allowed gpg/card>
Zum Zurücksetzen des Krypto-Gerätes auf Werkseinstellungen verwenden wir hier nun den Befehl factory-reset
gpg/card> factory-reset gpg: OpenPGP card no. D276000124010304000F6447F2530000 detected gpg: Note: This command destroys all keys stored on the card! Continue? (y/N)
Hier bestätigen wir unseren Wunsch mit Eingabe von y
.
Really do a factory reset? (enter "yes")
Nach Eingabe von yes
beginnt die LED des Nitrokey 3A Mini zu blinken und endet dann am Ende wenn der Factory-Reste abgeschlossen ist.
Rufen wir erneut den Status des Nitrokey 3A Mini ab, so sind alle unsere zuvor gemachten Änderungen wieder weg und wir können mit der Konfiguration wieder von vorne beginnen!
$ gpg2 --card-status
Reader ...........: 20A0:42B2:X:0 Application ID ...: D276000124010304000F6447F2530000 Application type .: OpenPGP Version ..........: 3.4 Manufacturer .....: Nitrokey Serial number ....: 6447F253 Name of cardholder: [not set] Language prefs ...: [not set] Salutation .......: 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 0 3 Signature counter : 0 KDF setting ......: off UIF setting ......: Sign=off Decrypt=off Auth=off Signature key ....: [none] Encryption key....: [none] Authentication key: [none]
Seit nummher einem Jahr - genauer gesagt seit 20223 - empfiehlt unter anderem das BSI1) keine RSA-Schlüssel mit einer Länge von 2048 Bit einzusetzen. Bei langen Nutzungsdauern von z.B. 5 Jahren und mehr ist es bereits jetzt notwendig, längere Schlüssel zu generieren. 3k oder 4-Schlüssel haben jedoch den Nachteil dass diese deutlich langsamer sind. Dank der Unterstützung bei der Verschlüsselung mittels beim Nitrokey 3A Mini können wir die deutlich Elliptische-Kurven-Kryptographie (ECC) verwednen! Dieses Verschlüsselungsverfahren gilt bei kleineren ECC-Schlüsseln als genauso sicher wie längere RSA-Schlüssel und ist zudem deutlich schneller!
Im Gegensatz zu RSA gibt es bei der Kryptographie mit elliptischen Kurven viele verschiedene Formen (sogenannte Kurven).
Nicht unerwähnt soll hier aber auch sein, dass die NSA2) an der Entwicklung der NIST-Kurven beteiligt war - auch wenn es keine Hinweise auf Hintertüren in den Kurven gibt, kann die Verwendung dieser bestimmten NIST-Kurve eine Frage des Vertrauens darstellen.
Glücklicherweise unterstützen die neuen Nitrokeyszwei Arten von Kurven, nämlich NIST und Brainpool, daher werden später statt der NIST-Kurven hier die Brainpool P-256-Kurven verwenden! Weiter ergänzende Informationen zum Thema ist in dem Artikel hier → Eine (relativ leicht verständliche) Einführung in die Kryptografie mit elliptischen Kurven zu finden!
Damit auf einem Nitrokey 3A Mini Schlüssel auf Basis elliptischer Kurven generiert werden können, 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 aktuell3) die Version 2.4.7 bereitgestellt wird. Bei Bedarf können wir die Version z.B. wie folgt abfragen.
$ gpg2 --version | grep gpg
gpg (GnuPG) 2.4.7
Die Version der Karten-Firmware können wir bei Bedarf wie folgt ermiteln:
$ gpg2 --card-status | grep Ver
Version ..........: 3.4
Nun werden wir uns Schlüsselpaar auf Basis elliptischer Kurven auf dem Nitrokey 3A Mini 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 ...........: 20A0:42B2:X:0 Application ID ...: D276000124010304000F6447F2530000 Application type .: OpenPGP Version ..........: 3.4 Manufacturer .....: Nitrokey Serial number ....: 6447F253 Name of cardholder: [not set] Language prefs ...: [not set] Salutation .......: 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 0 3 Signature counter : 0 KDF setting ......: off UIF setting ......: Sign=off Decrypt=off Auth=off 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 *default*.
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 *default* (4) NIST P-384 (6) Brainpool P-256 Your selection? 1
Bei dem erscheinenden Eingabefeld zur PIN-Eingabe geben wir hier und bei den nachfolgenden Änderungen jeweils die Default-Admin-PIN 12345678>
ein.
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 *default* (4) NIST P-384 (6) Brainpool P-256 Your selection? 1 The card will now be re-configured to generate a key of type: brainpoolP256r1
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 *default* (4) NIST P-384 (6) Brainpool P-256 Your selection? 1
gpg/card>
Zur Erfolgskontrolle können wir den Status wir folgt abfragen:
$ gpg2 --card-status | grep Key
Key attributes ...: ed25519 cv25519 ed25519
Nun werden wir unser ED25519-Schlüsselmaterial erzeugen. Hierzu verwenden wir den Admin-Befehl generate
.
gpg/card> generate Make off-card backup of encryption key? (Y/n)
Da wir unseren private-key, der unter anderem zum Verschlüsseln verwendet wird, ausschliesslich in der Hardware-Schlüsselchips des Nitrokey 3A Mini vorhalten wollen bestätigen wir diese Frage hier mit der Eingabe von 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: Michael Nausch Email address: michael@nausch.org Comment: You selected this USER-ID: "Michael Nausch <michael@nausch.org>" Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o gpg: revocation certificate stored as '/home/django/.gnupg/openpgp-revocs.d/F5F0CD13074BA693D950F92A0A56C9A3A69FE291.rev' public and secret key created and signed. pub ed25519 2024-12-15 [SC] F5F0CD13074BA693D950F92A0A56C9A3A69FE291 uid Michael Nausch <michael@nausch.org> sub ed25519 2024-12-15 [A] sub cv25519 2024-12-15 [E] gpg/card>
Die Erzeugung eines ED255194k-Schlüssels dauert wenige Sekunden, also auch hier keinesfalls den Nitrokey 3A Mini abziehen oder die Generierung abbrechen! Während der Erzeugung der Schlüssel leuchtet bzw. blinkt die LED im Stick.
gpg: revocation certificate stored as '/home/django/.gnupg/openpgp-revocs.d/F5F0CD13074BA693D950F92A0A56C9A3A69FE291.rev' public and secret key created and signed. pub ed25519 2024-12-15 [SC] F5F0CD13074BA693D950F92A0A56C9A3A69FE291 uid Michael Nausch <michael@nausch.org> sub ed25519 2024-12-15 [A] sub cv25519 2024-12-15 [E]
Wir verfügen als nun über unser gewünschte ED25519-Schlüsselmaterial.
$ gpg2 --card-status
Reader ...........: 20A0:42B2:X:0 Application ID ...: D276000124010304000F6447F2530000 Application type .: OpenPGP Version ..........: 3.4 Manufacturer .....: Nitrokey Serial number ....: 6447F253 Name of cardholder: [not set] Language prefs ...: [not set] 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 0 3 Signature counter : 4 KDF setting ......: off UIF setting ......: Sign=off Decrypt=off Auth=off Signature key ....: F5F0 CD13 074B A693 D950 F92A 0A56 C9A3 A69F E291 created ....: 2024-12-15 17:08:38 Encryption key....: DBBD 5355 D9D0 334A A3FA 751F A89D D54D AE0E 394A created ....: 2024-12-15 17:08:38 Authentication key: EE7C 3807 4F0A 8F2A 5601 BF91 1E61 4A9A 36D4 DF53 created ....: 2024-12-15 17:08:38 General key info..: pub ed25519/0A56C9A3A69FE291 2024-12-15 Michael Nausch <michael@nausch.org> sec> ed25519/0A56C9A3A69FE291 created: 2024-12-15 expires: never card-no: 000F 6447F253 ssb> ed25519/1E614A9A36D4DF53 created: 2024-12-15 expires: never card-no: 000F 6447F253 ssb> cv25519/A89DD54DAE0E394A created: 2024-12-15 expires: never card-no: 000F 6447F253
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
gpg: checking the trustdb gpg: marginals needed: 3 completes needed: 1 trust model: pgp gpg: depth: 0 valid: 6 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 6u /home/django/.gnupg/pubring.kbx ------------------------------- sec> ed25519 2024-12-15 [SC] F5F0CD13074BA693D950F92A0A56C9A3A69FE291 Card serial no. = 000F 6447F253 uid [ultimate] Michael Nausch <michael@nausch.org> ssb> ed25519 2024-12-15 [A] ssb> cv25519 2024-12-15 [E]
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 michael@nausch.org> ~/.gnupg/michael@nausch.org_F5F0CD13074BA693D950F92A0A56C9A3A69FE291.pubkey
Diese Datei enthält unseren Schlüssel in ASCII-lesbarer Form.
$ cat ~/.gnupg/secmail@nausch.org.pubkey
-----BEGIN PGP PUBLIC KEY BLOCK----- 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 Vo7asIbAswY= =6DCk -----END PGP PUBLIC KEY BLOCK-----
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:42B2:X:0 Application ID ...: D276000124010304000F6447F2530000 Application type .: OpenPGP Version ..........: 3.4 Manufacturer .....: Nitrokey Serial number ....: 6447F253 Name of cardholder: [not set] Language prefs ...: [not set] 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 0 3 Signature counter : 4 KDF setting ......: off UIF setting ......: Sign=off Decrypt=off Auth=off Signature key ....: F5F0 CD13 074B A693 D950 F92A 0A56 C9A3 A69F E291 created ....: 2024-12-15 17:08:38 Encryption key....: DBBD 5355 D9D0 334A A3FA 751F A89D D54D AE0E 394A created ....: 2024-12-15 17:08:38 Authentication key: EE7C 3807 4F0A 8F2A 5601 BF91 1E61 4A9A 36D4 DF53 created ....: 2024-12-15 17:08:38 General key info..: pub ed25519/0A56C9A3A69FE291 2024-12-15 Michael Nausch <michael@nausch.org> sec> ed25519/0A56C9A3A69FE291 created: 2024-12-15 expires: never card-no: 000F 6447F253 ssb> ed25519/1E614A9A36D4DF53 created: 2024-12-15 expires: never card-no: 000F 6447F253 ssb> cv25519/A89DD54DAE0E394A created: 2024-12-15 expires: never card-no: 000F 6447F253
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=0x0A56C9A3A69FE291
Somit ergeben sich folgende benutzerindividuellen Daten auf der Karte:
gpg/card> verify
Reader ...........: 20A0:42B2:X:0 Application ID ...: D276000124010304000F6447F2530000 Application type .: OpenPGP Version ..........: 3.4 Manufacturer .....: Nitrokey Serial number ....: 6447F253 Name of cardholder: Michael Nausch Language prefs ...: de Salutation .......: Mr. URL of public key : https://keys.openpgp.org/search?q=get&search=0x0A56C9A3A69FE291 Login data .......: django Signature PIN ....: forced Key attributes ...: ed25519 cv25519 ed25519 Max. PIN lengths .: 127 127 127 PIN retry counter : 3 0 3 Signature counter : 4 KDF setting ......: off UIF setting ......: Sign=off Decrypt=off Auth=off Signature key ....: F5F0 CD13 074B A693 D950 F92A 0A56 C9A3 A69F E291 created ....: 2024-12-15 17:08:38 Encryption key....: DBBD 5355 D9D0 334A A3FA 751F A89D D54D AE0E 394A created ....: 2024-12-15 17:08:38 Authentication key: EE7C 3807 4F0A 8F2A 5601 BF91 1E61 4A9A 36D4 DF53 created ....: 2024-12-15 17:08:38 General key info..: pub ed25519/0A56C9A3A69FE291 2024-12-15 Michael Nausch <michael@nausch.org> sec> ed25519/0A56C9A3A69FE291 created: 2024-12-15 expires: never card-no: 000F 6447F253 ssb> ed25519/1E614A9A36D4DF53 created: 2024-12-15 expires: never card-no: 000F 6447F253 ssb> cv25519/A89DD54DAE0E394A created: 2024-12-15 expires: never card-no: 000F 6447F253
Nun können wir die Erstinitialisierung abschliessen und den Einstellungsdialog mit dem Befehl quit verlassen.
gpg/card> quit
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
Nun werden wir kurz einmal testen, ob wir mit Hilfe der Hardware-Schlüssel-Karte eine Datei ver- und wieder entschlüsseln können.
$ cat /etc/os-release > testdatei.txt
Die Datei hat nun folgenden Inhalt:
$ bat testdatei.txt
───────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────── │ File: testdatei.txt ───────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 1 │ NAME="Arch Linux" 2 │ PRETTY_NAME="Arch Linux" 3 │ ID=arch 4 │ BUILD_ID=rolling 5 │ ANSI_COLOR="38;2;23;147;209" 6 │ HOME_URL="https://archlinux.org/" 7 │ DOCUMENTATION_URL="https://wiki.archlinux.org/" 8 │ SUPPORT_URL="https://bbs.archlinux.org/" 9 │ BUG_REPORT_URL="https://gitlab.archlinux.org/groups/archlinux/-/issues" 10 │ PRIVACY_POLICY_URL="https://terms.archlinux.org/docs/privacy-policy/" 11 │ LOGO=archlinux-logo ───────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
$ gpg2 -o testdatei.txt.pgp -a -r michael@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 Dec 15 18:33 testdatei.txt -rw-r--r-- 1 django django 687 Dec 15 18:35 testdatei.txt.pgp
Die Datei testdatei.txt.pgp können wir nun soweit nicht mehr lesen.
$ cat testdatei.txt.pgp
-----BEGIN PGP MESSAGE----- hE4DqJ3VTa4OOUoSAQdAFrLZCi4ZoZl0AcBxZSk/PlSK7CGGd3G/fwIe2+Ha7VAg Uwr1N2CAtxx2obPMMN1arTGakL7xjU34QAKef0mSHaqETgO15UNFvaKSoBIBB0BY hn4iz/gZAtl3tLXac/Qyu6/G82qI0RJmiQaFIY22XiCjk+bnhUZ9eoWeN/eW9z40 6tL30sxOYnAwviDvuoogE9LAaQEYHYqLVT0+BnzO6xRpKYOm6FafrIjGY4APg5hH I/4rELNdt/g5u1Z1xc7r/KHEelnOa8Nsg63r8jFuX1QH4vlKNFRPuYl1J7wytTdX 8DvdkQ1gDFrK0eL/b7dhrrR9PPHxNX4w+cpLMDmd+Wfd+zj4xrryVnrW88YHvXFH JVQLhJBCQ8GXhFheeozcattp0KZioVW6h12p4/tqttAySYLvMLSoTLFxOu4gPZrp kZYzQ89k63jay1g7kU3VF6jlOSHVNz5f5GODG2WNW+2lLlbDm1ISu22iTZ4uWnGh zGmSxh8NBFxg288gCj0He7HiKuYWEpvn872F8TGms6GCBKvnCPP9UGSehv7H+YQy VDKog8Fv17h1ieaMudrKE9YH6Dc1zx+rrhiYEg== =QWj0 -----END PGP MESSAGE-----
$ 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>" gpg: encrypted with cv25519 key, ID A89DD54DAE0E394A, created 2024-12-15 "Michael Nausch <michael@nausch.org>"
Den Inhalt dieser Datei können wir nun nach erfolgter Entschlüsselung natürlich wieder lesen.
$ cat testdatei-entschlüsselt.txt
───────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────── │ File: testdatei-entschlüsselt.txt ───────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 1 │ NAME="Arch Linux" 2 │ PRETTY_NAME="Arch Linux" 3 │ ID=arch 4 │ BUILD_ID=rolling 5 │ ANSI_COLOR="38;2;23;147;209" 6 │ HOME_URL="https://archlinux.org/" 7 │ DOCUMENTATION_URL="https://wiki.archlinux.org/" 8 │ SUPPORT_URL="https://bbs.archlinux.org/" 9 │ BUG_REPORT_URL="https://gitlab.archlinux.org/groups/archlinux/-/issues" 10 │ PRIVACY_POLICY_URL="https://terms.archlinux.org/docs/privacy-policy/" 11 │ LOGO=archlinux-logo ───────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
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.
$ date > textdatei.txt
Die Datei hat nun folgenden Inhalt:
$ bat textdatei.txt
───────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────── │ File: textdatei.txt ───────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 1 │ Sun Dec 15 06:41:05 PM CET 2024 ───────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
$ gpg --sign textdatei.txt
Wir haben also nun zwei Dokumente auf der Platte liegen.
$ ll textdatei.txt*
-rw-r--r-- 1 django django 32 Dec 15 18:41 textdatei.txt -rw-r--r-- 1 django django 183 Dec 15 18:42 textdatei.txt.gpg
Die Datei textdatei.txt.pgp können wir nun soweit aber nicht mehr lesen.
$ cat textdatei.txt.gpg
������!�vr���&2�1N�-I�(II,I��+�(I��\������`h�``febhe`����␦�`d`d��Q�� �� +�����Yav�e�o�Ԃ��2���S&"����8��;6N0����6��_�s���=���N��cQ �#^N�r�)����h�A���M�%�v��;�V�[
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
$ gpg --clearsign textdatei.txt
Wir haben nun neben den beiden bereits vorhandenen Dokumenten eine Datei mehr auf der Platte liegen.
$ ll textdatei.txt*
-rw-r--r-- 1 django django 32 Dec 15 18:41 textdatei.txt -rw-r--r-- 1 django django 309 Dec 15 18:47 textdatei.txt.asc -rw-r--r-- 1 django django 183 Dec 15 18:42 textdatei.txt.gpg
Diese neue zusätzliche Datei hat nun neben dem ursprünglichen Datumseintrag auch die Signatur als Inhalt:
$ bat textdatei.txt
───────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────── │ File: textdatei.txt.asc ───────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 1 │ -----BEGIN PGP SIGNED MESSAGE----- 2 │ Hash: SHA256 3 │ 4 │ Sun Dec 15 06:41:05 PM CET 2024 5 │ -----BEGIN PGP SIGNATURE----- 6 │ 7 │ iHUEARYIAB0WIQT18M0TB0umk9lQ+SoKVsmjpp/ikQUCZ18WPwAKCRAKVsmjpp/i 8 │ kWqCAQD2HgexZVX5kXZd4Rb0tpRDVWQ0mMYOddTEWHwSKjuH0wEA5vXotBQz/Gau 9 │ grzeojRPxjVR+wRcDCIyPOHw5ISq8ws= 10 │ =CNnO 11 │ -----END PGP SIGNATURE----- ───────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
--detach-sig
erstellt. $ gpg --output textdatei.sig --detach-sig textdatei.txt
wir haben nun eine vierte Datei auf unserer Platte.
$ ll text*
-rw-r--r-- 1 django django 119 Dec 15 19:00 textdatei.sig -rw-r--r-- 1 django django 32 Dec 15 18:41 textdatei.txt -rw-r--r-- 1 django django 309 Dec 15 18:47 textdatei.txt.asc -rw-r--r-- 1 django django 183 Dec 15 18:42 textdatei.txt.gpg
Diese neue Datei textdatei.sig
beinhaltet nun die Signatur unserer Datei textdatei.txt
. Mit Hilfe der Option --verify
ist nun ein Empfänger in der Lage die Validität der empfamngenen Textdatei zu überprüfen.
$ gpg --verify textdatei.sig textdatei.txt
gpg: Signature made Sun 15 Dec 2024 07:00:18 PM CET gpg: using EDDSA key F5F0CD13074BA693D950F92A0A56C9A3A69FE291 gpg: Good signature from "Michael Nausch <michael@nausch.org>" [ultimate]
Zum Testen was opassiert, wenn wir nun diese Datei maniüulieren z.B. durch anhängen eines weiteren Datums via.
$ date >> textdatei.txt
Nun überprüfen wir erneut ob die Signatur zur Datei passt.
$ gpg --verify textdatei.sig textdatei.txt
Da wir die ursprünglich signierte Datei ja verändert haben, wird nun ein entsprechender Fehler angezeigt:
gpg: Signature made Sun 15 Dec 2024 07:00:18 PM CET gpg: using EDDSA key F5F0CD13074BA693D950F92A0A56C9A3A69FE291 gpg: BAD signature from "Michael Nausch <michael@nausch.org>" [ultimate]
--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]
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 ....: F5F0 CD13 074B A693 D950 F92A 0A56 C9A3 A69F E291
Die vier letzten 4er-Blöcke merken wir uns nun entsprechend: 0A56 C9A3 A69F E291
, in Kurzform entsprechend 0A56C9A3A69FE291
Ü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 ].
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 A3 Mini 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.
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
# 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
# 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 # 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:42B2:X:0 Application ID ...: D276000124010304000F6447F2530000 Application type .: OpenPGP Version ..........: 3.4 Manufacturer .....: Nitrokey Serial number ....: 6447F253 Name of cardholder: Michael Nausch Language prefs ...: de Salutation .......: Mr. URL of public key : https://keys.openpgp.org/search?q=get&search=0x0A56C9A3A69FE291 Login data .......: django Signature PIN ....: forced Key attributes ...: ed25519 cv25519 ed25519 Max. PIN lengths .: 127 127 127 PIN retry counter : 3 0 3 Signature counter : 10 KDF setting ......: off UIF setting ......: Sign=off Decrypt=off Auth=off Signature key ....: F5F0 CD13 074B A693 D950 F92A 0A56 C9A3 A69F E291 created ....: 2024-12-15 17:08:38 Encryption key....: DBBD 5355 D9D0 334A A3FA 751F A89D D54D AE0E 394A created ....: 2024-12-15 17:08:38 Authentication key: EE7C 3807 4F0A 8F2A 5601 BF91 1E61 4A9A 36D4 DF53 created ....: 2024-12-15 17:08:38 General key info..: pub ed25519/0A56C9A3A69FE291 2024-12-15 Michael Nausch <michael@nausch.org> sec> ed25519/0A56C9A3A69FE291 created: 2024-12-15 expires: never card-no: 000F 6447F253 ssb> ed25519/1E614A9A36D4DF53 created: 2024-12-15 expires: never card-no: 000F 6447F253 ssb> cv25519/A89DD54DAE0E394A created: 2024-12-15 expires: never card-no: 000F 6447F253
Ein erneuter Blick in die Prozessliste zeigt nun den neu gestarteten Agenten.
$ ps aux | grep gpg-agent
django 1428 0.0 0.0 228968 4068 ? SLsl 19:52 0:00 /usr/bin/gpg-agent --supervised django 5787 0.0 0.0 6392 2300 pts/0 S+ 20:32 0:00 grep --color=auto gpg-agent
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: EE7C 3807 4F0A 8F2A 5601 BF91 1E61 4A9A 36D4 DF53
In diesem Konfigurationsbeispiel ist die Schlüssel-ID des Autentication Keys also die Nummer 1E614A9A36D4DF53
.
Nun exportieren wir den öffentlichen Schlüssel und schreiben diesen in eine separate Datei.
$ gpg2 --export-ssh-key 1E614A9A36D4DF53 >> ~/.ssh/1E614A9A36D4DF53.pub
Der Öffentliche Schlüssel in diesen Konfigurationsbeispiel lautet also:
$ cat ~/.ssh/1E614A9A36D4DF53.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILz8sjaPGlC16rOK7s8S8gzBmbfnCOsiz4jD77+BuLn4 openpgp:0x36D4DF53
Diesen Schlüssel kopieren wir nun auf das entsprechende Zielsystem an Ort und Stelle ~/.ssh/authorized_keys
.
$ scp ~/.ssh/1E614A9A36D4DF53.pub zielhost.dmz.nausch.org: && ssh zielhost.dmz.nausch.org 'cat authorized_keys >> ~/.ssh/authorized_keys'
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!