Zugriff auf ein NetHSM über die REST-API#

Dieses Tutorial zeigt, wie man über die REST-API auf NetHMS zugreifen kann. Die Schnittstelle ist hier dokumentiert, und ihre Spezifikation ist als RAML und als OpenAPI (Swagger) verfügbar.

Bemerkung

Wenn Sie eine NetHSM-Demo-Instanz mit einem selbstsignierten Zertifikat verwenden, zum Beispiel mit dem Docker-Image, müssen Sie die Option –insecure/-k für curl verwenden, um die Zertifikatsprüfung zu überspringen.

Bemerkung

Setzen Sie zunächst den Wert von $NETHSM_HOST auf die IP-Adresse oder URL Ihres NetHSM. Unser Demoserver ist unter https://nethsmdemo.nitrokey.com/ zu erreichen.

Schauen wir uns zunächst an, was wir hier haben:

$ curl -i -w '\n' https://$NETHSM_HOST/api/v1/info

HTTP/1.1 200 OK
content-length: 45
content-type: application/json
date: Mon, 25 Jan 2021 21:00:27 GMT
etag: "7bab62510e05c332735624bc7a585a30"
vary: Accept, Accept-Encoding, Accept-Charset, Accept-Language

{"vendor":"Nitrokey GmbH","product":"NetHSM"}

Bemerkung

Die Option -i/–include bewirkt, dass curl den HTTP-Statuscode und die Antwort-Header ausgibt. Die Option -w ‚n‘/–write-out ‚n‘ fügt einen Zeilenumbruch nach dem Antwortkörper ein.

Sehen Sie nach, welchen Status das Gerät hat:

$ curl -i -w '\n' https://$NETHSM_HOST/api/v1/health/state

HTTP/1.1 200 OK
cache-control: no-cache
content-length: 25
content-type: application/json
date: Mon, 25 Jan 2021 20:57:32 GMT
vary: Accept, Accept-Encoding, Accept-Charset, Accept-Language

{"state":"Unprovisioned"}

Initialisierung#

Ein neuer NetHSM muss zunächst mit Passphrasen und der aktuellen Uhrzeit eingerichtet werden. Die Admin Passphrase ist die Passphrase des Administrators, der der Superuser des NetHSM ist. Die Unlock Passphrase wird verwendet, um den vertraulichen Datenspeicher von NetHSM zu verschlüsseln.

Bemerkung

Die NetHSM-Demo-Instanz unter nethsmdemo.nitrokey.com ist bereits eingerichtet.

$ curl -i -w '\n' -X POST https://$NETHSM_HOST/api/v1/provision \
-H "content-type: application/json" \
-d "{ adminPassphrase: \"adminPassphrase\", unlockPassphrase: \"unlockPassphrase\", \
systemTime: \"$(date --utc -Iseconds)\"}"

HTTP/1.1 204 No Content
cache-control: no-cache
content-type: application/json
date: Wed, 11 Nov 2020 16:35:44 GMT
vary: Accept, Accept-Encoding, Accept-Charset, Accept-Language

NetHSM kann im Attended Boot-Modus und im Unattended Boot-Modus verwendet werden.

  • Im Modus Attended Boot muss bei jedem Start die Unlock Passphrase eingegeben werden, die zur Verschlüsselung des Datenspeichers verwendet wird. Aus Sicherheitsgründen wird dieser Modus empfohlen.

  • Im Modus Unattended Boot ist keine Unlock Passphrase erforderlich, daher kann der NetHSM unbeaufsichtigt starten und der Datenspeicher wird unverschlüsselt gespeichert. Verwenden Sie diesen Modus, wenn Ihre Verfügbarkeitsanforderungen mit dem Attended Boot-Modus nicht erfüllt werden können.

Ruft den aktuellen Modus ab:

$ curl -i -w '\n' -u admin \
https://$NETHSM_HOST/api/v1/config/unattended-boot

HTTP/1.1 200 OK
content-length: 16
content-type: application/json
date: Wed, 21 Apr 2021 10:20:55 GMT
vary: Accept, Accept-Encoding, Accept-Charset, Accept-Language

{"status":"off"}

Wechseln Sie in den Modus Unattended Boot:

$ curl -i -w '\n' -X PUT -H "content-type: application/json" \
https://$NETHSM_HOST/api/v1/config/unattended-boot -d "{ status: \"on\"}"

