AWS KMSによる、データの暗号化と復号 - 非対称鍵(RSA_4096)編

AWS KMSでを使ったデータの暗号化、復号の検証も行った。 対称鍵の検証は、別記事にした。

鍵の作成

Management ConsoleでもCLIでもお好みで。 以下のパラメータでCMK (Customer Management Key)を作成する。

  • キーのタイプ: 非対称
  • キーの使用: 暗号化および復号化
  • キーの仕様: RSA_4098
  • Alias: rsatest

鍵情報の取得

CLIで、describe-keyを使って鍵の情報を得る。

 aws kms describe-key --key-id alias/rsatest
{
    "KeyMetadata": {
        "AWSAccountId": "xxxxxxxxxxxxx",
        "KeyId": "0192e16e-01ed-4d84-84a5-5144259766f2",
        "Arn": "arn:aws:kms:ap-northeast-1:xxxxxxxxxxxxx:key/0192e16e-01ed-4d84-84a5-5144259766f2",
        "CreationDate": 1596690475.888,
        "Enabled": true,
        "Description": "",
        "KeyUsage": "ENCRYPT_DECRYPT",
        "KeyState": "Enabled",
        "Origin": "AWS_KMS",
        "KeyManager": "CUSTOMER",
        "CustomerMasterKeySpec": "RSA_4096",
        "EncryptionAlgorithms": [
            "RSAES_OAEP_SHA_1",
            "RSAES_OAEP_SHA_256"
        ]
    }
}

公開鍵の取得

4096bitの鍵長をもつRSA鍵ペアができている。 秘密鍵を取り出すことはできないが、公開鍵は取り出せる。

 aws kms get-public-key --key-id alias/rsatest
{
    "KeyId": "arn:aws:kms:ap-northeast-1:xxxxxxxxxxxxx:key/0192e16e-01ed-4d84-84a5-5144259766f2",
    "PublicKey": "MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA6u875H89mRNP7PLH6+QGEhPUIga6jrssgmLnC/98KGXfZx/jHYPH2oJw0uedA0uuu3wUbubduy8rYd+5LfQUiLoK+2cjOHp/u2xbKruDmZtVM68YNWBnYwp8bZ9y7c2VWblBgu0WPWa1NFGMi2reXcqDHppvzy15lv5kYYrfKKjabbluPOSDYYp4Hsw8Dmd/6tvc7zw1L+Qa4uyK/ojp05WPSVmlaUMuKopzr3ngD/sEKwQ1BmA0dWGzTUZTtOAQusSlLN7tCoLNLWKS1ZDfZJKbiVBLbErGiyLRhGt7MaXgB95O+Xh9wgdiCHFZ/S2ji68VCXEfrTomcy63kdctM7EmNWhgnBHGBgxelQSG9gwqCBciKBkVuCP594N3xVjN2T1DgbsMaznfN8+P03gfvOqwtD8LVXS87JuVAJb3iBm5hfH5m+/NL8vSZ9itamPPDVNG8hBnl2ZUCK2wZBMzw2djRIyUAe+9N1NwzoYTSNlsWC5KJTH5yIat99v3IRAhHMugwfaaKmpUauLdPxQf2vI4wLE/ZNGYR4f9IhPgs1VEpxVGYge198YPbeDzEdbTUIGMDR7kCTSXrt5JZRW/40RX/Rh6qq12Jo55TC6PVaGtMcLjz7LYiMdgeBZq4/TV6EbovuEo/x5MNyVMpWjR4o45LqQuw8983c++55zFju0CAwEAAQ==",
    "CustomerMasterKeySpec": "RSA_4096",
    "KeyUsage": "ENCRYPT_DECRYPT",
    "EncryptionAlgorithms": [
        "RSAES_OAEP_SHA_1",
        "RSAES_OAEP_SHA_256"
    ]
}

JSON形式では使いにくいので、Base64エンコードを解いてDERに変換する。

$ aws kms get-public-key \
	--key-id alias/rsatest \
	--output text --query PublicKey|base64 -d >pubkey.der

pubkey.derが生成される。

データの暗号化

kmsでは、4kByteまでしかデータを暗号化および復号ができない。そのため暗号化および復号に使用する鍵を独自に生成する。 この鍵をData Keyと呼ぶ。このData KeyをKMSで作成した鍵で暗号化し、別途DynamoDBなどで管理する。 これによりkmsでData Keyを復号する権限のないユーザにデータの復号はできなくなる。 鍵の管理については本稿では触れない。

Data Keyの生成

データの暗号化アルゴリズムはお好みで。今回はAES256-CBCにしよう。まずは、opensslで鍵を生成する。

$ openssl rand -out datakey 32

Data Keyの暗号化

OpenSSLを使用する場合

Data Keyをkmsで生成したCMKで暗号化する。さきほど取得した公開鍵で暗号化する。 kmsで復号できるアルゴリズムは限られているので注意が必要である。 データを復号するときには、kmsに暗号化したData Keyを復号してもらわなければならない。 そのため、kmsが復号できるアルゴリズムを使用する必要がある。

サポートしているアルゴリズムは、described-keyで取得できる。 今回の場合は、RSAES_OAEP_SHA_1RSAES_OAEP_SHA_256の二種類である。

ということで、今回は、RSAES_OAEP_SHA_256でData Keyを暗号化する。

$ openssl pkeyutl -encrypt \
    -pubin -inkey pubkey.der -keyform DER \
    -in datakey \
    -out encrypted_datakey \
    -pkeyopt rsa_padding_mode:oaep \
    -pkeyopt rsa_oaep_md:sha256

一応、ちゃんとkmsで復号できるか確認しておこう。

$ aws kms decrypt \
    --ciphertext-blob fileb://encrypted_datakey \
    --key-id alias/rsatest \
    --encryption-algorithm RSAES_OAEP_SHA_256 \
    --output text --query Plaintext | base64 -d >decrypted_datakey

kmsで復号されたData keyは、decrypted_datakeyに格納された。 暗号化前のData keyと復号されたData keyのHashを比較する。

$  sha256sum datakey decrypted_datakey 
0b9d181063f1e4ace5ac59e1253186406b27fb1ffd0c22bb1a62ffa2515f6803  datakey
0b9d181063f1e4ace5ac59e1253186406b27fb1ffd0c22bb1a62ffa2515f6803  decrypted_datakey

一致した。復号に成功していることが確認できた。

kmsにおまかせする場合

上記の例では、opensslコマンドを使ったが、もちろんkmsに任せることもできる。 こっちのほうが簡単か。ただAPI利用料がかかる。

 $ aws kms encrypt --key-id alias/rsatest \
    --plaintext fileb://datakey \
    --encryption-algorithm RSAES_OAEP_SHA_256
{
    "CiphertextBlob": "ZAo40r0pQ3COzELKzM8mJMFNbHno4jUiyzeuZ6rQVUH0ZLsIJbdESnhl....",
    "KeyId": "arn:aws:kms:ap-northeast-1:xxxxxxxxxxxxx:key/0192e16e-01ed-4d84-84a5-5144259766f2",
    "EncryptionAlgorithm": "RSAES_OAEP_SHA_256"
}

データの暗号化

データを暗号化する。これは普通にopensslで

$ openssl aes-256-cbc -e \
    -in plain_data.bin \
    -out encrypted_data.bin
    -pass file:datakey \
    -pbkdf2

暗号化したら、暗号化に使用したData Keyを削除する。 これを忘れるとkmsを使う意味がまったくなくなってしまう。

$ rm datakey

データの復号

データを復号するには、まず暗号化されたData Keyを復号する。

$ aws kms decrypt \
    --ciphertext-blob fileb://encrypted_datakey \
    --key-id alias/rsatest \
    --encryption-algorithm RSAES_OAEP_SHA_256 \
    --output text --query Plaintext | base64 -d >decrypted_datakey

そして、データを復号する。

$ openssl aes-256-cbc -d \
    -in encrypted_data.bin \
    -out decrypted_data \
    -pass file:./decrypted_datakey \
    -pbkdf2

復号できたデータは、decrypted_dataに格納されている。 確認のため、平文のデータのHashと比較する。

$ sha256sum plain_data.bin decrypted_data.bin 
5678c5a7a63f910c6eb172ebb3736b73099b8d62172c6b42034d87b7bf30b107  plain_data.bin
5678c5a7a63f910c6eb172ebb3736b73099b8d62172c6b42034d87b7bf30b107  decrypted_data.bin

一致した。復号が成功したことがわかる。

Have Fun!


awskms

1460 Words

2020-08-07 16:41 +0900