Alibaba Cloud にデプロイされた IT 資産の機密情報を暗号化する必要があります。 エンベロープ暗号化では、Key Management Service (KMS) によって生成されたデータキーを使用して、大量のローカルデータを暗号化できます。 Key Management Service (KMS) の対応する暗号化操作を呼び出して、オンラインでデータキーペアを生成し、そのデータキーペアを使用してローカルデータを暗号化および復号化できます。 この暗号化メカニズムは、エンベロープ暗号化と呼ばれます。
シナリオ
エンベロープ暗号化は、以下のような多くのシナリオで使用できますが、これらに限定されません。
- ビジネスデータファイルの暗号化
- ローカルディスクに保存されているすべてのデータの暗号化
エンベロープ暗号化の仕組み
KMS を使用して Customer Master Key (CMK) を作成し、CMK を使用してデータキーペアを生成します。次に、プレーンテキストデータキーを使用してローカルファイルを暗号化します。
エンベロープ暗号化は、大量のデータの暗号化に適しています。 次の図は、エンベロープ暗号化手順の全体を示しています。
- エンベロープ暗号化操作手順 :
- KMS コンソールを使用するか、CreateKey 操作を呼び出して CMK を作成します。
- KMS の GenerateDataKey 操作を呼び出して、データキーペアを生成します。 KMS は、データキーペア (プレーンテキストデータキーと暗号文データキー) を返します。
- プレーンテキストデータキーを使用してローカルファイルを暗号化し、RAM (Random Access Memory) に格納されているプレーンテキストデータキーを削除します。
- 暗号文データキーと暗号化されたデータファイルをストレージデバイスまたはサービスに保存します。
- エンベロープ復号化操作手順 :
- ローカルデバイスまたはサービスから暗号文データキーを取得します。
- KMS の復号操作を呼び出して、暗号文データキーを復号します。 データキーのプレーンテキストのコピーが返されます。
- プレーンテキストデータキーを使用してローカルファイルを復号し、RAM に保存されているプレーンテキストデータキーを削除します。
関連 API 操作
次の KMS API 操作を呼び出して、ローカルデータを暗号化および復号化できます。
操作 | 説明 |
---|---|
CreateKey | CMK を作成します。 |
CreateAlias | CMK にエイリアスを割り当てます。 |
GenerateDataKey | データキーを生成し、指定された CMK を使用してデータキーを暗号化してから、プレーンテキストデータキーと暗号文データキーを返します。 |
Decrypt | GenerateDataKey 操作を呼び出して生成された暗号文データキーなど、KMS によって暗号化されたデータを復号します。 CMK を指定する必要はありません。 |
ローカルファイルの暗号化と復号化
- エンベロープ暗号化
- CMK を作成します。
$ aliyun kms CreateKey { "KeyMetadata": { "CreationDate": "2019-04-08T07:45:54Z", "Description": "", "KeyId": "1234abcd-12ab-34cd-56ef-12345678****", "KeyState": "Enabled", "KeyUsage": "ENCRYPT/DECRYPT", "DeleteDate": "", "Creator": "111122223333", "Arn": "acs:kms:cn-hangzhou:111122223333:key/1234abcd-12ab-34cd-56ef-12345678****", "Origin": "Aliyun_KMS", "MaterialExpireTime": "" }, "RequestId": "2a37b168-9fa0-4d71-aba4-2077dd9e80df" }
- CMK にエイリアスを割り当てます。
エイリアスは CMK のオプションです。 CMK にエイリアスがない場合、その ID を使用できます。
$ aliyun kms CreateAlias --AliasName alias/Apollo/WorkKey --KeyId 1234abcd-12ab-34cd-56ef-1234567890ab
注 この例では、Apollo/WorkKey は、データキーの暗号化に使用される Apollo プロジェクトの CMK を指定します。 CMK のエイリアスは WorkKey です。 つまり、alias/Apollo/WorkKey を指定して CMK WorkKey を使用し、データキーを暗号化できます。 - ローカルデータファイルを暗号化します。
サンプルコード:
- CMK:CMK のエイリアスは、
alias/Apollo/WorkKey
です 。 - プレーンテキストデータファイル: ./data/sales.csv
- 暗号文データファイル: ./data/sales.csv.cipher
#! /usr/bin/env python # coding=utf-8 import json import base64 from Crypto.Cipher import AES from aliyunsdkcore import client from aliyunsdkkms.request.v20160120 import GenerateDataKeyRequest def KmsGenerateDataKey(client, key_alias): request = GenerateDataKeyRequest.GenerateDataKeyRequest() request.set_accept_format('JSON') request.set_KeyId(key_alias) request.set_NumberOfBytes(32) response = json.loads(client.do_action(request)) datakey_encrypted = response["CiphertextBlob"] datakey_plaintext = response["Plaintext"] return (datakey_plaintext, datakey_encrypted) def ReadTextFile(in_file): file = open(in_file, 'r') content = file.read() file.close() return content def WriteTextFile(out_file, lines): file = open(out_file, 'w') for ln in lines: file.write(ln) file.write('\n') file.close() # Out file format (text) # Line 1: b64 encoded data key # Line 2: b64 encoded IV # Line 3: b64 encoded ciphertext # Line 4: b64 encoded authentication tag def LocalEncrypt(datakey_plaintext, datakey_encrypted, in_file, out_file): data_key_binary = base64.b64decode(datakey_plaintext) cipher = AES.new(data_key_binary, AES.MODE_EAX) in_content = ReadTextFile(in_file) ciphertext, tag = cipher.encrypt_and_digest(in_content) lines = [datakey_encrypted, base64.b64encode(cipher.nonce), base64.b64encode(ciphertext), base64.b64encode(tag)]; WriteTextFile(out_file, lines) clt = client.AcsClient('Access-Key-Id','Access-Key-Secret','Region-Id') key_alias = 'alias/Apollo/WorkKey' in_file = './data/sales.csv' out_file = './data/sales.csv.cipher' # Generate Data Key datakey = KmsGenerateDataKey(clt, key_alias) # Locally Encrypt the sales record LocalEncrypt(datakey[0], datakey[1], in_file, out_file)
- CMK:CMK のエイリアスは、
- CMK を作成します。
- エンベロープ復号化
ローカルファイルを復号します。
サンプルコード:- 暗号文データファイル: ./data/sales.csv.cipher
- プレーンテキストデータファイル: ./data/decrypted_sales.csv
#! /usr/bin/env python #coding=utf-8 import json import base64 from Crypto.Cipher import AES from aliyunsdkcore import client 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(clt.do_action(request)) return response.get("Plaintext") def ReadTextFile(in_file): file = open(in_file, 'r') lines = [] for ln in file: lines.append(ln) file.close() return lines def WriteTextFile(out_file, content): file = open(out_file, 'w') file.write(content) file.close() def LocalDecrypt(datakey, iv, ciphertext, tag, out_file): cipher = AES.new(datakey, AES.MODE_EAX, iv) data = cipher.decrypt_and_verify(ciphertext, tag).decode('utf-8') WriteTextFile(out_file, data) clt = client.AcsClient('Access-Key-Id','Access-Key-Secret','Region-Id') in_file = './data/sales.csv.cipher' out_file = './data/decrypted_sales.csv' # Read encrypted file in_lines = ReadTextFile(in_file) # Decrypt data key datakey = KmsDecrypt(clt, in_lines[0]) # Locally decrypt the sales record LocalDecrypt( base64.b64decode(datakey), base64.b64decode(in_lines[1]), # IV base64.b64decode(in_lines[2]), # Ciphertext base64.b64decode(in_lines[3]), # Authentication tag out_file )