阿里云密钥管理服务KMS(Key Management Service)新增了专属KMS产品形态,可以为您提供租户侧独享存储和密钥运算的密钥管理服务,提高使用安全性。本文介绍如何将KMS密钥迁移到专属KMS。
迁移的内容
重要 如果不做迁移,您可以继续使用阿里云KMS,但您将无法提高密钥配额和QPS。
迁移内容 | 说明 |
---|---|
密钥 | 您只需要迁移用户主密钥CMK,不需要迁移服务托管的密钥。阿里云会继续支持用户通过免费的方式使用服务托管的密钥,用于云产品的默认加密能力。 说明 以acs/云产品为别名的都是服务托管的密钥。 |
业务应用 | 如果您的密钥只在阿里云云产品做加密使用,无需进行业务应用的迁移。如果密钥在您自己管理的业务应用中被使用,您需要将网关从KMS网关切换到专属KMS私有网关。
重要 阿里云将在您所有密钥迁移到专属KMS的1个月后关闭KMS网关入口,您将只能通过专属KMS私有网关调用,请务必在密钥迁移后的1个月内完成业务应用的迁移。 |
迁移流程
步骤一:判断密钥和业务应用是否可以迁移
如果密钥或者业务应用经判断不支持迁移,您无需关注本文档剩余内容,可以继续使用阿里云KMS。
说明 如果您的密钥只在云产品中做加密使用,只需要判断密钥是否迁移,不需要判断业务应用是否需要迁移。如果您的密钥在业务应用中使用,则需要判断密钥和业务应用是否都可以迁移。
判断密钥是否可以迁移
- 方式一:通过用户主密钥迁移判断工具进行判断(推荐)
- 登录密钥管理服务控制台。
- 单击用户主密钥,在用户主密钥页面的上方单击主密钥迁移判断工具。
- 仔细阅读提示信息后单击确定,工具会给出判断结果及详情。
- 方式二:根据如下信息自行判断如下类型的用户主密钥,暂不支持迁移专属KMS。
不支持迁移的密钥 说明 多版本密钥 目前仅支持迁移有且仅有一个版本的密钥,对于存在多个版本的密钥暂不支持迁移。 开启轮转的密钥 对于开启了自动轮转但目前仅有一个版本的密钥,在关闭密钥轮转后仍可以迁移。 BYOK密钥 BYOK密钥暂不支持迁移,您可以自行将密钥材料导入到专属KMS构建相同的密钥。
判断业务应用是否可以迁移
如果密钥在您自己管理的业务应用中被使用,请根据业务实际情况从以下三方面判断业务应用是否可以迁移。同时满足条件时,业务应用才支持迁移。
条件 | 说明 |
---|---|
根据密码运算API判断是否支持迁移 | 如果您的业务应用使用了ReEncrypt(转加密)、ExportDataKey(数据密钥导出)、GenerateAndExportDataKey(生成数据密钥)密钥运算API,暂时无法迁移到专属KMS。 |
根据应用网络位置判断是否支持迁移 | 专属KMS部署在您的私有VPC内,其中基础版实例部署在启动时您指定的VPC,标准版实例与HSM集群部署在同一个VPC。当应用和专属KMS实例的网络位置属于如下情况之一时支持迁移。
|
根据应用开发语言判断是否支持迁移 | 目前提供Java、Go、Python三种语言类型的迁移SDK,以支持您将业务应用以较少的代码改动完成从KMS迁移至专属KMS。如果您的业务应用使用其他语言开发,暂不支持迁移至专属KMS,您可以通过智能在线联系技术支持人员反馈需求。 |
步骤二:选择专属KMS版本
您可以通过查看专属KMS基础版和标准版之间的差异,根据业务需要选择合适的专属KMS版本。具体信息,请参见专属KMS基础版和标准版的差异。
步骤三:迁移密钥
步骤四:迁移业务应用
如果您的密钥只在云产品中做加密使用,不需要执行本步骤。如果您的密钥在业务应用中使用,您需要在密钥迁移完成后的1个月内完成业务应用的迁移。
- 为实例创建应用接入点,并保存Client Key、CA证书。具体操作,请参见基础版快速入门和标准版快速入门。
- 对应用进行改造升级,将网关从KMS切换到专属KMS。
改造示例(JAVA)
导入Maven依赖
<!-- add dkms sdk dependency --> <dependency> <groupId>com.aliyun</groupId> <artifactId>alibabacloud-dkms-gcs-sdk</artifactId> <version>x.x.x</version> </dependency> <dependency> <groupId>com.aliyun.kms</groupId> <artifactId>kms-transfer-client</artifactId> <version>x.x.x</version> </dependency>
说明 SDK的最新版本,请参见alibabacloud-dkms-gcs-java-sdk和alibabacloud-dkms-transfer-java-sdk。代码改造
改造前业务代码示例:import com.aliyuncs.DefaultAcsClient; import com.aliyuncs.IAcsClient; import com.aliyuncs.exceptions.ClientException; import com.aliyuncs.exceptions.ServerException; import com.aliyuncs.profile.DefaultProfile; import com.google.gson.Gson; import java.util.*; import com.aliyuncs.kms.model.v20160120.*; public class Encrypt { public static void main(String[] args) { DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", "<your-access-key-id>", "<your-access-key-secret>"); IAcsClient client = new DefaultAcsClient(profile); // 设置 request 参数 EncryptRequest request = new EncryptRequest(); request.setProtocol(ProtocolType.HTTPS); request.setAcceptFormat(FormatType.JSON); request.setMethod(MethodType.POST); request.setKeyId(<keyId>); request.setPlaintext(plainText); try { EncryptResponse response = client.getAcsResponse(request); System.out.println(new Gson().toJson(response)); } catch (ServerException e) { e.printStackTrace(); } catch (ClientException e) { System.out.println("ErrCode:" + e.getErrCode()); System.out.println("ErrMsg:" + e.getErrMsg()); System.out.println("RequestId:" + e.getRequestId()); } } }
改造后业务代码示例:import com.aliyun.kms.KmsTransferAcsClient; import com.aliyun.dkms.gcs.openapi.models.Config; import com.aliyuncs.IAcsClient; import com.aliyuncs.exceptions.ClientException; import com.aliyuncs.exceptions.ServerException; import com.aliyuncs.profile.DefaultProfile; import com.google.gson.Gson; import java.util.*; import com.aliyuncs.kms.model.v20160120.*; public class Encrypt { public static void main(String[] args) { DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", "<your-access-key-id>", "<your-access-key-secret>"); Config config = new Config(); //连接协议,固定为HTTPS。 config.setProtocol("https"); //专属KMS实例Client Key。 config.setClientKeyFile("<your-client-key-file>"); //专属KMS实例Client Key解密口令。 config.setPassword("<your client key password>"); //Endpoint,专属KMS实例服务地址去掉https://。 config.setEndpoint("<service_id>.cryptoservice.kms.aliyuncs.com"); IAcsClient client = new KmsTransferAcsClient(profile, config); // 设置 request 参数 EncryptRequest request = new EncryptRequest(); request.setProtocol(ProtocolType.HTTPS); request.setAcceptFormat(FormatType.JSON); request.setMethod(MethodType.POST); request.setKeyId(<keyId>); request.setPlaintext(plainText); try { EncryptResponse response = client.getAcsResponse(request); System.out.println(new Gson().toJson(response)); } catch (ServerException e) { e.printStackTrace(); } catch (ClientException e) { System.out.println("ErrCode:" + e.getErrCode()); System.out.println("ErrMsg:" + e.getErrMsg()); System.out.println("RequestId:" + e.getRequestId()); } } }
改造示例(Python)
安装增加依赖包
- 如果您使用python3安装命令如下:
$ pip install alibabacloud-dkms-gcs $ pip install alibabacloud-dkms-transfer-python
- 如果您使用python2安装命令如下:
$ pip install alibabacloud-dkms-gcs-python2 $ pip install alibabacloud-dkms-transfer-python2
代码改造
改造前业务代码示例:
from aliyunsdkcore.auth.credentials import AccessKeyCredential from aliyunsdkcore.client import AcsClient from aliyunsdkkms.request.v20160120.EncryptRequest import EncryptRequest def encrypt(): credentials = AccessKeyCredential('<your-access-key-id>', '<your-access-key-secret>') client = AcsClient(region_id="<your-region-id>", credential=credentials) request = EncryptRequest() request.set_accept_format('json') request.set_KeyId("<your-key-id>") request.set_Plaintext("<your-plaintext>") response = client.do_action_with_exception(request) print(str(response, encoding='utf-8')) encrypt()
改造后业务代码示例:
from alibabacloud_dkms_transfer.kms_transfer_acs_client import KmsTransferAcsClient from aliyunsdkcore.auth.credentials import AccessKeyCredential from aliyunsdkkms.request.v20160120.EncryptRequest import EncryptRequest from openapi.models import Config def encrypt(): config = Config() config.protocol = "https" config.client_key_file = "<your-client-key-file-path>" config.password = "<your-password>" config.endpoint = "<your-endpoint>" credentials = AccessKeyCredential('<your-access-key-id>', '<your-access-key-secret>') client = KmsTransferAcsClient(config=config, credential=credentials, verify='<your-ca-certificate-file-path>') request = EncryptRequest() request.set_KeyId("<your-key-id>") request.set_Plaintext("<your-plaintext>") response = client.do_action_with_exception(request) print(str(response, encoding='utf-8')) encrypt()
- 如果您使用python3安装命令如下:
改造示例(Go)
使用如下方式之一安装依赖包:
- 使用go mod管理您的依赖:
require ( github.com/aliyun/alibabacloud-dkms-transfer-go-sdk vX.X.X github.com/aliyun/alibabacloud-dkms-gcs-go-sdk vX.X.X github.com/alibabacloud-go/tea vX.X.X )
- 通过go get命令获取远程代码包:
$ go get -u github.com/aliyun/alibabacloud-dkms-transfer-go-sdk $ go get -u github.com/aliyun/alibabacloud-dkms-gcs-go-sdk $ go get -u github.com/alibabacloud-go/tea
说明 SDK的最新版本,请参见alibabacloud-dkms-gcs-go-sdk和alibabacloud-dkms-transfer-go-sdk。
代码改造
改造前业务代码示例:import ( "fmt" "github.com/aliyun/alibaba-cloud-sdk-go/services/kms" ) func main() { client, err := kms.NewClientWithAccessKey("<your-region-id>", "<your-access-key-id>", "<your-access-key-secret>") if err != nil { panic(err) } request := kms.CreateEncryptRequest() request.Scheme = "https" request.KeyId = "<your cmk id>" request.Plaintext = "<your plaintext>" response, err := client.Encrypt(request) if err != nil { panic(err) } fmt.Println(response) }
改造后业务代码示例:import ( "fmt" "github.com/alibabacloud-go/tea/tea" "github.com/aliyun/alibaba-cloud-sdk-go/services/kms" dedicatedkmsopenapi "github.com/aliyun/alibabacloud-dkms-gcs-go-sdk/openapi" "github.com/aliyun/alibabacloud-dkms-transfer-go-sdk/sdk" ) func main() { config := &dedicatedkmsopenapi.Config{ Protocol: tea.String("https"), ClientKeyFile: tea.String("<your-client-key-file>"), Password: tea.String("<your-client-key-password>"), Endpoint: tea.String("<your-dkms-instance-service-endpoint>"), } client, err := sdk.NewClientWithAccessKey("<your-region-id>", "<your-access-key-id>", "<your-access-key-secret>", config) if err != nil { panic(err) } request := kms.CreateEncryptRequest() request.KeyId = "<your cmk id>" request.Plaintext = "<your plaintext>" response, err := client.Encrypt(request) if err != nil { panic(err) } fmt.Println(response) }
- 使用go mod管理您的依赖: