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_1
とRSAES_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!