AWS CloudHSMを使ってデジタル署名を作成してみた

AWS CloudHSMを使ってデジタル署名を作成してみた

2025.12.15

AWS CloudHSM(以下、CloudHSM)を使ってデジタル署名を作成してみました。

CloudHSM クラスターの作成

CloudHSMを使用するには、まずクラスターの作成が必要です。

1. クラスターの作成

aws cloudhsmv2 create-cluster \
    --hsm-type hsm2m.medium \
    --mode NON_FIPS \
    --subnet-ids <Subnet ID> \
    --backup-retention-policy Type=DAYS,Value=7

2. HSMインスタンスの作成

クラスター作成後、HSMインスタンスを追加します。

--availability-zoneはクラスター作成時に指定したサブネットの所属するAZを指定してください。

# クラスターIDを取得
CLUSTER_ID=$(aws cloudhsmv2 describe-clusters \
    --query 'Clusters[].ClusterId' \
    --output text \
    --region us-east-1)

# HSMインスタンスを作成
aws cloudhsmv2 create-hsm \
    --cluster-id $CLUSTER_ID \
    --availability-zone us-east-1a

3. CA証明書の作成

CloudHSMクラスターの初期化には以下が必要です。

  • SignedCert: HSMのCSR(証明書署名要求)に署名した証明書
  • TrustAnchor: 署名に使用したCA(認証局)の自己署名証明書

今回は検証のため、自己署名証明書を直接使用してHSMのCSRに署名します。

# 1. クラスターのCSRを取得
aws cloudhsmv2 describe-clusters \
    --filters "clusterIds=$CLUSTER_ID" \
    --query 'Clusters[0].Certificates.ClusterCsr' \
    --output text > cluster.csr

# 2. CA用の秘密鍵を作成
openssl genrsa -out customerCA.key 2048

# 3. 自己署名CA証明書を作成(これがTrustAnchor)
openssl req -new -x509 -days 90 -key customerCA.key -out customerCA.crt \
    -subj "/C=JP/ST=Tokyo/L=Tokyo/O=MyCompany/OU=IT/CN=CloudHSM CA"

# 4. HSMのCSRに署名(これがSignedCert)
openssl x509 -req -in cluster.csr -CA customerCA.crt -CAkey customerCA.key \
    -CAcreateserial -out cluster_signed.crt -days 90

# 5. 証明書の確認
openssl x509 -in cluster_signed.crt -text -noout

4. クラスターの初期化

作成したCA証明書を使用してクラスターを初期化します:

aws cloudhsmv2 initialize-cluster \
    --cluster-id $CLUSTER_ID \
    --signed-cert file://cluster_signed.crt \
    --trust-anchor file://customerCA.crt

5. クラスター状態の確認

aws cloudhsmv2 describe-clusters \
      --filters "clusterIds=$CLUSTER_ID" \
      --query 'Clusters[0].State' \
      --output text

INITIALIZEDが出力されることを確認します。これには数分かかります。

出力例
INITIALIZED

CloudHSM CLIクライアントのセットアップ(CloudShell)

CloudHSMはプライベートサブネット内での利用を前提としています。

Network isolation is achieved by creating a VPC and a private subnet for the HSM cluster, with an elastic network
interface (ENI) assigned to each HSM

https://docs.aws.amazon.com/cloudhsm/latest/userguide/infrastructure-security.html

デジタル署名を試すには、VPC内にあるCloudHSMと接続できるクライアント環境が必要です。

CloudHSMと同一のVPC内にクライアント用のEC2を立てる手順が公式ドキュメントでは紹介されていました。

今回は、検証用の一時的な環境であるためセットアップが簡単なCloudShell(VPC内に起動)をクライアントとして使用します。

CloudShellにCloudHSM CLIをインストールして各種操作を行います。

VPC内にCloudShell環境を作成

CloudShellからCloudHSMにアクセスするため、CloudHSMと同一のVPC内にCloudShellを作成します。

VPC___us-east-1.png

loudHSMクラスターのセキュリティグループは、ポート 2223〜2225 経由でのインバウンド通信とアウトバウンド通信を許可しています。

このセキュリティグループをCloudShellにアタッチすることで、CloudHSMクラスターへのアクセスが可能になります。

https://docs.aws.amazon.com/ja_jp/cloudhsm/latest/userguide/configure-sg.html

CLIツールをS3からインストールするために、アウトバウンドのHTTPSが許可されているVPCのデフォルトセキュリティグループをアタッチしています。

証明書のS3アップロード(ローカル)

VPC内のCloudShellはコンソールからのファイルアップロードに対応していないため、S3を経由してファイルを転送します。

# 既存のS3バケット名を設定(例:your-bucket-name)
BUCKET_NAME="your-bucket-name"

# CA証明書をS3にアップロード
aws s3 cp customerCA.crt s3://$BUCKET_NAME/cloudhsm/

# アップロードを確認
aws s3 ls s3://$BUCKET_NAME/cloudhsm/

証明書のダウンロード

CloudShell上で以下のコマンドを実行して、証明書をダウンロードします。

# CloudShellで作業ディレクトリを作成
mkdir -p ~/cloudhsm-setup
cd ~/cloudhsm-setup

# 使用するS3バケット名を設定
BUCKET_NAME="your-bucket-name"

# S3から証明書をダウンロード
aws s3 cp s3://$BUCKET_NAME/cloudhsm/customerCA.crt ~/cloudhsm-setup/

# ファイルの存在確認
ls -la ~/cloudhsm-setup/customerCA.crt

CloudHSM CLIのインストール

CloudShellで以下のコマンドを実行して、CloudHSM CLIをインストールします。

# CloudHSM CLIをダウンロード(Amazon Linux 2023用)
wget https://s3.amazonaws.com/cloudhsmv2-software/CloudHsmClient/EL9/cloudhsm-cli-latest.el9.x86_64.rpm

