AWS Key Management Service (KMS)は暗号鍵の生成・管理と、アプリケーションデータの暗号化・復号を提供してくれるサービスです。KMS を利用することで、暗号鍵ファイルを直接扱うリスクを回避することでできます。
以前の記事で紹介した LocalStack Docker コンテナで KMS モックサーバを実行し KMS を利用するアプリケーションを開発した際、他の開発メンバーの環境で暗号化したテストデータを復号できるよう、鍵ファイルを固定する必要があり、事前に作成した暗号鍵ファイルをインポートした KMS キーを生成するよう自動化しました。
その手順を共有します。
Docker compose file 設定
version: '3.8'
services:
localstack:
container_name: localaws-container-localstack
image: localstack/localstack:0.13.3
platform: linux/amd64
environment:
SERVICES: kms
EDGE_PORT: 4566
INIT_SCRIPTS_PATH: /docker-entrypoint-initaws.d
DEFAULT_REGION: 'ap-northeast-1'
KMS_PROVIDER: 'local-kms'
ports:
- '4566:4566'
volumes:
- ./init:/docker-entrypoint-initaws.d:ro
- ./data:/data:rw
- 環境変数
SERVICES
にkms
を追加 - 環境変数
KMS_PROVIDER
にlocal-kms
設定 - 初期化スクリプトを配置する init ディレクトリを /docker-entrypoint-initaws.d にマウント
- インポートする鍵ファイルを配置する data ディレクトリを /data にマウント
※Apple Silicon (M1)で実行する場合、通常 ARM 向けイメージが使用されますが、ARM 向けイメージでは本手順が実行できない不具合があるため platform: linux/amd64
で AMD64 用イメージを実行しています
インポートする鍵ファイルを作成
以下のコマンドで生成した PlaintextKeyMaterial.b64 を data ディレクトリに配置
openssl rand -base64 -out PlaintextKeyMaterial.b64 32
docker-compose.ymlや初期化スクリプトとともに、このファイルをGitリポジトリにコミットし、開発メンバー間で共有
初期化スクリプト
以下のようなスクリプトを init ディレクトリに配置
#!/bin/bash
# JSONファイルを扱うために jq をインストール
apt update -y && apt install jq -y
cd /data
# 暗号鍵をバイナリファイルに変換
openssl enc -d -base64 -A -in PlaintextKeyMaterial.b64 -out PlaintextKeyMaterial.bin
# KMSキーを生成しKeyId取得
awslocal kms create-key --origin EXTERNAL > create-key-output.json
KeyId=`jq -r '.KeyMetadata.KeyId' create-key-output.json`
# PublicKeyとImportTokenを取得
awslocal kms get-parameters-for-import \
--key-id ${KeyId} \
--wrapping-algorithm RSAES_OAEP_SHA_1 \
--wrapping-key-spec RSA_2048 \
> get-parameters-for-import-output.json
jq -r '.PublicKey' get-parameters-for-import-output.json > PublicKey.b64
openssl enc -d -base64 -A -in PublicKey.b64 -out PublicKey.bin
jq -r '.ImportToken' get-parameters-for-import-output.json > ImportToken.b64
openssl enc -d -base64 -A -in ImportToken.b64 -out ImportToken.bin
# 暗号鍵をインポート用に暗号化
openssl rsautl -encrypt \
-in PlaintextKeyMaterial.bin \
-oaep \
-inkey PublicKey.bin \
-keyform DER \
-pubin \
-out EncryptedKeyMaterial.bin
# 暗号化した鍵マテリアルをインポート
awslocal kms import-key-material \
--key-id ${KeyId} \
--encrypted-key-material fileb://EncryptedKeyMaterial.bin \
--import-token fileb://ImportToken.bin \
--expiration-model KEY_MATERIAL_DOES_NOT_EXPIRE
# KMSキーのエイリアス
awslocal kms create-alias --target-key-id ${KeyId} --alias-name 'alias/local-kms-key'
# KMSキーの情報を確認
awslocal kms describe-key --key-id 'alias/local-kms-key'
docker compose up でコンテナを起動すると
シェルスクリプトが自動的に実行され、KMS キーを生成し鍵ファイルをインポートします
KMS キー ID は毎回変わりますが、アプリケーションからはエイリアス 'alias/local-kms-key' を指定して利用できます
aws kms encrypt --key-id 'alias/local-kms-key' --plaintext 'プレインテキスト' --endpoint http://localhost:4566 --region ap-northeast-1
aws kms decrypt --key-id 'alias/local-kms-key' --ciphertext-blob '暗号化文字列(base64)' --endpoint http://localhost:4566 --region ap-northeast-1
参考資料