全部產品
Search
文件中心

Key Management Service:使用KMS主要金鑰線上加密和解密資料

更新時間:Jul 06, 2024

阿里雲使用者在雲上部署IT資產,需要對敏感性資料進行加密保護。如果被加密的資料對象較小(小於6 KB),則可以通過Key Management Service(Key Management Service)的密碼運算API,線上對資料直接加解密。本文以加密SSL認證私密金鑰為例,介紹如何調用KMS API實現對資料的線上加密和解密。

背景資訊

典型的使用情境包括(但不限於):

  • 對設定檔的加密

  • 對SSL私密金鑰的加密

產品架構

使用者的資料會通過安全通道傳遞到KMS服務端,服務端完成加密和解密後,操作結果通過安全通道返回給使用者。具體架構如下圖所示。使用KMS主要金鑰線上加密和解密資料_網路架構圖 操作流程如下:

  1. 通過KMS控制台或者調用CreateKey介面,建立一個使用者主要金鑰(CMK)。

  2. 調用KMS服務的Encrypt介面,將明文認證加密為密文認證。

  3. 將密文認證部署在雲端服務器上。

  4. 當伺服器啟動需要使用認證時,調用KMS服務的Decrypt介面將密文認證解密為明文認證。

相關API

您可以調用以下KMS API,完成對資料的加密或解密操作。

API名稱

說明

CreateKey

建立使用者主要金鑰(CMK)。

CreateAlias

為指定使用者主要金鑰建立一個別名。

Encrypt

指定CMK,由KMS加密資料。

Decrypt

解密KMS直接加密的資料,不需要指定CMK。

加密/解密認證密鑰

說明

阿里雲帳號AccessKey擁有所有OpenAPI的存取權限,建議您使用RAM使用者進行API訪問或日常營運。強烈建議不要把AccessKey ID和AccessKey Secret儲存到工程代碼裡,否則可能導致AccessKey泄露,威脅您帳號下所有資源的安全。

本樣本以將AccessKey配置在環境變數ALIBABA_CLOUD_ACCESS_KEY_ID和ALIBABA_CLOUD_ACCESS_KEY_SECRET的方式來實現身分識別驗證為例。

  1. 調用CreateKey,建立使用者主要金鑰。

    aliyun kms CreateKey

    預期輸出:

    {
      "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"
    }
  2. 可選:給主要金鑰添加別名(推薦步驟)。

    別名是使用者主要金鑰的可選標識。如果使用者不建立別名,也可以直接使用密鑰的ID。

    aliyun kms CreateAlias --AliasName alias/Apollo/WorkKey --KeyId 1234abcd-12ab-34cd-56ef-12345678****
    說明

    其中,Apollo/WorkKey表示Apollo專案中的工作密鑰(當前被用於加密的密鑰),並在後續範例程式碼中使用此別名。即表示應用可以使用alias/Apollo/WorkKey調用加密API。

  3. 加密認證私密金鑰(業務系統對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)
  4. 解密認證私密金鑰(業務系統對部署在雲上的密文認證私密金鑰進行解密)。

    範例程式碼中:

    • 部署的密文認證檔案:./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)