创建和导入加密密钥
了解如何使用 Hyper Protect Crypto Services创建加密密钥并将其引入云。
目标
本教程指导您创建加密密钥并将其安全地导入到 Hyper Protect Crypto Services 服务中。 它适用于不熟悉 Hyper Protect Crypto Services的密钥管理功能,但可能对密钥管理系统有一定熟悉的用户。 以下步骤需要大约 20 分钟才能完成。
- 设置密钥管理服务 API
- 准备 Hyper Protect Crypto Services 服务实例以开始导入密钥
- 使用 OpenSSL 密码术工具箱创建和加密密钥
- 将加密密钥导入到 Hyper Protect Crypto Services 服务实例
本教程不会对您的 IBM Cloud 帐户产生任何费用。
任务流程
以下流程图概述了如何创建和导入加密密钥。 您可以单击图表上的每个步骤以查看该步骤的详细信息。
准备工作
要开始使用,您需要 IBM Cloud CLI,以便可以与在 IBM Cloud上供应的服务进行交互。 您还需要在工作站上本地安装 openssl
和 jq
软件包。
-
创建 IBM Cloud 帐户。
-
下载并安装适用于您操作系统的 IBM Cloud CLI。
-
下载并安装 IBM Key Protect CLI 插件 v0.6.3 或更高版本,并 将其配置为在 Hyper Protect Crypto Services 中使用。 确保将
KP_PRIVATE_ADDR
变量更新为当前实例密钥管理端点 URL。要检查 IBM Key Protect CLI 插件版本:
ibmcloud plugin show key-protect
要将 IBM Key Protect CLI 插件更新为最新版本,请执行以下操作:
ibmcloud plugin update key-protect -r 'IBM Cloud'
-
下载并安装 OpenSSL 密码术库。
如果您首次尝试 Hyper Protect Crypto Services,那么可以使用
openssl
命令在本地工作站上创建加密密钥。 本教程需要 OpenSSL V1.0.2r
或更高版本。如果您使用的是 Mac,那么可以使用 Homebrew快速启动并运行 OpenSSL。 如果是首次安装软件包,请运行
brew install openssl
,或者运行brew upgrade openssl
以将现有软件包升级到最新版本。 -
下载并安装 jq。
jq
可帮助您对 JSON 数据进行切片。 在本教程中,您将使用jq
来抓取和使用在调用 Hyper Protect Crypto Services 密钥管理服务 API 时返回的特定数据。
创建导入令牌
通过服务凭证,您可以开始与密钥管理服务 API 进行交互,以创建加密密钥并将其引入服务。
在以下步骤中,您将为 Hyper Protect Crypto Services 服务实例创建 导入令牌。 通过根据您指定的策略创建导入令牌,可以在加密密钥传输到服务时对其启用额外安全性。
-
从命令行切换到新的
hs-crypto-test
目录。mkdir hs-crypto-test && cd hs-crypto-test
您将使用此目录来存储将在后续步骤中创建的文件。
-
您可以使用 密钥管理服务 API 或使用 CLI 为 Hyper Protect Crypto Services 服务实例创建导入令牌,然后将响应保存到 JSON 文件。
-
使用 API
curl -X POST $HPCS_API_URL/api/v2/import_token \ -H "Accept: application/vnd.ibm.collection+json" \ -H "Authorization: $ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -H "Bluemix-Instance: $INSTANCE_ID" \ -d '{ "expiration": 1200, "maxAllowedRetrievals": 1 }' > createImportTokenResponse.json
在请求主体中,可以对导入令牌指定基于时间和使用计数限制使用的策略。 在此示例中,您将导入令牌的到期时间设置为 1200 秒 (20 分钟),并且还允许在到期时间内仅检索一次该令牌。
-
使用 IBM Key Protect CLI
ibmcloud kp import-token create --instance-id $INSTANCE_ID --max-retrievals=1 --expiration=1200 -o json > createImportTokenResponse.json
-
-
查看导入令牌的详细信息。
jq '.' createImportTokenResponse.json
输出将显示与导入令牌关联的元数据,例如创建日期和策略详细信息。 以下片段显示了示例输出。
{ "creationDate": "2020-06-08T16:58:29Z", "expirationDate": "2020-06-08T17:18:29Z", "maxAllowedRetrievals": 1, "remainingRetrievals": 1 }
检索导入令牌
在上一步中,您创建了导入令牌,并查看了与该令牌关联的元数据。
在此步骤中,您将检索与导入令牌关联的公用密钥和现时标志值。 您将需要公用密钥以在后续步骤中加密数据,并需要现时标志以验证对 Hyper Protect Crypto Services 服务的安全导入请求。
要检索导入令牌内容:
-
检索先前步骤生成的导入令牌,然后将响应保存到 JSON 文件。
-
使用 API
curl -X GET $HPCS_API_URL/api/v2/import_token \ -H "Accept: application/vnd.ibm.collection+json" \ -H "Authorization: $ACCESS_TOKEN" \ -H "Bluemix-Instance: $INSTANCE_ID" > getImportTokenResponse.json
-
使用 IBM Key Protect CLI
ibmcloud kp import-token show -o json > getImportTokenResponse.json
-
-
可选: 检查导入令牌的内容。
jq '.' getImportTokenResponse.json
输出显示有关导入令牌的详细信息。 以下片段显示具有截断值的示例输出。
{ "creationDate": "2020-06-08T16:58:29Z", "expirationDate": "2020-06-08T17:18:29Z", "maxAllowedRetrievals": 1, "remainingRetrievals": 0, "payload": "MIICIjANBgkqhkiG...", "nonce": "8zJE9pKVdXVe/nLb" }
payload
值表示与导入令牌关联的公用密钥。 此值采用 base64 编码。 为了实现额外的安全性,Hyper Protect Crypto Services 提供了一个nonce
值,用于验证对服务的请求的原创性。 您需要在导入加密密钥时加密并提供此值。 -
将公用密钥解码并保存到名为
PublicKey.pem
的文件中,然后将值抽取到变量中以供以后使用。jq -r '.payload' getImportTokenResponse.json | openssl enc -base64 -A -d -out PublicKey.pem
HPCS_PUBKEY="$(jq -r '.payload' getImportTokenResponse.json)" NONCE="$(jq -r '.nonce' getImportTokenResponse.json)"
现在,公用密钥将以 PEM 格式下载到您的工作站。 继续执行下一步。
创建加密密钥
通过 Hyper Protect Crypto Services,您可以通过创建和上载自己的加密密钥以在 IBM Cloud上使用,从而启用“保留自己的密钥”(KYOK) 的安全优势。
在以下步骤中,您将在本地工作站上创建 256 位 AES 对称密钥。
本教程使用 OpenSSL 密码术工具箱来生成伪随机密钥,但您可能希望 探索不同的选项 以根据安全需求生成更强的密钥。 例如,您可能希望使用组织的内部密钥管理系统 (由内部部署硬件安全模块 (HSM) 支持) 来创建和导出密钥。
如果要创建 256 位 AES 对称密钥,请从命令行运行以下 openssl
命令:
openssl rand 32 > PlainTextKey.bin
如果在本教程中使用您自己的密钥,那么可以跳过此步骤。
成功! 您的加密密钥现在保存在名为 PlainTextKey.bin
的文件中。 继续执行下一步。
将加密密钥设置为环境变量
如果通过执行 步骤 3 来创建密钥,那么要对密钥进行编码并将编码后的值设置为环境变量,请执行以下命令。 如果在本教程中使用您自己的密钥,那么可以跳过此步骤:
KEY_MATERIAL=$(openssl enc -base64 -A -in PlainTextKey.bin)
使用加密密钥对现时标志进行加密
为了获得额外的安全性,Hyper Protect Crypto Services 在将加密密钥导入到服务时需要现时标志验证。
在密码术中,现时标志充当会话令牌,用于检查请求的原创性,以防止恶意攻击和未经授权的调用。 通过使用由 Hyper Protect Crypto Services分发的相同现时标志,可帮助确保上载密钥的请求有效。 必须使用要导入到服务中的相同密钥对现时标志值进行加密。
要加密现时标志值:
-
如果要使用 API 来执行后续步骤,请执行以下操作:
如果要使用 IBM Key Protect CLI,那么无需执行此步骤。
-
下载与您的操作系统兼容的样本
kms-encrypt-nonce
二进制文件。 解压缩该文件,然后将二进制文件移至hs-crypto-test
目录。二进制文件包含一个脚本,您可以使用在 步骤 2 中生成的密钥对现时标志值运行 AES-CBC 加密。 要了解有关该脚本的更多信息,请 查看 GitHub上的源文件。
-
如果您正在使用 Linux,请通过运行以下
chmod
命令将该文件标记为可执行文件。 如果使用的是 Windows,那么可以跳过此步骤。chmod +x ./kms-encrypt-nonce
-
运行脚本以使用您在 步骤 2 中生成的密钥对现时标志值进行加密。
-
-
将加密现时标志保存到名为
EncryptedValues.json
的文件中。-
使用 API
./kms-encrypt-nonce -key $KEY_MATERIAL -nonce $NONCE -alg "CBC" > EncryptedValues.json
-
使用 IBM Key Protect CLI
ibmcloud kp import-token nonce-encrypt --key "$KEY_MATERIAL" --nonce "$NONCE" --cbc -o json > EncryptedValues.json
-
-
可选: 检查 JSON 文件的内容。
jq '.' EncryptedValues.json
输出将显示需要为下一步提供的值。 以下片段显示具有截断值的示例输出。
{ "encryptedNonce": "DVy/Dbk37X8gSVwRA5U6vrHdWQy8T2ej+riIVw==", "iv": "puQrzDX7gU1TcTTx" }
encryptedNonce
值表示使用 OpenSSL生成的密钥打包 (或加密) 的原始现时标志。iv
值是由 AES-CBC 算法创建的初始化向量 (IV),稍后需要此值,以便 Hyper Protect Crypto Services可以成功解密现时标志。
对创建的加密密钥进行加密
接下来,使用 Hyper Protect Crypto Services 在 步骤 2 中分发的公用密钥来加密使用 OpenSSL创建的加密密钥。
-
使用 API 对创建的加密密钥进行加密,并将密钥分配给环境变量:
openssl pkeyutl \ -encrypt \ -pubin \ -keyform PEM \ -inkey PublicKey.pem \ -pkeyopt rsa_padding_mode:oaep \ -pkeyopt rsa_oaep_md:sha1 \ -in PlainTextKey.bin \ -out EncryptedKey.bin
ENCRYPTED_KEY=$(openssl enc -base64 -A -in EncryptedKey.bin)
如果在 Mac OSX 上运行
openssl
命令时迂到参数设置错误,那么可能需要确保为环境正确配置 OpenSSL。 如果使用 Homebrew 安装了 OpenSSL,请运行brew update
,然后运行brew install openssl
以获取最新版本。 然后,运行export PATH="/usr/local/opt/openssl/bin:$PATH"' >> ~/.bash_profile
以符号链接包。 从命令行运行which openssl && openssl version
以验证最新版本的 OpenSSL 是否在/usr/local/
位置下可用。 如果继续迂到错误,请确保仅使用本示例中列出的参数。 -
使用 IBM Key Protect CLI 对创建的加密密钥进行加密:
ibmcloud kp import-token key-encrypt -k "$KEY_MATERIAL" -p "$HPCS_PUBKEY" --hash SHA1 -o json > EncryptedKey.json ENCRYPTED_KEY=$(jq -r '.encryptedKey' EncryptedKey.json)
成功! 您都可以将加密密钥上载到 Hyper Protect Crypto Services。 继续执行下一步。
导入加密密钥
现在,您可以使用密钥管理服务 API 来导入加密密钥。
要导入加密密钥,请执行以下操作:
-
收集加密现时标志和初始化向量 (IV) 值。
ENCRYPTED_NONCE=$(jq -r '.encryptedNonce' EncryptedValues.json)
IV=$(jq -r '.iv' EncryptedValues.json)
-
将加密密钥存储在 Hyper Protect Crypto Services 服务实例中。
-
使用 API
curl -X POST $HPCS_API_URL/api/v2/keys \ -H "Accept: application/vnd.ibm.collection+json" \ -H "Authorization: $ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -H "Bluemix-Instance: $INSTANCE_ID" \ -d '{ "metadata": { "collectionType": "application/vnd.ibm.kms.key+json", "collectionTotal": 1 }, "resources": [ { "name": "encrypted-root-key", "type": "application/vnd.ibm.kms.key+json", "payload": "'"$ENCRYPTED_KEY"'", "extractable": false, "encryptionAlgorithm": "RSAES_OAEP_SHA_1", "encryptedNonce": "'"$ENCRYPTED_NONCE"'", "iv": "'"$IV"'" } ] }' > createRootKeyResponse.json
在请求主体中,提供在上一步中准备的加密密钥。 您还提供验证请求所需的加密现时标志和 IV 值。 最后,设置为
false
的extractable
值将新密钥指定为服务中可用于包络加密的根密钥。如果 API 请求由于导入令牌到期错误而失败,请 返回到步骤 1 以创建新的导入令牌。 请记住,根据您在创建时指定的策略,导入令牌及其关联的公用密钥将到期。
-
使用 IBM Key Protect CLI
ibmcloud kp key create new-imported-key --key-material "$ENCRYPTED_KEY" --encrypted-nonce "$ENCRYPTED_NONCE" --iv "$IV" --sha1 -o json > createRootKeyResponse.json
在后台,Hyper Protect Crypto Services 通过 TLS 1.2 连接接收加密包。 在硬件安全模块中,系统使用专用密钥来解密对称密钥。 最后,系统使用对称密钥和 IV 对现时标志进行解密并验证请求。 您的密钥现在存储在经过 FIPS 140-$tag1 级别 4 验证的防篡改硬件安全模块中。
-
-
查看密钥的详细信息。
jq '.' createRootKeyResponse.json
以下片段显示了示例输出。
{ "metadata": { "collectionType": "application/vnd.ibm.kms.key+json", "collectionTotal": 1 }, "resources": [ { "id": "644cba65-e240-471f-8b84-14115447d2ae", "type": "application/vnd.ibm.kms.key+json", "name": "encrypted-root-key", "state": 1, "crn": "crn:v1:bluemix:public:hs-crypto:us-south:a/f047b55a3362ac06afad8a3f2f5586ea:346d9f67-4bb2-481e-a3e1-3c2c646aa886:key:644cba65-e240-471f-8b84-14115447d2ae", "extractable": false, "imported": true } ] }
-
id
值是分配给密钥的唯一标识,用于后续调用密钥管理服务 API。 -
设置为 1 的
state
值指示您的密钥现在处于 活动密钥状态。 -
crn
值提供了指定资源位于 IBM Cloud中的位置的键的完整作用域路径。 -
最后,
extractable
和imported
值将此资源描述为您导入到服务的根密钥。 将extractable
属性设置为true
时,服务会将该密钥指定为可以存储在应用程序或服务中的标准密钥。 否则,当您将extractable
属性设置为false
时,服务会将该密钥指定为根密钥。
-
-
可选: 浏览至 Hyper Protect Crypto Services 仪表板以查看和管理密钥。
清除
-
收集在上一步中导入的加密密钥的标识。
ROOT_KEY_ID=$(jq -r '.resources[].id' createRootKeyResponse.json)
-
从 Hyper Protect Crypto Services 服务实例中除去加密密钥。
-
使用 API
curl -X DELETE $HPCS_API_URL/api/v2/keys/$ROOT_KEY_ID \ -H "Accept: application/vnd.ibm.collection+json" \ -H "Authorization: $ACCESS_TOKEN" \ -H "Bluemix-Instance: $INSTANCE_ID" | jq .
-
使用 IBM Key Protect CLI
ibmcloud kp key delete {ROOT_KEY_ID}
-
-
除去与本教程关联的所有本地文件。
rm kms-encrypt-nonce *.json *.bin *.pem
-
删除您为此教程创建的测试目录。
cd .. && rm -r hs-crypto-test
-
可选: 除去 Hyper Protect Crypto Services 服务实例。
ibmcloud resource service-instance-delete import-keys-demo
如果在服务实例中创建了更多测试密钥,请确保在取消供应该实例之前 从服务实例中除去所有加密密钥。
后续步骤
在本教程中,您学习了如何设置 Hyper Protect Crypto Services 密钥管理服务 API,创建加密密钥以及安全地将加密密钥导入到 Hyper Protect Crypto Services 服务实例中。
- 了解有关 使用根密钥保护静态数据 的更多信息。
- 跨 受支持的云服务 部署根密钥。
- 了解有关 密钥管理服务 API 的更多信息。