操作流程
创建外部密钥 CMK,您可以通过以下4个步骤完成操作。
1. 通过控制台或 API 创建一个密钥来源为“外部”的用户主密钥 CMK,即创建外部密钥 CMK。
2. 通过 API 操作获取密钥材料导入的参数,包括一个用于加密密钥材料的公钥,以及一个导入令牌。
3. 在本地通过加密机或其他安全的加密措施,利用步骤2获取的加密公钥对您的密钥材料进行加密。
4. 通过 API 操作,将加密后的密钥材料及步骤2获取的导入令牌,导入创建的外部密钥 CMK 中,至此导入外部密钥完成。
操作步骤
步骤1:创建外部密钥 CMK
创建外部密钥 CMK 有两种方式,控制台方式和调用 API 的方式。
控制台方式
(1)登录 密钥管理系统(合规) 控制台。
(2)选择需要创建密钥的区域,单击新建开始创建密钥。
(3)在新建密钥窗口,输入密钥名称,选择密钥材料来源为外部,阅读导入外部密钥材料的方法及注意事项并勾选确认框。

(4)单击确定,即可创建外部密钥 CMK。您可在控制台看到已创建的外部密钥 CMK,“密钥来源”显示为“外部”。
调用 API 方式
本文示例使用腾讯云 命令行工具 TCCLI ,后续您可以使用任何受支持的编程语言调用。
请求 CreateKey API 时指定参数 Type为2,执行命令如下。
tccli kms CreateKey --Alias <alias> --Type 2
CreateKey 函数源码示例:
def create_external_key(client, alias):"""生成 BYOK 密钥,:param Type = 2"""try:req = models.CreateKeyRequest()req.Alias = aliasreq.Type = 2rsp = client.CreateKey(req)return rsp, Noneexcept TencentCloudSDKException as err:return None, err
步骤2:获取导入密钥材料参数
为确保密钥材料的安全性,需要先对您的密钥材料进行加密后再导入。您可以通过 API 获取导入密钥材料的参数,其中包括一个用于加密密钥材料的公钥,以及一个导入令牌。
通过 TCCLI 执行命令如下:
tccli kms GetParametersForImport --KeyId <keyid> --WrappingAlgorithm RSAES_PKCS1_V1_5 --WrappingKeySpec RSA_2048
GetParametersForImport 函数源码示例:
def get_parameters_for_import(client, keyid):"""获取导入主密钥(CMK)材料的参数,返回的Token作为执行ImportKeyMaterial的参数之一,返回的PublicKey用于对自主导入密钥材料进行加密。返回的Token和PublicKey 24小时后失效,失效后如需重新导入,需要再次调用该接口获取新的 Token 和 PublicKey。WrappingAlgorithm 指定加密密钥材料的算法,目前支持 RSAES_PKCS1_V1_5、RSAES_OAEP_SHA_1、RSAES_OAEP_SHA_256。WrappingKeySpec 指定加密密钥材料的类型,目前只支持 RSA_2048。"""try:req = models.GetParametersForImportRequest()req.KeyId = keyidreq.WrappingAlgorithm = 'RSAES_PKCS1_V1_5' # RSAES_PKCS1_V1_5 | RSAES_OAEP_SHA_1 | RSAES_OAEP_SHA_256req.WrappingKeySpec = 'RSA_2048' # RSA_2048rsp = self.client.GetParametersForImport(req)return rsp, Noneexcept TencentCloudSDKException as err:return None, err
步骤3:本地加密您的密钥材料
在本地利用 步骤2 获取的加密公钥对您的密钥材料进行加密。加密公钥是一个2048比特的 RSA 公钥,使用的加密算法需要与获取导入密钥材料参数时指定的一致。 由于 API 返回的加密公钥经过 base64 编码,因此在使用时需要先进行 base64 解码。目前 KMS 支持的加密算法有 RSAES_OAEP_SHA_1、RSAES_OAEP_SHA_256 与 RSAES_PKCS1_V1_5。
以下为通过 openssl 加密密钥材料的测试示例。在实际使用中,建议您通过加密机或其他更为安全的加密措施对密钥材料进行加密。
(1)调用 GetParametersForImport 接口获取Token 和 PublicKey。将 PublicKey 写入文件 public_key.base64。
(2)使用 openssl 生成随机数。
openssl rand -out raw_material.bin 16
您也可以通过 GenerateRandom 生成随机数进行 base64 解码。
注意
国密版本 key material 长度必须为 128, FIPS 版本为 256。
(3)Decode Public Key 获取公钥原文。
openssl enc -d -base64 -A -in public_key.base64 -out public_key.bin
(4)使用公钥对 key material 进行加密。
# RSAES_OAEP_SHA_1 对应的命令行如下openssl pkeyutl -in raw_material.bin -out encrypted_key_material.bin -inkey public_key.bin -keyform DER -pubin -encrypt -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha1# RSAES_PKCS1_V1_5 对应的命令行如下openssl pkeyutl -in raw_material.bin -out encrypted_key_material.bin -inkey public_key.bin -keyform DER -pubin -encrypt -pkeyopt rsa_padding_mode:pkcs1# RSAES_OAEP_SHA_256 对应的命令行如下openssl pkeyutl -in raw_material.bin -out encrypted_key_material.bin -inkey public_key.bin -keyform DER -pubin -encrypt -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha256
(5)将密文编码后作为参数可以导入 KMS。
openssl enc -e -base64 -A -in encrypted_key_material.bin -out encrypted_material.base64
encrypted_material.base64 为最终输出,作为 EncryptedKeyMaterial 导入 KMS。
步骤4:导入密钥材料
导入令牌与加密密钥材料的公钥具有绑定关系,同时一个令牌只能为其生成时指定的主密钥导入密钥材料。导入令牌的有效期为24小时,在有效期内可以重复使用,失效以后需要获取新的导入令牌和加密公钥。
如果多次调用 GetParametersForImport 获取导入材料,只有最后一次调用的 token 和 publicKey 有效,历史调用返回的将自动过期。
可以为从未导入过密钥材料的外部密钥导入密钥材料,也可以重新导入已经过期和已被删除的密钥材料,或者重置密钥材料的过期时间。
请求通过 ImportKeyMaterial 来导入,命令示例如下:
tccli kms ImportKeyMaterial --EncryptedKeyMaterial <material> --ImportToken <token> --KeyId <keyid>
ImportKeyMaterial 函数源码示例:
def import_key_material(client, material, token, keyid):try:req = models.ImportKeyMaterialRequest()req.EncryptedKeyMaterial = materialreq.ImportToken = tokenreq.KeyId = keyidrsp = client.ImportKeyMaterial(req)return rsp, Noneexcept TencentCloudSDKException as err:return None, err
至此,导入外部密钥操作完成。您可以像使用普通密钥一样使用外部密钥 CMK。
更多操作
删除外部密钥 CMK
外部密钥 CMK 的删除操作涉及到两类操作,一类操作为计划删除 CMK,一类操作为删除密钥材料,两类操作将会有不同的操作效果。
计划删除 CMK
通过计划删除功能,删除外部密钥 CMK。计划删除的操作强制要求有7 - 30天的等待期,当达到到期时间后,外部密钥CMK 将被彻底删除。已经删除的 CMK 将无法恢复,通过其加密的数据也将无法解密,请谨慎操作。
删除密钥材料
您可以通过两种方式删除密钥材料。当密钥材料过期或者被删除以后,外部密钥 CMK 将无法继续使用,由该 CMK 加密的密文也无法被解密,除非您重新导入相同的密钥材料。
通过 API 操作 DeleteImportedKeyMaterial 完成。当操作删除密钥材料后,密钥状态将变为等待导入(PendingImport)。
在导入密钥材料 API 操作中,将 ImportKeyMaterial 设置 ValidTo 输入参数设置过期时间完成,KMS 服务将自动删除到达过期时间的密钥材料。
说明
等待密钥材料到期失效与手动删除密钥材料所达到的效果是一样的。
删除密钥材料,执行命令如下:
tccli DeleteImportedKeyMaterial --KeyId <keyid>
DeleteImportedKeyMaterial 函数源码示例:
def delete_key_material(client, keyid):try:req = models.DeleteImportedKeyMaterialRequest()req.KeyId = keyidrsp = client.DeleteImportedKeyMaterial(req)return rsp, Noneexcept TencentCloudSDKException as err:return None, err
注意
当您将密钥材料导入 CMK 时,该 CMK 与该密钥材料永久关联,即不能将其他密钥材料导入该外部密钥 CMK 中。当您删除密钥材料后,若需要重新导入密钥材料,导入的密钥材料必须与删除的密钥材料完全相同,才能导入成功。
当使用外部密钥 CMK 加密数据时,加密后的数据必须使用加密时采用的 CMK(即 CMK 的元数据及密钥材料与导入的密钥匹配)才能解密数据,否则解密会失败。请谨慎处理密钥材料、CMK 的删除操作。