# インストール(CloudShellはAmazon Linux 2023ベース)
sudo dnf install -y ./cloudhsm-cli-latest.el9.x86_64.rpm

CloudHSM CLIのセットアップ

CloudHSM CLIをセットアップします。

今回は検証のため、HSM 1台の構成にしています。

単一HSM環境ではキーペア作成時にエラーが発生するため、検証環境に限定してキー可用性チェックを無効化しています。

本番環境では複数HSMの冗長構成を推奨し、このチェックは有効のままにしてください。

# HSM Cluster IDを取得
CLUSTER_ID=$(aws cloudhsmv2 describe-clusters \
    --query 'Clusters[].ClusterId' \
    --output text \
    --region us-east-1)

# HSM IPを取得
HSM_IP=$(aws cloudhsmv2 describe-clusters \
  --filters "clusterIds=$CLUSTER_ID" \
  --query 'Clusters[0].Hsms[0].EniIp' --output text)
echo "Using HSM IP: $HSM_IP"

# 設定ディレクトリを作成
sudo mkdir -p /opt/cloudhsm/etc

# CA証明書を配置
sudo cp customerCA.crt /opt/cloudhsm/etc/
sudo chmod 444 /opt/cloudhsm/etc/customerCA.crt

# configureツールを実行(単一HSM環境でキー可用性チェックを無効化)
sudo /opt/cloudhsm/bin/configure-cli -a $HSM_IP --disable-key-availability-check

# 設定を確認
cat /opt/cloudhsm/etc/cloudhsm-cli.cfg

クラスターのアクティベーション

初期化されたクラスターをアクティベートして実際に使用可能な状態にします。

CloudShellで以下を実行します:

# CloudHSM CLI対話モードを起動
/opt/cloudhsm/bin/cloudhsm-cli interactive

# クラスターをアクティベート(初回adminパスワードを設定)
aws-cloudhsm> cluster activate
# パスワード入力を求められるので、パスワードを設定

# アクティベーション後、adminとしてログイン
aws-cloudhsm> login --username admin --role admin
# アクティベーション時に設定したパスワードを入力

# ユーザーリストを確認(adminがCOになっていることを確認)
aws-cloudhsm> user list

CloudHSM CLIを使用してデジタル署名を作成・検証してみる

アクティベートされたクラスターで実際にデジタル署名を作成・検証してみましょう。

管理者ログインとCryptoUserの作成

# Crypto Officer(admin)でログイン
aws-cloudhsm> login --username admin --role admin
# アクティベーション時に設定したパスワードを入力

# CryptoUserを作成
aws-cloudhsm> user create --username cryptouser --role crypto-user
# CryptoUserのパスワードを設定

# ログアウト
aws-cloudhsm> logout

デジタル署名用キーペアの生成

CryptoUserでログインして、デジタル署名用のRSAキーペアを生成します:

# CryptoUserでログイン
aws-cloudhsm> login --username cryptouser --role crypto-user
# CryptoUserのパスワードを入力

# 既存のキーペアを削除(もし既に生成済みの場合)
aws-cloudhsm> key delete --filter attr.label=code_signing_key_pub
aws-cloudhsm> key delete --filter attr.label=code_signing_key_priv

# RSA鍵ペアを生成(デジタル署名用、署名・検証属性を設定)
aws-cloudhsm> key generate-asymmetric-pair rsa --public-label code_signing_key_pub --private-label code_signing_key_priv --modulus-size-bits 2048 --public-exponent 65537 --private-attributes sign=true --public-attributes verify=true

# 生成されたキーを確認
aws-cloudhsm> key list

デジタル署名を作成・検証

RSA鍵ペアを使用してデジタル署名を作成・検証します。

まず、**通常のターミナル(CloudHSM CLI対話モード外)**でテストファイルを作成:

# テストデータファイルを作成(通常のbashで実行)
echo "This is a test document for signing" > test_document.txt

次に、CloudHSM CLI対話モード内で署名・検証を実行:

# CryptoUserでログイン済みの状態で実行

# 1. 生成されたキーのハンドル番号を確認
aws-cloudhsm> key list
# 出力例:
# {
#   "data": {
#     "matched_keys": [
#       {
#         "key-reference": "0x00000000000XXXXX",
#         "attributes": { "label": "code_signing_key_pub" }
#       },
#       {
#         "key-reference": "0x00000000000YYYYY",
#         "attributes": { "label": "code_signing_key_priv" }
#       }
#     ]
#   }
# }

# 2. テストデータに署名(秘密鍵のラベルを使用)
aws-cloudhsm> crypto sign rsa-pkcs --key-filter attr.label=code_signing_key_priv --hash-function sha256 --data-path /home/cloudshell-user/test_document.txt

# 署名結果(Base64形式)が出力されるので、これを保存
# 例:MEUCIQDxxx... のような署名が表示される

# 3. 署名を検証(公開鍵のラベルを使用)
# 検証時は署名をBase64形式で直接指定するか、ファイルから読み込む
aws-cloudhsm> crypto verify rsa-pkcs --key-filter attr.label=code_signing_key_pub --hash-function sha256 --data-path /home/cloudshell-user/test_document.txt --signature <Base64署名>

# 検証成功時のメッセージ
#{
#  "error_code": 0,
#  "data": {
#    "message": "Signature verified successfully"
#  }
# }

セッション終了

# ログアウト
aws-cloudhsm> logout

# CloudHSM CLI終了(対話モードから抜ける)
aws-cloudhsm> exit

参考

https://dev.classmethod.jp/articles/import-and-export-private-key-with-aws-cloudhsm/

この記事をシェアする

FacebookHatena blogX

関連記事