Доступ к NetHSM с помощью REST API#

This tutorial demonstrates how to access the NetHMS via REST API. The interface is documented here, and its specification is available as RAML and as OpenAPI (Swagger).

Примечание

Если вы используете демонстрационный экземпляр NetHSM с самоподписанным сертификатом, например, с помощью образа Docker, вам придется использовать опцию --insecure/-k для curl, чтобы пропустить проверку сертификата.

Примечание

Сначала установите значение $NETHSM_HOST в IP-адрес или URL вашего NetHSM. Наш демо-сервер можно найти по адресу https://nethsmdemo.nitrokey.com/.

Во-первых, давайте посмотрим, что у нас есть:

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

Примечание

Опция -i/–include заставляет curl печатать код состояния HTTP и заголовки ответа. Опция -w „n“/–write-out „n“ добавляет новую строку после тела ответа.

Узнайте состояние устройства:

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

Инициализация#

Для нового NetHSM необходимо сначала установить парольные фразы и текущее время. Парольная фраза Admin - это парольная фраза Administrator, который является суперпользователем NetHSM. Пароль Unlock Passphrase используется для шифрования хранилища конфиденциальных данных NetHSM.

Примечание

Демо-экземпляр NetHSM по адресу nethsmdemo.nitrokey.com уже предоставлен.

$ 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 может быть использован в режиме Attended Boot и Unattended Boot.

  • В режиме Attended Boot при каждом запуске необходимо вводить Unlock Passphrase, которая используется для шифрования хранилища данных. В целях безопасности рекомендуется использовать этот режим.

  • В режиме Unattended Boot не требуется парольная фраза для разблокировки, поэтому NetHSM может запускаться без присмотра, а хранилище данных хранится в незашифрованном виде. Используйте этот режим, если ваши требования к доступности не могут быть выполнены в режиме Attended Boot.

Получение текущего режима:

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

Переключитесь в режим 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

Или переключитесь обратно в режим 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

Управление пользователями#

Создать пользователя#

Теперь создайте нового пользователя с ролью оператора, который может использоваться для подписи и расшифровки данных. Обратите внимание, что NetHSM назначает случайный идентификатор пользователя, если мы его не указываем.

$ 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

Управление ключами#

NetHSM поддерживает ключи RSA, ED25519 и ECDSA. При создании ключа необходимо выбрать как алгоритм ключа, так и используемые ключевые механизмы. Ключи RSA можно использовать для расшифровки (в режимах raw, PKCS #1 и OAEP с MD5, SHA1, SHA224, SHA256, SHA384 или SHA512) и для подписи (в режимах PKCS #1 и PSS с MD5, SHA1, SHA224, SHA256, SHA384 или SHA512). Остальные алгоритмы поддерживают только механизм подписи.

Полный список доступных ключевых алгоритмов и ключевых механизмов см. в документации API для типов KeyAlgorithm и KeyMechanism.

Генерировать ключи#

В этом руководстве мы хотим использовать ключ RSA для расшифровки данных с помощью PKCS #1 и для подписи данных с помощью PSS с использованием SHA256. Поэтому давайте сгенерируем новый ключ на NetHSM. Обязательно используйте алгоритм RSA и выберите ключевые механизмы RSA_Signature_PSS_SHA256 и RSA_Decryption_PKCS1. Если вы не укажете идентификатор ключа, NetHSM сгенерирует случайный идентификатор для нового ключа.

$ 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

Импортные ключи#

Вместо того чтобы генерировать ключ на NetHSM, вы также можете импортировать существующие закрытые ключи в 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

Ключи списка#

Чтобы убедиться, что ключ был создан и имеет правильные настройки алгоритма и механизма, мы можем запросить все ключи в 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"}]

Показать ключевые детали#

Мы также можем запросить открытый ключ сгенерированной пары ключей:

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

Чтобы иметь возможность использовать ключ в OpenSSL, мы экспортируем его в PEM-файл и храним его под именем public.pem:

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

Мы можем проверить ключ с помощью openssl и использовать его для шифрования или проверки подписи (как описано в следующем разделе):

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

Ключевые сертификаты#

Можно устанавливать и запрашивать сертификаты для ключей, хранящихся на экземпляре 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

Запросы на подписание сертификата ключа#

NetHSM поддерживает генерацию запросов на подписание сертификатов (CSR) для хранящихся ключей:

$ 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

Основные операции#

Расшифровка#

Мы можем зашифровать данные для ключа, хранящегося на NetHSM, используя openssl. (public.pem - это файл открытого ключа, который мы создали в разделе Show Key Details).

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

Теперь мы можем использовать NetHSM для расшифровки данных:

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

Подпись#

Аналогичным образом мы можем подписывать данные, используя ключ на NetHSM. Для RSA и ECDSA сначала нужно вычислить дайджест:

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

Затем мы можем создать подпись из этого дайджеста с помощью 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

А затем используйте OpenSSL для проверки подписи:

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

Verified OK

Резервные копии#

Можно создать резервную копию NetHSM, которая будет содержать как конфигурацию, так и сохраненные ключи. Для создания резервной копии сначала необходимо задать парольную фразу, которая будет использоваться для шифрования файла резервной копии:

$ 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

Теперь необходимо создать пользователя с ролью 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

Получите резервную копию и сохраните ее в файле:

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

Этот резервный файл может быть восстановлен на экземпляре NetHSM, не прошедшем ревизию:

$ 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

Обновления#

Обновления для NetHSM можно установить в два этапа. Сначала необходимо загрузить образ обновления в NetHSM. Затем образ проверяется и подтверждается. Если проверка прошла успешно, NetHSM возвращает информацию о выпуске обновления:

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

Если вы хотите продолжить установку, вы можете зафиксировать обновление:

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

Кроме того, можно отменить обновление:

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