LoginSignup
2
2

More than 1 year has passed since last update.

ローカル環境 KMS で暗号鍵を固定化する (LocalStack)

Posted at

AWS Key Management Service (KMS)は暗号鍵の生成・管理と、アプリケーションデータの暗号化・復号を提供してくれるサービスです。KMS を利用することで、暗号鍵ファイルを直接扱うリスクを回避することでできます。

以前の記事で紹介した LocalStack Docker コンテナで KMS モックサーバを実行し KMS を利用するアプリケーションを開発した際、他の開発メンバーの環境で暗号化したテストデータを復号できるよう、鍵ファイルを固定する必要があり、事前に作成した暗号鍵ファイルをインポートした KMS キーを生成するよう自動化しました。
その手順を共有します。

Docker compose file 設定

docker-compose.yml
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
  • 環境変数 SERVICESkms を追加
  • 環境変数 KMS_PROVIDERlocal-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 ディレクトリに配置

init/kms.sh
#!/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

参考資料

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2