操作指南

最近更新时间:2019-11-05 15:06:21

操作流程

创建外部密钥 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 = alias
              req.Type = 2
              rsp = client.CreateKey(req)
              return rsp, None
          except 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 = keyid
        req.WrappingAlgorithm = 'RSAES_PKCS1_V1_5' # RSAES_PKCS1_V1_5 | RSAES_OAEP_SHA_1 | RSAES_OAEP_SHA_256
        req.WrappingKeySpec =  'RSA_2048' # RSA_2048       
        rsp = self.client.GetParametersForImport(req)
        return rsp, None
    except 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:导入密钥材料

最后,将加密后的密钥材料及 步骤2 获取的导入令牌,通过 API 操作,一起导入至 步骤1 创建的外部密钥 CMK中。

  • 导入令牌与加密密钥材料的公钥具有绑定关系,同时一个令牌只能为其生成时指定的主密钥导入密钥材料。导入令牌的有效期为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 = material
        req.ImportToken = token
        req.KeyId = keyid
        rsp = client.ImportKeyMaterial(req)
        return rsp, None
    except 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 = keyid
        rsp = client.DeleteImportedKeyMaterial(req)
        return rsp, None
    except TencentCloudSDKException as err:
        return None, err
注意:

  • 当您将密钥材料导入 CMK 时,该 CMK 与该密钥材料永久关联,即不能将其他密钥材料导入该外部密钥 CMK 中。当您删除密钥材料后,若需要重新导入密钥材料,导入的密钥材料必须与删除的密钥材料完全相同,才能导入成功。
  • 当使用外部密钥 CMK 加密数据时,加密后的数据必须使用加密时采用的 CMK(即 CMK 的元数据及密钥材料与导入的密钥匹配)才能解密数据,否则解密会失败。请谨慎处理密钥材料、CMK 的删除操作。