📝

KMS キーでの暗号化と復号化をチュートリアルレベルでやってみた

に公開

AWS Key Management Service - AWS Key Management Service
コマンドと Python プログラムでやってみました。

  • KMS キー作成
  • データキー (暗号化キー) 作成
  • データ暗号化
  • データ復号化
    • 正しいキーで復号
    • 不正なキーで復号

コマンド

コマンド実行環境は CloudShell です。

# KMS キーを 2 つ作成
$ aws kms create-key --description "Test Key A for encryption learning"
$ aws kms create-key --description "Test Key B for encryption learning"

# データキーを 2 つ作成
$ aws kms generate-data-key --key-id <キー A の キー ID> --key-spec AES_256
$ aws kms generate-data-key --key-id <キー B の キー ID> --key-spec AES_256

# テストデータファイル作成
$ echo "This is secret data for encryption test" > test-data.txt

# データの暗号化
$ openssl enc -aes-256-cbc -in test-data.txt -out encrypted-with-keyA.bin -K $(echo "<データキー A の Plaintext>" | base64 -d | xxd -p -c 256) -iv 00000000000000000000000000000000

# データの復号化
$ openssl enc -aes-256-cbc -d -in encrypted-with-keyA.bin -out decrypted-with-keyA.txt -K $(echo "<データキー A の Plaintext>" | base64 -d | xxd -p -c 256) -iv 00000000000000000000000000000000

# 不正なキーでのデータの復号化
$ openssl enc -aes-256-cbc -d -in encrypted-with-keyA.bin -out decrypted-with-keyB.txt -K $(echo "<データキー B の Plaintext>" | base64 -d | xxd -p -c 256) -iv 00000000000000000000000000000000

bad decrypt
00DE9FC0C17F0000:error:1C800064:Provider routines:ossl_cipher_unpadblock:bad decrypt:providers/implementations/ciphers/ciphercommon_block.c:107:

Python プログラム

Lambda 関数で試してみました。

  • ランタイム: Python 3.13
  • Lambda 実行ロールの権限: AdministratorAccess
import json
import boto3
import base64
from botocore.exceptions import ClientError

def lambda_handler(event, context):
    kms = boto3.client('kms')
    
    try:
        # Step 1: Create two KMS keys
        print("Creating KMS Key A...")
        key_a = kms.create_key(Description='Lambda Demo Key A')
        key_a_id = key_a['KeyMetadata']['KeyId']
        print(f"Key A created: {key_a_id}")
        
        print("Creating KMS Key B...")
        key_b = kms.create_key(Description='Lambda Demo Key B')
        key_b_id = key_b['KeyMetadata']['KeyId']
        print(f"Key B created: {key_b_id}")
        
        # Step 2: Generate data keys
        print("Generating data key with Key A...")
        data_key_a = kms.generate_data_key(KeyId=key_a_id, KeySpec='AES_256')
        plaintext_key_a = data_key_a['Plaintext']
        
        print("Generating data key with Key B...")
        data_key_b = kms.generate_data_key(KeyId=key_b_id, KeySpec='AES_256')
        plaintext_key_b = data_key_b['Plaintext']
        
        # Step 3: Test encryption/decryption
        test_data = b"This is secret data for Lambda KMS test"
        
        # Encrypt with Key A's data key
        encrypted_a = kms.encrypt(KeyId=key_a_id, Plaintext=test_data)
        print("Data encrypted with Key A")
        
        # Decrypt with Key A (should succeed)
        try:
            decrypted_a = kms.decrypt(CiphertextBlob=encrypted_a['CiphertextBlob'])
            success_a = decrypted_a['Plaintext'] == test_data
            print(f"Decryption with Key A: {'SUCCESS' if success_a else 'FAILED'}")
        except Exception as e:
            print(f"Decryption with Key A failed: {str(e)}")
        
        # Try to decrypt with Key B (should fail)
        try:
            # This will fail because we're using the wrong key
            kms.decrypt(CiphertextBlob=encrypted_a['CiphertextBlob'], KeyId=key_b_id)
            print("Decryption with Key B: UNEXPECTED SUCCESS")
        except ClientError as e:
            print(f"Decryption with Key B: EXPECTED FAILURE - {e.response['Error']['Code']}")
        
        return {
            'statusCode': 200,
            'body': json.dumps({
                'message': 'KMS encryption/decryption test completed',
                'key_a_id': key_a_id,
                'key_b_id': key_b_id,
                'test_result': 'Key isolation verified successfully'
            })
        }
        
    except Exception as e:
        print(f"Error: {str(e)}")
        return {
            'statusCode': 500,
            'body': json.dumps({'error': str(e)})
        }

実行結果は以下の通りです。

Creating KMS Key A...
Key A created: dc2ba2fa-8969-4836-a389-c7bf944d00cf
Creating KMS Key B...
Key B created: 3ff0b7bd-217f-4e7e-81d0-67d3edbe3811
Generating data key with Key A...
Generating data key with Key B...
Data encrypted with Key A
Decryption with Key A: SUCCESS
Decryption with Key B: EXPECTED FAILURE - IncorrectKeyException

正しいキーでは復号化が成功し、不正なキーでは IncorrectKeyException が発生することを確認できました。
CloudTrail にも Decrypt で IncorrectKeyException が発生した記録が残っていました。

"errorCode": "IncorrectKeyException",
"errorMessage": "The key ID in the request does not identify a CMK that can perform this operation.",

まとめ

今回は KMS キーでの暗号化と復号化をチュートリアルレベルでやってみました。
どなたかの参考になれば幸いです。

参考資料

Discussion