Accès à un NetHSM à l’aide de l’API REST#

Ce tutoriel démontre comment accéder au NetHMS via l’API REST. L’interface est documentée ici, et sa spécification est disponible en tant que RAML et en tant que OpenAPI (Swagger).

Note

Si vous utilisez une instance de démonstration NetHSM avec un certificat auto-signé, par exemple en utilisant l’image Docker, vous devrez utiliser l’option –insecure/-k pour curl afin d’ignorer la vérification du certificat.

Note

Tout d’abord, définissez la valeur de $NETHSM_HOST sur l’adresse IP ou l’URL de votre NetHSM. Notre serveur de démonstration est accessible à l’adresse https://nethsmdemo.nitrokey.com/.

Tout d’abord, voyons ce que nous avons ici :

$ 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"}

Note

L’option -i/–include permet à curl d’imprimer le code d’état HTTP et les en-têtes de réponse. L’option -w “n”/–write-out “n” ; ajoute une nouvelle ligne après le corps de la réponse.

Voir quel est l’état de l’appareil :

$ 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"}

Initialisation#

Un nouveau NetHSM doit d’abord être approvisionné avec des phrases de passe et l’heure actuelle. La Admin Passphrase est la passphrase de l”Administrator, qui est le super-utilisateur du NetHSM. La Unlock Passphrase est utilisée pour crypter le magasin de données confidentielles du NetHSM.

Note

L’instance de démonstration NetHSM à nethsmdemo.nitrokey.com est déjà provisionnée.

$ 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 peut être utilisé en mode Attended Boot et Unattended Boot.

  • En mode Attended Boot, la Unlock Passphrase doit être saisie à chaque démarrage, ce qui permet de chiffrer la mémoire de données. Pour des raisons de sécurité, ce mode est recommandé.

  • En mode Démarrage sans surveillance, aucune phrase de passe de déverrouillage n’est requise, le NetHSM peut donc démarrer sans surveillance et la mémoire de données est stockée en clair. Utilisez ce mode si vos exigences de disponibilité ne peuvent être satisfaites avec le mode Attended Boot.

Récupère le mode actuel :

$ 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"}

Passez en mode 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

Ou repassez en mode Attended Boot :

$ 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

Gestion des utilisateurs#

Créer un utilisateur#

Créez maintenant un nouvel utilisateur avec le rôle d’opérateur qui pourra être utilisé pour signer et décrypter les données. Notez que le NetHSM attribue un ID utilisateur aléatoire si nous ne le spécifions pas.

$ 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

Gestion des clés#

Le NetHSM prend en charge les clés RSA, ED25519 et ECDSA. Lors de la création d’une clé, vous devez sélectionner à la fois l’algorithme de clé et les mécanismes de clé à utiliser. Les clés RSA peuvent être utilisées pour le décryptage (avec les modes raw, PKCS#1 et OAEP avec MD5, SHA1, SHA224, SHA256, SHA384 ou SHA512) et pour les signatures (avec les modes PKCS#1 et PSS avec MD5, SHA1, SHA224, SHA256, SHA384 ou SHA512). Les autres algorithmes ne supportent que le mécanisme de signature.

Pour obtenir une liste complète des algorithmes et des mécanismes de clé disponibles, consultez la documentation de l’API pour les types KeyAlgorithm et KeyMechanism.

Générer des clés#

Dans cette section, nous voulons utiliser une clé RSA pour déchiffrer des données en utilisant PKCS#1 et pour signer des données avec PSS en utilisant SHA256. Nous allons donc générer une nouvelle clé sur le NetHSM. Veillez à utiliser l’algorithme RSA et à sélectionner les mécanismes de clé RSA_Signature_PSS_SHA256 et RSA_Decryption_PKCS1. Si vous ne spécifiez pas d’ID de clé, le NetHSM générera un ID aléatoire pour la nouvelle clé.

$ 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

Clés d’importation#

Au lieu de générer une clé sur le NetHSM, vous pouvez également importer des clés privées existantes dans le NetHSM :

$ 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

Clés de liste#

Pour s’assurer que la clé a été créée et que les paramètres de l’algorithme et du mécanisme sont corrects, nous pouvons interroger toutes les clés du NetHSM :

$ 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"}]

Afficher les détails de la clé#

Nous pouvons également demander la clé publique de la paire de clés générée :

$ 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}

Pour pouvoir utiliser la clé avec OpenSSL, nous l’exportons sous forme de fichier PEM et la stockons sous le nom de public.pem :

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

Nous pouvons inspecter la clé avec OpenSSL et l’utiliser pour le cryptage ou la vérification des signatures (comme décrit dans la section suivante) :

$ 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-----

Certificats de clé#

Il est possible de définir et d’interroger des certificats pour les clés stockées sur une instance NetHSM :

$ 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

Demandes de signature de certificats de clés#

Le NetHSM prend en charge la génération de demandes de signature de certificats (CSR) pour les clés stockées :

$ 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

Opérations clés#

Décryptage#

Nous pouvons chiffrer les données pour la clé stockée sur le NetHSM en utilisant OpenSSL. (public.pem est le fichier de clé publique que nous avons créé dans la section Show Key Details).

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

Maintenant, nous pouvons utiliser le NetHSM pour décrypter les données :

$ 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!

Signature#

De même, nous pouvons signer des données en utilisant la clé du NetHSM. Pour RSA et ECDSA, nous devons d’abord calculer un condensé :

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

Nous pouvons ensuite créer une signature à partir de ce condensé en utilisant le NetHSM :

$ 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

Et ensuite utiliser OpenSSL pour vérifier la signature :

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

Verified OK

Sauvegardes#

Il est possible de créer une sauvegarde du NetHSM qui contient à la fois la configuration et les clés stockées. Pour créer une sauvegarde, vous devez d’abord définir une phrase de passe de sauvegarde qui sera utilisée pour chiffrer le fichier de sauvegarde :

$ 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

Maintenant vous devez créer un utilisateur avec le rôle R-Backup :

$ 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

Récupérez la sauvegarde et stockez-la dans un fichier :

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

Ce fichier de sauvegarde peut être restauré uniquement sur une instance NetHSM non provisionnée :

$ 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

Mises à jour#

Les mises à jour du NetHSM peuvent être installées en deux étapes. Vous devez d’abord télécharger l’image de mise à jour sur le NetHSM. L’image est ensuite vérifiée et validée. Si la validation est réussie, les notes de version de la mise à jour sont renvoyées par le NetHSM :

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

Si vous souhaitez poursuivre l’installation, vous pouvez maintenant valider la mise à jour :

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

Vous pouvez également annuler la mise à jour :

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