「AWSで耐量子暗号を使用する」ワークショップやってみた
こんにちは、臼田です。
みなさん、耐量子暗号使ってますか?(挨拶
今回はAWSから提供されている「AWSで耐量子暗号を使用する」ワークショップをやってみました。
AWSで現状利用できる耐量子暗号の実装方法や動作の詳細を確認できます。
概要
耐量子暗号(PQC:Post-Quantum Cryptography、ポスト量子暗号)とは、量子コンピュータにより現在使用されているRSAや楕円曲線暗号(ECC)などの公開鍵暗号が、ショアのアルゴリズムによって効率的に解読される脅威に対抗するため開発された新しい暗号方式です。従来暗号が素因数分解や離散対数問題の計算困難性に依存するのに対し、耐量子暗号は格子問題、符号理論、多変数方程式、ハッシュ関数など量子コンピュータでも解読が困難とされる数学的問題を基盤としており、量子攻撃に対しても安全性を維持できる暗号技術のことです。
現在耐量子暗号はまだ一般利用されておらず、NIST(米国標準技術研究所)による標準化プロセスが進行中で、2024年8月にML-KEM、ML-DSA、SLH-DSAの3つのアルゴリズムが正式に標準化されました。しかし実装や性能面での課題があるため、現在は従来暗号と耐量子暗号を組み合わせたハイブリッド方式による段階的な移行が検討されており、各ベンダーや組織が実証実験を通じて実用化に向けた準備を進めている段階です。
詳細はこのあたりなどご確認ください。
CRYPTREC | 耐量子計算機暗号の研究動向調査報告書の公開
AWSではAWS ポスト量子暗号への移行計画 | Amazon Web Services ブログで各サービスごとのサポート状況などが解説されています。
現在下記サービスなどが耐量子暗号をサポートしています。
- AWS Key Management Service (AWS KMS)
- AWS Secrets Manager
- AWS Certificate Manager (ACM)
このワークショップではEC2からKMSとTransfer FamilyのSFTPサーバーと耐量子暗号を利用して通信します。
やってみた
このワークショップはAWSが準備したものと個人で準備したもの両方で実行できます。今回は個人で準備していきます。
ただ、2025/09/07現在ワークショップに書いてある準備だけでは足りないので、いくつか手探りしたのでそれも書いていきます。
ワークショップの内容は以下のとおりです。
- 量子耐性暗号 (PQC) とは何か、なぜそれが必要なのかについて概要を説明します。
- デモ #1 : PQ TLS をサポートする AWS Java v2 SDK を使用し、PQ TLS 接続を介してキーを KMS にインポートします。
- デモ #2 : ポスト量子ベンチマークを実行して、パフォーマンスと帯域幅の特性を比較します。
- デモ #3 : ハイブリッドポスト量子 TLS ハンドシェイクのパケット キャプチャを実行し、WireShark を使用してハンドシェイクを調べます。
- デモ #4 : AWS Transfer Family を使用して SFTP エンドポイントを作成し、PQ 対応の SSH を使用して接続します。
- 学んだことをまとめる
準備
下記内容を準備します。
- EC2
- AMI: Ubuntu 24.04 LTS
- インスタンスサイズ: m7i.large
- ストレージサイズ: 30 GB
- セキュリティグループ: sshと8080を開ける
- EC2用IAM Role
- KMSを使えるように
- SFTP用S3バケット
- Transfer SFTPサーバー(手順内で作成)
- SFTPユーザー用IAM Role
- AWSTransferFullAccessをアタッチ
- Wireshark(ローカル環境)
EC2は上記スペックでセットアップしたあと、coderをセットアップしていきます。参考手順はこのインストール手順とこのSSH転送設定ですが、調整しています。
curl -fsSL https://code-server.dev/install.sh | sh
# 一度起動する
sudo systemctl start code-server
# Replaces "auth: password" with "auth: none" in the code-server config.
sed -i.bak 's/auth: password/auth: none/' ~/.config/code-server/config.yaml
sudo systemctl restart code-server
デモ1: ポスト量子TLS接続を使用してKMSにキーをインポートする
このモジュールでは、AWS Java v2 SDKとaws-kms-pq-tls-exampleを使用して、ローカル生成したAESキーを耐量子暗号通信でKMSにインポートし、「今すぐ収集、後で復号(harvest-now-decrypt-later style)」攻撃から保護します。
「今すぐ収集、後で復号」攻撃は、攻撃者が現在から暗号化された通信をキャプチャーしておいて、量子コンピュータが発達して攻撃可能になったときに復号する事により機密情報を盗み出す攻撃のことです。以下の図で説明されています。
今は破れなくても将来的に破れる見込みがあるため、そこに期待する攻撃方法です。
まずは建てたEC2にSSHトンネルを張り、coderにブラウザでアクセスします。
# -N disables executing a remote shell
ssh -N -L 8080:127.0.0.1:8080 -i 秘密鍵 ubuntu@<instance-ip>
ブラウザでhttp://127.0.0.1:8080
にアクセスします。
好きなようにセットアップしてください。
ワークショップの環境と合わせるために下記のようにフォルダを作成します。
mkdir environment
cd environment
エクスプローラーも開きます。
ターミナルのログがすぐに流れるので、settingからscrollbackを増やしておきます。
Java周りのセットアップをします。事前にupdateした後、ワークショップの手順の通りインストールします。ついでにAWS KMS PQ TLS Example Repoをcloneします。
sudo apt update
# Install Demo Dependencies
sudo apt-get install maven gradle -y
# Download Demo Code
cd ~/environment/ && git clone https://github.com/aws-samples/aws-kms-pq-tls-example.git -b aws-pq-workshop
/aws-kms-pq-tls-example/src/main/java/com/example/AwsKmsPqTlsExample.java
を見て内容を理解します。とありますが、解説はだいたいワークショップ内に書いてあるのでそちらを参考に見ていきましょう。
解説のフローを翻訳したものがこちらです。参考にしてください。
下記2つのデモが実行されます。
- Example 1: ローカルで生成したAESキーをRSA公開鍵で暗号化し、ポスト量子TLS接続経由でKMSにCustomer Managed Key(CMK)としてインポートするデモ。
- Example 2: KMSでAESデータ暗号化キー(DEK)を生成し、CMKで暗号化されたDEKをポスト量子TLS経由で受信後、KMSに復号化を依頼してクライアント側でデータ暗号化に使用するデモ。
では実行してみます。
# Clean any previous JAR files, build new JAR file, and then run it
cd ~/environment/aws-kms-pq-tls-example \
&& mvn clean \
&& mvn package \
&& java -jar target/aws-kms-pq-tls-example-1.0-jar-with-dependencies.jar
無事ワークショップと同じようになりました。
デモ2: ECDHEとML-KEMのベンチマーク
続いてAWS LibCrypto(AWS-LC)のspeedコマンドを利用してECDHとML-KEMの鍵交換の速度を比較し、鍵と暗号文のサイズを比較します。
必要なaws-lcとs2nコマンドラインツールを取得します。
# Download s2n and aws-lc command line tools
cd ~/environment/
curl 'https://static.us-east-1.prod.workshops.aws/public/fea0b681-9702-4ce9-870c-f1683ba8c2cb/static/files/ubuntu-24.04/pq-tls-cli-tools-local-installs.tar.gz' --output pq-tls-cli-tools-local-installs.tar.gz
tar -xzvf pq-tls-cli-tools-local-installs.tar.gz
確認します。
# Display locally installed tools
ls ~/environment/local-installs/bin/
ベンチマークを実行します。
``bash
./local-installs/bin/awslc speed -filter ECDH
./local-installs/bin/awslc speed -filter ML-KEM

ワークショップの内容と比べると結構パフォーマンスが変わりました。
帯域も確認します。
```bash
# Perform a TLS Handshake with KMS using classical TLS Ciphers
~/environment/local-installs/bin/s2nc -c default kms.us-east-1.amazonaws.com 443
# Perform a TLS Handshake with KMS using post-quantum TLS Ciphers
~/environment/local-installs/bin/s2nc -c default_pq kms.us-east-1.amazonaws.com 443
こちらはほぼ同等になりました。
デモ3:耐量子TLSハンドシェイクの実行と検証
このモジュールでは、TLSハンドシェイクをキャプチャしてWiresharkで動作を確認します。
一応ワークショップにもキャプチャ済みpcapが置いてありますが、キャプチャしてみましょう。
# Start a background job to capture all packets to kms.us-east-1.amazonaws.com
sudo tcpdump "host kms.us-east-1.amazonaws.com" -s 0 -i any -w ~/environment/classic-tls-capture.pcap &
# Wait 1 second, then perform a Classical TLS 1.3 Handshake with kms.us-east-1.amazonaws.com using "KMS-TLS-1-2-2023-06" cipher policy
sleep 1 && ~/environment/local-installs/bin/s2nc -c KMS-TLS-1-2-2023-06 kms.us-east-1.amazonaws.com 443
# Wait 1 second, then kill all background jobs (which will stop the packet capture running in the background)
sleep 1 && sudo kill $(jobs -p)
# Start a background job to capture all packets to kms.us-east-1.amazonaws.com
sudo tcpdump "host kms.us-east-1.amazonaws.com" -s 0 -i any -w ~/environment/pq-tls-capture.pcap &
# Wait 1 second, then perform a Hybrid Post-Quantum TLS Handshake with kms.us-east-1.amazonaws.com using "default_pq" cipher policy
sleep 1 && ~/environment/local-installs/bin/s2nc -c default_pq kms.us-east-1.amazonaws.com 443
# Wait 1 second, then kill all background jobs (which will stop the packet capture running in the background)
sleep 1 && sudo kill $(jobs -p)
キャプチャしたら中身を見てみましょう。まずは従来の方式の場合。
ClientHelloではx25519、P-256、および P-384 楕円曲線のみとなっています。KeyShareはx25519のみが含まれ、長さは32バイトです。
ServerHelloではx25519を選択しています。
続いて耐量子暗号を利用する場合です。
ClientHelloではハイブリッド耐量子鍵交換の3つがグループに追加されています。ワークショップではWiresharkが新しい企画を識別できていませんでしたが、私のWiresharkでは適切に判定できていました。鍵は長くなっています。
ServerHelloもx25519_mlkem768が選択されていることが確認できました。
デモ4: 耐量子ファイル転送
このモジュールでは、AWS Transfer FamilyのSFTPサーバーでPQ ハイブリッドキー交換をします。
まずツールのセットアップをします。
# Download pre-compiled ssh artifacts
cd ~/environment
curl 'https://static.us-east-1.prod.workshops.aws/public/fea0b681-9702-4ce9-870c-f1683ba8c2cb/static/files/ubuntu-24.04/pq-ssh-cli-tools-local-installs.tar.gz' --output pq-ssh-cli-tools-local-installs.tar.gz
tar -xzvf pq-ssh-cli-tools-local-installs.tar.gz
利用するSSHキーペアを作成します。
# Generate an ECDSA keypair for SSH client authentication in SFTP
cd ~/environment/
ssh-keygen -t ecdsa -f ./pqsftpuser-ssh-key
# Print the SSH public key
cat ./pqsftpuser-ssh-key.pub
ワークショップの通りAWS Transfer FamilyでSFTPサーバーを建てます。
手順通りに進めて、セキュリティポリシーも同じものを選択します。
事前に作成したS3とSFTP用IAM Roleを設定します。
作成できたら、手順通りユーザーも作成します。
SFTPエンドポイントを指定しEC2から接続します。
cd ~/environment
./local-installs/openssh/bin/sftp -S ./local-installs/openssh/bin/ssh -v\
-o KexAlgorithms=mlkem768x25519-sha256\
-i pqsftpuser-ssh-key pqsftpuser@s-xxxxxxxxxx.server.transfer.ap-northeast-1.amazonaws.com
無事ML-KEMを利用して接続できました。
まとめ
耐量子暗号を利用してKMSの鍵交換をしたりSFTPで接続したり動きの詳細を見たりしていきました。
AWS LCを利用すればアプリケーション側にあまり手を加えなくても耐量子暗号に対応できたり、実際のハンドシェイクがどの様になるのか理解できました。
付録: PQCの詳細に関連する情報の解説などもありますので合わせてご確認ください。