HTTP/1.1 204 No Content
content-type: application/json
date: Wed, 21 Apr 2021 10:24:25 GMT
vary: Accept, Accept-Encoding, Accept-Charset, Accept-Language

Oder wechseln Sie zurück in den Attended Boot-Modus:

$ curl -i -w '\n' -u admin -X PUT -H "content-type: application/json" \
https://$NETHSM_HOST/api/v1/config/unattended-boot -d "{ status: \"off\"}"

HTTP/1.1 204 No Content
content-type: application/json
date: Wed, 21 Apr 2021 10:24:53 GMT
vary: Accept, Accept-Encoding, Accept-Charset, Accept-Language

Benutzerverwaltung#

Erstellen eines Benutzers#

Erstellen Sie nun einen neuen Benutzer mit der Operator-Rolle, der zum Signieren und Entschlüsseln von Daten verwendet werden kann. Beachten Sie, dass der NetHSM eine zufällige Benutzer-ID vergibt, wenn wir diese nicht angeben.

$ curl -i -w '\n' -u admin \
"https://$NETHSM_HOST/api/v1/users/operator" -X PUT \
-H "content-type: application/json" -d "{\"realName\": \"Jane User\", \
\"role\": \"Operator\", \"passphrase\": \"opPassphrase\"}"

HTTP/1.1 201 Created
content-length: 0
content-type: application/json
date: Wed, 21 Apr 2021 10:25:27 GMT
location: /api/v1/users/operator
vary: Accept, Accept-Encoding, Accept-Charset, Accept-Language

Schlüsselverwaltung#

