
AWS CloudTrailログでAPIエンドポイントとのPQC(耐量子暗号)通信を検証する
AWSのS3やKMSやSecrets Managerといった一部サービスは、エンドポイントとのTLS通信の鍵交換がPQC(耐量子暗号)に対応しています。
API呼び出し時にPQCが使用されているかを検証する方法として、クライアント側でtcpdump等を活用したパケットキャプチャがありますが、サーバー側でCloudTrailのログからも確認できます。
本記事では、CloudTrailの tlsDetails フィールドを使って、PQC対応の鍵交換が行われたかを検証する方法を解説します。
CloudTrailのtlsDetailsフィールドの keyExchange から確認
CloudTrailのイベントレコードには、TLS通信に関する情報を記録するtlsDetailsフィールドがあります。
"tlsDetails": {
"tlsVersion": "TLSv1.3",
"cipherSuite": "TLS_AES_128_GCM_SHA256",
"clientProvidedHostHeader": "secretsmanager.ap-northeast-1.amazonaws.com",
"keyExchange": "X25519MLKEM768"
}
この keyExchange フィールドを確認することで、PQC対応の鍵交換が行われたかを判断できます。
X25519MLKEM768 であれば PQC、x25519 であれば古典的な鍵交換が使用されたことを示します。
keyExchangeフィールドの値
keyExchangeフィールドの代表的な値は以下の通りです。
| 値 | 説明 |
|---|---|
| x25519 | TLS 1.2や1.3の古典的な鍵交換 |
| X25519MLKEM768 | TLS 1.3のPQCハイブリッド鍵交換 |
X25519MLKEM768はX25519(古典の楕円曲線暗号)とML-KEM-768(次世代のPQCの格子暗号)を組み合わせたハイブリッドの鍵交換方式です。
実行ログの例
PQC対応のAWS CLI、及び、cURLからAWSのAPIを呼び出し、CloudTrailログで keyExchange フィールドを確認した例を示します。
PQC通信結果がCloudTrailに素直に記録される例
Secrets ManagerにPQC通信した例です。
実行コマンド
aws secretsmanager list-secrets
CloudTrailイベント(抜粋)
{
...
"eventSource": "secretsmanager.amazonaws.com",
"eventName": "ListSecrets",
"awsRegion": "ap-northeast-1",
"userAgent": "aws-cli/2.32.29 md/awscrt#0.29.1 ...",
"tlsDetails": {
"tlsVersion": "TLSv1.3",
"cipherSuite": "TLS_AES_128_GCM_SHA256",
"clientProvidedHostHeader": "secretsmanager.ap-northeast-1.amazonaws.com",
"keyExchange": "X25519MLKEM768"
}
}
keyExchangeがX25519MLKEM768となっており、PQCハイブリッド鍵交換が使用されたことが確認できます。
PQC通信結果がCloudTrailに素直に記録されない例
APIエンドポイントがPQC対応していても、S3のように、CloudTrailには鍵交換(keyExchange)フィールドが記録されないサービスがあります。
実行コマンド
aws s3 mb s3://バケット名
CloudTrailイベント(抜粋)
"tlsDetails": {
"tlsVersion": "TLSv1.3",
"cipherSuite": "TLS_AES_128_GCM_SHA256",
"clientProvidedHostHeader": "xxx.s3.ap-northeast-1.amazonaws.com"
}
パケットキャプチャからは、PQC通信をしていることを確認できますが、CloudTrailからは、 TLS 1.3 で通信したことしかわかりません。
ドキュメントにも記載されています。
Note: PQ-TLS key exchange details for requests to Amazon S3 are not available in AWS CloudTrail events or S3 server access logs.
https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingEncryptionInTransit.PQ-TLS.html
TLS 1.2 通信の例
PQCはTLS 1.3を前提としています。
PQC非対応のTLS 1.2通信の例です。
実行コマンド
TLS 1.2t通信を強制するために、cURLの sigv4 オプションでリクエストしました。
curl -v --tlsv1.2 --tls-max 1.2 \
--user "$AWS_ACCESS_KEY_ID:$AWS_SECRET_ACCESS_KEY" \
--aws-sigv4 "aws:amz:ap-northeast-1:kms" \
-H "X-Amz-Security-Token: $AWS_SESSION_TOKEN" \
-H "Content-Type: application/x-amz-json-1.1" \
-H "X-Amz-Target: TrentService.ListKeys" \
-d "{}" \
"https://kms.ap-northeast-1.amazonaws.com/"
CloudTrailイベント(抜粋)
{
...
"eventSource": "kms.amazonaws.com",
"eventName": "ListKeys",
"awsRegion": "ap-northeast-1",
"userAgent": "curl/8.7.1",
"tlsDetails": {
"tlsVersion": "TLSv1.2",
"cipherSuite": "ECDHE-RSA-AES256-GCM-SHA384",
"clientProvidedHostHeader": "kms.ap-northeast-1.amazonaws.com",
"keyExchange": "x25519"
}
}
cipherSuite の ECDHE や keyExchange の x25519 から、TLS 1.2の古典的な楕円曲線の鍵交換が使用されたことが確認できます。
keyExchangeフィールドの追加背景
TLS 1.2では、暗号スイート名から鍵交換方式を特定できました。例えば ECDHE-RSA-AES256-GCM-SHA384という暗号スイートであれば、鍵交換はECDHEであることがわかります。
一方、TLS 1.3では暗号スイートの命名規則が変わり、TLS_AES_128_GCM_SHA256のように鍵交換方式が含まれなくなりました。
この変更に対応するため、CloudTrailには keyExchange フィールドが追加されています。
TLSのバージョンによらず、 keyExchange フィールドを確認するだけで一貫して鍵交換方式を確認できるようになりました。
AWSサービスによるAPI呼び出しで keyExchange は記録されない
AWSサービスが代理でAPI呼び出しを行う場合(例: Lambda関数からのAPI呼び出し)、tlsDetailsフィールド自体が記録されないことがあります。
この場合、CloudTrailイベントのuserIdentity.invokedByフィールドに呼び出し元のAWSサービスが記録されます。
まとめ
AWS CloudTrailのtlsDetails.keyExchangeフィールドから、API呼び出し時にPQC対応の鍵交換が使用されたか確認できます。クライアント側で特別な作業をすることなく、サーバー側で一括して確認できるため、非常に便利です。
"tlsDetails": {
"tlsVersion": "TLSv1.3",
"cipherSuite": "TLS_AES_128_GCM_SHA256",
"clientProvidedHostHeader": "secretsmanager.ap-northeast-1.amazonaws.com",
"keyExchange": "X25519MLKEM768"
}
tlsDetails.keyExchange が X25519MLKEM768 であれば、古典と耐量子(PQC)のハイブリッド鍵交換が行われたことを示します。
x25519 であれば、古典的な鍵交換が行われていることを示します。
以下のように、 keyExchange フィールドが記録されないケースもあることにご注意ください
- S3 のように一部サービスはPQC通信していても
keyExchangeフィールドが記録されない(参考) - AWSサービスによるAPI呼び出しの場合、
tlsDetailsフィールド自体が記録されない(userIdentityから呼び出し元サービスを確認可能)
詳細は、次のドキュメントをご確認ください。










