Alibaba Cloud にデプロイされた IT 資産の機密情報を暗号化する必要があります。 大量のローカルデータを暗号化する必要がある場合は、Key Management Service (KMS) の暗号化API操作を呼び出してオンラインでデータキーを生成し、そのデータキーを使用してローカルデータをオフラインで暗号化できます。 この暗号化メカニズムは、エンベロープ暗号化と呼ばれます。
背景情報
エンベロープ暗号化は、以下のシナリオで使用できますが、これに限定されません。
ビジネスデータファイルの暗号化
ローカルディスクに保存されているすべてのデータの暗号化
このドキュメントでは、エンベロープ暗号化を使用してローカルファイルを暗号化および復号化する方法について説明します。
データの暗号化と復号化の仕組み
KMSを使用して顧客マスターキー (CMK) を作成し、CMKを使用してデータキーを生成し、そのデータキーを使用してローカルファイルを暗号化および復号化します。 エンベロープ暗号化は、大量のデータの暗号化と復号化に適しています。 エンベロープ暗号化の手順を次の図に示します。
手順: エンベロープ暗号化
KMSコンソールで、またはCreateKey操作を呼び出してCMKを作成します。
GenerateDataKey操作を呼び出して、データキーを生成します。 KMSは、データキーの平文と暗号文を返します。
平文データキーを使用してローカルファイルを暗号化し、メモリから平文データキーを削除します。
暗号文データキーと暗号化されたデータファイルを永続的なストレージデバイスまたはサービスに保存します。
手順: エンベロープ復号化
ローカルファイルから暗号文データキーを取得します。
KMSのDecrypt操作を呼び出して、暗号文データキーを復号します。 データキーのプレーンテキストが返されます。
平文データキーを使用してローカルファイルを復号化し、メモリから平文データキーを削除します。
暗号化および復号化API操作
次の表に示すAPIを呼び出して、ローカルデータを暗号化および復号化できます。
API 操作 | 説明 |
CMK を作成します。 | |
CMK のエイリアスを作成します。 | |
データキーを生成し、指定されたCMKを使用してデータキーを暗号化します。 KMSは、データキーの平文と暗号文を返します。 | |
GenerateDataKey操作を呼び出して生成された暗号文データキーを含む、KMSで暗号化されたデータを復号します。 CMK を指定する必要はありません。 |
ローカルファイルの暗号化と復号化
Alibaba CloudアカウントのAccessKeyペアには、すべてのAPI操作に対する権限があります。 AccessKeyペアを使用して操作を実行することは、リスクの高い操作です。 RAMユーザーを使用してAPI操作を呼び出したり、ルーチンのO&Mを実行することを推奨します。プロジェクトコードにAccessKey IDとAccessKey Secretを保存しないことを推奨します。 そうしないと、AccessKeyペアが漏洩し、アカウントに属するすべてのリソースのセキュリティが侵害される可能性があります。
この例では、AccessKeyペアは、ID認証を実装するためにALIBABA_CLOUD_ACCESS_KEY_IDとALIBABA_CLOUD_ACCESS_KEY_SECRET環境変数に保存されます。
認証情報の設定方法の詳細については、「アクセス資格情報の管理」をご参照ください。
環境変数を設定するために使用される方法は、オペレーティングシステムによって異なります。 詳細については、「Linux、macOS、およびWindowsでの環境変数の設定」をご参照ください。
Alibaba Cloud CLIを使用してCMKを作成し、ローカルファイルを暗号化および復号化できます。
CreateKey操作を呼び出して、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": "151266687691****", "Arn": "acs:kms:cn-hangzhou:151266687691****:key/1234abcd-12ab-34cd-56ef-12345678****", "Origin": "Aliyun_KMS", "MaterialExpireTime": "" }, "RequestId": "2a37b168-9fa0-4d71-aba4-2077dd9e80df" }オプション。 CMKのエイリアスを作成します。
エイリアスは、CMKを識別するためにオプションで使用されます。 CMKにエイリアスがない場合は、CMKのIDを使用してCMKを識別できます。
aliyun kms CreateAlias --AliasName alias/Apollo/WorkKey --KeyId 1234abcd-12ab-34cd-56ef-12345678****説明この例では、
Apollo/WorkKeyはApolloプロジェクトのCMKのエイリアスです。 後続のサンプルコードでエイリアスalias/Apollo/WorkKeyを使用して、暗号化操作を呼び出すことができます。ローカルファイルを暗号化します。
次のサンプルコード:
alias/Apollo/WorkKeyはCMKのエイリアスです。. /データ /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(os.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"),os.getenv("ALIBABA_CLOUD_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)ローカルファイルを复号化します。
次のサンプルコード:
. /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(client.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(os.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"),os.getenv("ALIBABA_CLOUD_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 )