Der NetHSM unterstützt RSA-, ED25519- und ECDSA-Schlüssel. Bei der Erstellung eines Schlüssels müssen Sie sowohl den Schlüsselalgorithmus als auch die zu verwendenden Schlüsselmechanismen auswählen. RSA-Schlüssel können zur Entschlüsselung (in den Modi raw, PKCS#1 und OAEP mit MD5, SHA1, SHA224, SHA256, SHA384 oder SHA512) und für Signaturen (in den Modi PKCS#1 und PSS mit MD5, SHA1, SHA224, SHA256, SHA384 oder SHA512) verwendet werden. Die anderen Algorithmen unterstützen nur den Signaturmechanismus.

Eine vollständige Liste der verfügbaren Schlüsselalgorithmen und Schlüsselmechanismen finden Sie in der API-Dokumentation für die Typen KeyAlgorithm und KeyMechanism.

Schlüssel generieren#

In diesem Abschnitt wollen wir einen RSA-Schlüssel zum Entschlüsseln von Daten mit PKCS#1 und zum Signieren von Daten mit PSS mit SHA256 verwenden. Lassen Sie uns also einen neuen Schlüssel auf dem NetHSM generieren. Stellen Sie sicher, dass Sie den RSA-Algorithmus verwenden und die Schlüsselmechanismen RSA_Signature_PSS_SHA256 und RSA_Decryption_PKCS1 auswählen. Wenn Sie keine Schlüssel-ID angeben, generiert der NetHSM eine zufällige ID für den neuen Schlüssel.

$ curl -i -w '\n' -u admin -X POST \
https://$NETHSM_HOST/api/v1/keys/generate -H "content-type: application/json" \
-d "{ \"mechanisms\": [ \"RSA_Signature_PSS_SHA256\", \"RSA_Decryption_PKCS1\" ], \
\"type\": \"RSA\",  \"length\": 2048,  \"id\": \"myFirstKey\"}"

HTTP/1.1 201 Created
cache-control: no-cache
content-length: 0
content-type: application/json
date: Tue, 26 Jan 2021 05:54:09 GMT
location: /api/v1/keys/0ead0d9dd849cecf845c
vary: Accept, Accept-Encoding, Accept-Charset, Accept-Language

Schlüssel importieren#

Anstatt einen Schlüssel auf dem NetHSM zu generieren, können Sie auch vorhandene private Schlüssel in den NetHSM importieren:

$ curl -i -w '\n' -u admin -X PUT \
https://$NETHSM_HOST/api/v1/keys/mySecondKey -H "content-type: application/json" \
-d "{ \"mechanisms\": [ \"RSA_Signature_PSS_SHA256\", \"RSA_Decryption_PKCS1\" ], \
\"type\": \"RSA\",  \"key\": {\"primeP\": \"AOnWFZ+JrI/xOXJU04uYCZOiPVUWd6CSbVseEYrYQYxc7dVroePshz29tc+VEOUP5T0O8lXMEkjFAwjW6C9QTAsPyl6jwyOQluMRIkdN4/7BAg3HAMuGd7VmkGyYrnZWW54sLWp1JD6XJG33kF+9OSar9ETPoVyBgK5punfiUFEL\", \"primeQ\": \"ANT1kWDdP9hZoFKT49dwdM/S+3ZDnxQa7kZk9p+JKU5RaU9e8pS2GOJljHwkES1FH6CUGeIaUi81tRKe2XZhe/163sEyMcxkaaRbBbTc1v6ZDKILFKKt4eX7LAQfhL/iFlgi6pcyUM8QDrm1QeFgGz11ChM0JuQw1WwkX06lg8iv\", \"publicExponent\": \"AQAB\"}}"

HTTP/1.1 204 No Content
content-type: application/json
date: Wed, 21 Apr 2021 10:37:23 GMT
vary: Accept, Accept-Encoding, Accept-Charset, Accept-Language

Schlüssel auflisten#

Um sicherzustellen, dass der Schlüssel erstellt wurde und die richtigen Algorithmus- und Mechanismuseinstellungen hat, können wir alle Schlüssel auf dem NetHSM abfragen:

$ curl -i -w '\n' -u admin
HTTP/1.1 200 OK
content-length: 39
content-type: application/json
date: Tue, 26 Jan 2021 05:56:24 GMT
etag: "34353234366432333063663739313939346635316666343937333564653434333937613237626139"
vary: Accept, Accept-Encoding, Accept-Charset, Accept-Language

[{"key":"myFirstKey"},{"key":"mySecondKey"}]

Schlüsseldetails anzeigen#

Wir können auch den öffentlichen Schlüssel des erzeugten Schlüsselpaares abfragen:

$ curl -s -w '\n' -u admin https://$NETHSM_HOST/api/v1/keys/myFirstKey

{"mechanisms":["RSA_Decryption_PKCS1","RSA_Signature_PSS_SHA256"],"type":"RSA","modulus":"td583uBYRfO7qtvPoQF7liUh8gq3zckCk9LpCfblx2S0HdOvButfD4TyH4EMiZj3NhEoq18BZhqhxTL22UyNJwYJd2tCF4EbgTaj/Z3LeCPoGN5LjadFCsYriPeHsdnuLmTK6KsmTAP/CWJ+u3LesU5bCGWbDnPjv2WaLTeiMuNw1347gj1drft8jFA9SmOFjZxM9pq2Hk1nQSYpeAPCnigC7hLwAWgzKqVQv/J7VVWat3ke/jOrxFiRDFIeC3qxtBs6T7GYwqmsxkxgqKDljTAH4qMrC9vgVbbFPffe8UgmtDfvQ0ghP57b3HYZDON90MJ2qrU944E74g+ua6unTw==","publicExponent":"AQAB","operations":0}

Um den Schlüssel mit OpenSSL verwenden zu können, exportieren wir ihn als PEM-Datei und speichern ihn als public.pem:

$ curl -u operator -X GET \
https://$NETHSM_HOST/api/v1/keys/myFirstKey/public.pem -o public.pem

Wir können den Schlüssel mit OpenSSL untersuchen und ihn zur Verschlüsselung oder Signaturprüfung verwenden (wie im nächsten Abschnitt beschrieben):

$ openssl rsa -in public.pem -pubin -text

RSA Public-Key: (2048 bit)
Modulus:
    00:c3:56:f5:09:cc:a9:3e:ca:16:2e:fb:d2:8b:9d:
    a9:33:5a:87:8f:3f:7a:bb:8a:3d:62:9b:5d:56:84:
    95:97:bb:97:f0:77:e2:c8:59:f2:b5:c6:b7:f5:b3:
    76:69:a3:e8:f6:b7:35:f4:3c:52:6d:3c:a0:b6:a1:
    e4:1a:32:05:1d:51:68:21:7d:fc:53:69:ec:bc:0b:
    a0:db:63:b2:0e:47:00:03:4d:98:1f:ab:c0:7b:2e:
    3c:8f:b6:36:ff:f0:db:80:26:f0:a6:af:30:2f:7b:
    16:fd:5c:db:0f:2c:54:8a:26:2b:db:3d:78:49:4b:
    7b:d1:60:ea:a7:f0:b4:5e:fc:33:ff:57:f8:83:fd:
    12:64:8f:29:d1:94:96:9a:15:18:5d:04:ca:1c:29:
    44:ad:42:31:c5:80:38:4c:eb:3b:b8:7e:17:27:5c:
    69:a8:88:44:ea:d1:82:64:fe:51:31:47:97:a7:a9:
    87:c3:13:c9:00:7a:b9:fb:6f:cc:66:4c:07:d7:68:
    fa:78:68:9a:e7:87:1e:94:c6:27:92:5f:f2:7d:11:
    44:11:b5:39:35:59:2c:cd:f9:4f:59:e3:56:93:1f:
    94:20:fd:6b:23:0d:15:e6:4e:bb:84:a8:a5:0d:9f:
    1c:90:ab:a8:10:04:50:12:c1:80:02:94:85:78:df:
    d6:b3
Exponent: 65537 (0x10001)
writing RSA key
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw1b1CcypPsoWLvvSi52p
M1qHjz96u4o9YptdVoSVl7uX8HfiyFnytca39bN2aaPo9rc19DxSbTygtqHkGjIF
HVFoIX38U2nsvAug22OyDkcAA02YH6vAey48j7Y2//DbgCbwpq8wL3sW/VzbDyxU
iiYr2z14SUt70WDqp/C0Xvwz/1f4g/0SZI8p0ZSWmhUYXQTKHClErUIxxYA4TOs7
uH4XJ1xpqIhE6tGCZP5RMUeXp6mHwxPJAHq5+2/MZkwH12j6eGia54celMYnkl/y
fRFEEbU5NVkszflPWeNWkx+UIP1rIw0V5k67hKilDZ8ckKuoEARQEsGAApSFeN/W
swIDAQAB
-----END PUBLIC KEY-----

Schlüssel-Zertifikate#

Es ist möglich, Zertifikate für die auf einer NetHSM-Instanz gespeicherten Schlüssel zu setzen und abzufragen:

$ curl -i -w '\n' -u admin -X PUT \
https://$NETHSM_HOST/api/v1/keys/myFirstKey/cert -H "content-type: application/x-pem-file" \
--data-binary @/tmp/cert.pem

HTTP/1.1 201 Created
content-length: 0
content-type: text/html
date: Thu, 20 May 2021 19:15:39 GMT
vary: Accept, Accept-Encoding, Accept-Charset, Accept-Language
 $ curl -s -w '\n' -u operator -X GET \
https://$NETHSM_HOST/api/v1/keys/myFirstKey/cert > /tmp/cert.pem
$ curl -i -w '\n' -u admin -X DELETE \
https://$NETHSM_HOST/api/v1/keys/myFirstKey/cert

HTTP/1.1 204 No Content
content-type: text/html
date: Thu, 20 May 2021 19:14:45 GMT
vary: Accept, Accept-Encoding, Accept-Charset, Accept-Language

Signieranforderungen für Schlüsselzertifikate#

Der NetHSM unterstützt die Erzeugung von Certificate Signing Requests (CSR) für die gespeicherten Schlüssel:

$ curl -s -w '\n' -u operator -X POST \
https://$NETHSM_HOST/api/v1/keys/myFirstKey/csr.pem -H "content-type: application/json" \
-d "{ \"countryName\": \"DE\", \"stateOrProvinceName\": \"BE\", \
\"localityName\": \"Berlin\", \"organizationName\": \"ACME\", \
\"organizationalUnitName\": \"IT\", \"commonName\": \"example.com\", \
\"emailAddress\": \"it@example.com\" }" > /tmp/cert.pem

Wichtige Vorgänge#

Entschlüsselung#

Wir können Daten für den auf dem NetHSM gespeicherten Schlüssel mit openssl verschlüsseln. (public.pem ist die Datei des öffentlichen Schlüssels, die wir im Abschnitt Schlüsseldetails anzeigen erstellt haben)

$ echo 'NetHSM rulez!' | OpenSSL rsautl -encrypt -inkey public.pem -pubin | base64 > data.crypt

Jetzt können wir den NetHSM zum Entschlüsseln der Daten verwenden:

$ curl -s -u operator -X POST \
https://$NETHSM_HOST/api/v1/keys/myFirstKey/decrypt -H "content-type: application/json" \
-d "{ \"mode\": \"PKCS1\", \"encrypted\": \"$(cat data.crypt)\"}" | \
jq -r .decrypted | base64 -d

NetHSM rulez!

Signieren#

Auf ähnliche Weise können wir Daten mit dem Schlüssel auf dem NetHSM signieren. Für RSA und ECDSA müssen wir zuerst einen Digest berechnen:

$ echo 'NetHSM rulez!' > data
$ openssl dgst -sha256 -binary data | base64 > data.digest

Dann können wir mit dem NetHSM eine Signatur aus diesem Digest erstellen:

$ curl -s -u operator -X POST \
https://$NETHSM_HOST/api/v1/keys/myFirstKey/sign -H "content-type: application/json" \
-d "{ \"mode\": \"PSS_SHA256\", \"message\": \"$(cat data.digest)\"}" | \
jq -r .signature | base64 -d > data.sig

Und dann verwenden Sie OpenSSL, um die Signatur zu überprüfen:

$ openssl dgst -sha256 -verify public.pem -signature data.sig \
-sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1 data

Verified OK

Backups#

Es ist möglich, ein Backup des NetHSM zu erstellen, das sowohl die Konfiguration als auch die gespeicherten Schlüssel enthält. Um ein Backup zu erstellen, müssen Sie zunächst eine Backup-Passphrase festlegen, die zur Verschlüsselung der Backup-Datei verwendet wird:

$ curl -i -w '\n' -u admin -X PUT \
https://$NETHSM_HOST/api/v1/config/backup-passphrase -H "content-type: application/json" \
-d "{\"passphrase\": \"backupencryptionkey\"}"

HTTP/2 204
server: nginx/1.14.2
date: Sat, 08 May 2021 10:26:36 GMT
cache-control: no-cache
vary: Accept, Accept-Encoding, Accept-Charset, Accept-Language
strict-transport-security: max-age=63072000; includeSubDomains; preload
x-frame-options: DENY
x-content-type-options: nosniff
x-xss-protection: 1; mode=block
x-permitted-cross-domain-policies: none

Nun müssen Sie einen Benutzer mit der Rolle R-Backup anlegen:

$ curl -i -w '\n' -u admin -X PUT \
https://$NETHSM_HOST/api/v1/users/backup -H "content-type: application/json" \
-d "{\"realName\": \"Backup User\", \"role\": \"Backup\", \
\"passphrase\": \"backupPassphrase\"}"

HTTP/2 201
server: nginx/1.14.2
date: Sat, 08 May 2021 10:30:45 GMT
content-type: application/json
content-length: 0
location: /api/v1/users/backup
vary: Accept, Accept-Encoding, Accept-Charset, Accept-Language
strict-transport-security: max-age=63072000; includeSubDomains; preload
x-frame-options: DENY
x-content-type-options: nosniff
x-xss-protection: 1; mode=block
x-permitted-cross-domain-policies: none

Holen Sie sich das Backup und speichern Sie es in einer Datei:

$ curl -s -u backup -X POST \
https://$NETHSM_HOST/api/v1/system/backup > /tmp/nethsm-backup

Diese Sicherungsdatei kann nur auf einer unprovisionierten NetHSM-Instanz wiederhergestellt werden:

$ curl -i -X POST \
"https://$NETHSM_HOST/api/v1/system/restore?backupPassphrase=backupencryptionkey&systemTime=$(date --utc +"%Y-%m-%dT%H:%M:%SZ")" \
 --data-binary @/tmp/nethsm-backup

HTTP/1.1 204 No Content
cache-control: no-cache
content-type: application/json
date: Sat, 08 May 2021 10:59:19 GMT
vary: Accept, Accept-Encoding, Accept-Charset, Accept-Language

Aktualisierungen#

Updates für den NetHSM können in einem zweistufigen Verfahren installiert werden. Zunächst müssen Sie das Update-Image auf den NetHSM hochladen. Anschließend wird das Image geprüft und validiert. Wenn die Validierung erfolgreich ist, werden die Versionshinweise für das Update vom NetHSM zurückgegeben:

$ curl -i -w '\n' -u admin -X POST  \
https://$NETHSM_HOST/api/v1/system/update --data-binary "@/tmp/nethsm-update.img.cpio"

Wenn Sie mit der Installation fortfahren möchten, können Sie das Update jetzt bestätigen:

$ curl -i -w '\n' -u admin -X POST  \
https://$NETHSM_HOST/api/v1/system/commit-update

Alternativ können Sie das Update auch abbrechen:

$ curl -i -w '\n' -u admin -X POST  \
https://$NETHSM_HOST/api/v1/system/cancel-update