使用KMS主密鑰在線加密和解密數(shù)據(jù)
阿里云用戶在云上部署IT資產(chǎn),需要對敏感數(shù)據(jù)進行加密保護。如果被加密的數(shù)據(jù)對象較小(小于6 KB),則可以通過密鑰管理服務(wù)KMS(Key Management Service)的密碼運算API,在線對數(shù)據(jù)直接加解密。本文以加密SSL證書私鑰為例,介紹如何調(diào)用KMS API實現(xiàn)對數(shù)據(jù)的在線加密和解密。
背景信息
典型的使用場景包括(但不限于):
對配置文件的加密
對SSL私鑰的加密
產(chǎn)品架構(gòu)
用戶的數(shù)據(jù)會通過安全信道傳遞到KMS服務(wù)端,服務(wù)端完成加密和解密后,操作結(jié)果通過安全信道返回給用戶。具體架構(gòu)如下圖所示。 操作流程如下:
通過KMS控制臺或者調(diào)用CreateKey接口,創(chuàng)建一個用戶主密鑰(CMK)。
調(diào)用KMS服務(wù)的Encrypt接口,將明文證書加密為密文證書。
將密文證書部署在云服務(wù)器上。
當(dāng)服務(wù)器啟動需要使用證書時,調(diào)用KMS服務(wù)的Decrypt接口將密文證書解密為明文證書。
相關(guān)API
您可以調(diào)用以下KMS API,完成對數(shù)據(jù)的加密或解密操作。
API名稱 | 說明 |
創(chuàng)建用戶主密鑰(CMK)。 | |
為指定用戶主密鑰創(chuàng)建一個別名。 | |
指定CMK,由KMS加密數(shù)據(jù)。 | |
解密KMS直接加密的數(shù)據(jù),不需要指定CMK。 |
加密/解密證書密鑰
阿里云賬號AccessKey擁有所有OpenAPI的訪問權(quán)限,建議您使用RAM用戶進行API訪問或日常運維。強烈建議不要把AccessKey ID和AccessKey Secret保存到工程代碼里,否則可能導(dǎo)致AccessKey泄露,威脅您賬號下所有資源的安全。
本示例以將AccessKey配置在環(huán)境變量ALIBABA_CLOUD_ACCESS_KEY_ID和ALIBABA_CLOUD_ACCESS_KEY_SECRET的方式來實現(xiàn)身份驗證為例。
更多認(rèn)證信息配置方式,請參見客戶端與憑證。
不同操作系統(tǒng)的環(huán)境變量配置方法不同,具體操作,請參見在Linux、macOS和Windows系統(tǒng)配置環(huán)境變量。
調(diào)用CreateKey,創(chuàng)建用戶主密鑰。
aliyun kms CreateKey
預(yù)期輸出:
{ "KeyMetadata": { "CreationDate": "2019-04-08T07:45:54Z", "Description": "", "KeyId": "1234abcd-12ab-34cd-56ef-12345678****", "KeyState": "Enabled", "KeyUsage": "ENCRYPT/DECRYPT", "DeleteDate": "", "Creator": "151266687691****", "Arn": "acs:kms:cn-hangzhou:151266687691****:key/1234abcd-12ab-34cd-56ef-12345678****", "Origin": "Aliyun_KMS", "MaterialExpireTime": "" }, "RequestId": "2a37b168-9fa0-4d71-aba4-2077dd9e80df" }
可選:給主密鑰添加別名(推薦步驟)。
別名是用戶主密鑰的可選標(biāo)識。如果用戶不創(chuàng)建別名,也可以直接使用密鑰的ID。
aliyun kms CreateAlias --AliasName alias/Apollo/WorkKey --KeyId 1234abcd-12ab-34cd-56ef-12345678****
說明其中,
Apollo/WorkKey
表示Apollo項目中的工作密鑰(當(dāng)前被用于加密的密鑰),并在后續(xù)示例代碼中使用此別名。即表示應(yīng)用可以使用alias/Apollo/WorkKey
調(diào)用加密API。加密證書私鑰(業(yè)務(wù)系統(tǒng)對SSL私鑰證書進行加密保護)。
示例代碼中:
用戶主密鑰別名:
alias/Apollo/WorkKey
。明文證書文件:./certs/key.pem。
輸出的密文證書文件:./certs/key.pem.cipher。
#!/usr/bin/env python #coding=utf-8 import json from aliyunsdkcore import client from aliyunsdkkms.request.v20160120 import EncryptRequest from aliyunsdkkms.request.v20160120 import DecryptRequest def KmsEncrypt(client, plaintext, key_alias): request = EncryptRequest.EncryptRequest() request.set_accept_format('JSON') request.set_KeyId(key_alias) request.set_Plaintext(plaintext) response = json.loads(client.do_action(request)) return response.get("CiphertextBlob") def ReadTextFile(in_file): file = open(in_file, 'r') content = file.read() file.close() return content def WriteTextFile(out_file, content): file = open(out_file, 'w') file.write(content) file.close() clt = client.AcsClient(os.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"),os.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"),'<Region-Id>') key_alias = 'alias/Apollo/WorkKey' in_file = './certs/key.pem' out_file = './certs/key.pem.cipher' # Read private key file in text mode in_content = ReadTextFile(in_file) # Encrypt ciphertext = KmsEncrypt(clt, in_content, key_alias) # Write encrypted key file in text mode WriteTextFile(out_file, ciphertext)
解密證書私鑰(業(yè)務(wù)系統(tǒng)對部署在云上的密文證書私鑰進行解密)。
示例代碼中:
部署的密文證書文件:./certs/key.pem.cipher。
輸出的明文證書文件:./certs/decrypted_key.pem。
#!/usr/bin/env python #coding=utf-8 import json from aliyunsdkcore import client from aliyunsdkkms.request.v20160120 import EncryptRequest from aliyunsdkkms.request.v20160120 import DecryptRequest def KmsDecrypt(client, ciphertext): request = DecryptRequest.DecryptRequest() request.set_accept_format('JSON') request.set_CiphertextBlob(ciphertext) response = json.loads(client.do_action(request)) return response.get("Plaintext") def ReadTextFile(in_file): file = open(in_file, 'r') content = file.read() file.close() return content def WriteTextFile(out_file, content): file = open(out_file, 'w') file.write(content) file.close() clt = client.AcsClient(os.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"),os.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"),'<Region-Id>') in_file = './certs/key.pem.cipher' out_file = './certs/decrypted_key.pem' # Read encrypted key file in text mode in_content = ReadTextFile(in_file) # Decrypt ciphertext = KmsDecrypt(clt, in_content) # Write Decrypted key file in text mode WriteTextFile(out_file, ciphertext)