Amazon Web Services ブログ

AWS KMS と ML-DSA を使用してポスト量子署名を作成する方法

本ブログは 2025 年 6 月 13 日に公開された AWS Blog “How to create post-quantum signatures using AWS KMS and ML-DSA” を翻訳したものです。

量子コンピューティングの能力が進化し続ける中、AWS は、公開鍵暗号に対する新たな脅威にお客様が先手を打てるよう取り組んでいます。本日 (2025 年 6 月 13 日)、FIPS 204: ML-DSA (Module-Lattice-Based Digital Signature Standard)AWS Key Management Service (AWS KMS) でのサポート開始を発表します。デジタル署名に使用している既存の AWS KMS API (CreateKeySignVerify オペレーションなど) を通じて、ML-DSA キーの作成と使用が可能になりました。この新機能は一般提供されており、米国西部 (北カリフォルニア) および欧州 (ミラノ) の AWS リージョンで ML-DSA を使用できます。残りの商用リージョンも数日以内に対応予定です。今回のリリースは、先日のブログ記事で紹介した、AWS のより広範なポスト量子暗号移行計画の一環です。この記事では、AWS KMS を使用して ML-DSA キーを作成し、ポスト量子署名を生成する手順を説明します。

多くの組織が AWS KMS を使用して、ファームウェア、オペレーティングシステム、アプリケーション、その他のアーティファクトにデジタル署名を行っています。AWS KMS で ML-DSA をサポートしたことにより、FIPS 140-3 レベル 3 認定の HSM 内でポスト量子キーを生成し、署名・検証処理に使用できるようになりました。ML-DSA 署名を今から導入しておけば、暗号解読能力を持つ量子コンピュータ (CRQC) が利用可能になった場合でも、システムの運用期間全体を通じてセキュリティを維持できます。これは、長期間有効な信頼の基点を製造段階でデバイスに組み込むメーカーにとって特に重要です。ハードウェアに直接組み込む場合でも、長期間オフラインのままになる可能性のあるデバイスに組み込む場合でも同様です。いずれの場合も、出荷後にデジタル署名を簡単に更新することはできないため、システムの運用期間全体にわたるポスト量子対応が不可欠です。

新機能

AWS KMS では、3 つの新しい AWS KMS キースペック (ML_DSA_44ML_DSA_65ML_DSA_87) が利用可能になりました。これらは新しいポスト量子 SigningAlgorithm である ML_DSA_SHAKE_256 と組み合わせて使用します。他の署名アルゴリズムと同様に、この名前には、署名スキーム内で署名または検証の前にメッセージをダイジェストするために使用されるハッシュ関数が含まれています。ここで使用されるハッシュ関数は、NIST が FIPS 202 で標準化した SHA-3 ファミリーに属する SHAKE256 です。

表 1 に、各キースペックの詳細 (NIST セキュリティカテゴリおよび対応するキーサイズ (バイト単位) など) を示します。各 ML-DSA キースペックは、セキュリティ強度とリソース要件のバランスが異なります。ML-DSA-44 は従来の 128 ビット暗号化に匹敵するセキュリティが必要なアプリケーションに適しています。一方、ML-DSA-65 と ML-DSA-87 はそれぞれ従来の 192 ビットおよび 256 ビット暗号化に相当する、より強力なセキュリティレベルを提供します。セキュリティレベルが上がるにつれてキーと署名のサイズも大きくなるため、セキュリティ要件とエンジニアリング上の制約に応じて最適なキースペックを選択できます。

Key spec NIST security Level Public key (B) Private key (B) Signature (B)
ML_DSA_44 1 (128 ビットセキュリティ相当) 1,312 2,560 2,420
ML_DSA_65 3 (192 ビットセキュリティ相当) 1,952 4,032 3,309
ML_DSA_87 5 (256 ビットセキュリティ相当) 2,592 4,896 4,627

AWS KMS Sign API を RAW MessageType で使用する場合、署名対象のメッセージは 4,096 バイトに制限されます。4,096 バイトを超えるメッセージに署名するには、KMS Sign API への入力サイズを削減するために、AWS KMS の外部でメッセージを前処理して µ (mu) を作成する必要があります。この external mu プロセスでは、ML-DSA 署名キーペアの公開鍵を使用してメッセージをプリハッシュし、メッセージサイズを 64 バイトに縮小します。今回のリリースに合わせて、KMS Sign API に新しいメッセージタイプ EXTERNAL_MU を追加しました。これは ML-DSA の署名または検証の呼び出しで使用でき、AWS KMS に送信する前にメッセージが µ (mu) を使用して前処理済みであることを示します。

以降のセクションでは、external mu の作成方法を詳しく説明し、ML-DSA を使用した AWS KMS の基本的な操作を紹介します。キーの作成、署名の生成と検証について、RAWEXTERNAL_MU の両方の署名モードを取り上げます。なお、同じメッセージと署名キーを使用した場合、RAWEXTERNAL_MU のどちらで生成しても ML-DSA 署名は同一になります。

ML-DSA キーの作成

まず、AWS コマンドラインインターフェイス (AWS CLI) を使用して、以下のコマンドで非対称 AWS KMS キーを作成します。

aws kms create-key --key-spec ML_DSA_65 --key-usage SIGN_VERIFY

このコマンドは、以下のようなレスポンスを返します。

{
    "KeyMetadata": {
        "Origin": "AWS_KMS",
        "KeyId": "1234abcd-12ab-34cd-56ef-1234567890ab",
        "MultiRegion": false,
        "Description": "",
        "KeyManager": "CUSTOMER",
        "Enabled": true,
        "SigningAlgorithms": [
            "ML_DSA_SHAKE_256"
        ],
        "CustomerMasterKeySpec": "ML_DSA_65",
        "KeyUsage": "SIGN_VERIFY",
        "KeySpec": "ML_DSA_65",
        "KeyState": "Enabled",
        "CreationDate": 1748371316.734,
        "Arn": "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab",
        "AWSAccountId": "111122223333"
    }
}

レスポンスに含まれる KeyId または Arn の値を控えておいてください。以降の署名操作でキーを参照する際に必要になります。このレスポンスから、SIGN_VERIFY オペレーション用に ML_DSA_65 キーが作成され、署名オペレーションには ML_DSA_SHAKE_256 署名アルゴリズムが使用されることを確認できます。

署名

このセクションでは、Web における認可処理において当事者間のクレーム受け渡しに広く使われている JSON Web Token (JWT) を例に、ML-DSA による署名と検証の方法を紹介します。2021 年には、従来の非対称暗号アルゴリズムである楕円曲線デジタル署名アルゴリズム (ECDSA) を使用した JWT の署名と検証の方法を紹介しました (「How to verify AWS KMS signatures in decoupled architectures at scale」を参照)。以下の例では、AWS KMS で管理される ML-DSA プライベートキーで JWT に署名し、AWS KMS 内または OpenSSL を使用して外部で検証します。

署名対象の JWT コンテンツは、RFC7519 のセクション 3.1 に基づいています。JWT ヘッダーは以下のとおりです。

{"typ":"JWT",
 "alg":"ML-DSA-65"}

JWT クレームセットは以下のとおりです。

{"iss":"joe",
 "exp":1748952000,
 "http://example.com/is_root":true}

ヘッダーとペイロードを Base64URL エンコードすることで、署名対象の JWT メッセージを生成できます。

echo -n -e '{"typ":"JWT",\015\012 "alg":"ML-DSA-65"}' | \
	basenc --base64url -w 0 | \
	sed 's/=//g' ; echo -n "." ; echo -n -e '{"iss":"joe",\015\012 "exp":1748952000,\015\012 "http://example.com/is_root":true}' | \
	basenc --base64url -w 0 | sed 's/=//g' ; echo ""

このコマンドは、ML-DSA で署名する対象となる以下の Base64 文字列を出力します。

eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJNTC1EU0EtNjUifQ.eyJpc3MiOiJqb2UiLA0KICJleHAiOjE3NDg5NTIwMDAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ

以下の例では、AWS KMS で管理される ML-DSA プライベートキーを使用してメッセージの ML-DSA 署名を生成し、バイナリ形式で出力します。JWT で使用するには Base64URL に変換する必要がありますが、この署名はさまざまなデータ暗号化および署名形式で利用できます。具体的には、Cryptographic Message Syntax (CMS)、CBOR Object Signing and Encryption (COSE)、UEFI や Open Titan のイメージ署名エンコーディングなどが挙げられます。バイナリからこれらの形式への変換は容易ですが、本記事の執筆時点では、一般的な暗号ライブラリの実装において新しいアルゴリズムのサポートがまだ利用できない場合があります。

RAW モードでの ML-DSA 署名

4,096 バイト未満のメッセージに AWS KMS で ML-DSA 署名を行うには、以下のように AWS CLI を使用します。

aws kms sign \
    --key-id <1234abcd-12ab-34cd-56ef-1234567890ab> \
    --message ' eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJNTC1EU0EtNjUifQ.eyJpc3MiOiJqb2UiLA0KICJleHAiOjE3NDg5NTIwMDAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ' \
    --message-type RAW \
    --signing-algorithm ML_DSA_SHAKE_256 \
    --output text \
    --query Signature | base64 --decode > ExampleSignature.bin

target-key-id の値 <1234abcd-12ab-34cd-56ef-1234567890ab> を実際の KeyId に置き換えてください。このコマンドは署名を生成し、ExampleSignature.bin としてディスクに書き込みます。

署名を生成したら、以下のコマンドでヘッダー、ペイロード、署名から構成される完全な JWT を作成できます。

echo -n "eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJNTC1EU0EtNjUifQ.eyJpc3MiOiJqb2UiLA0KICJleHAiOjE3NDg5NTIwMDAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ." ; \
	basenc --base64url -w 0 ExampleSignature.bin | \
	sed 's/=//g' ; echo ""

このコマンドは、RFC 7519 で要求される形式に準拠した、AWS KMS で署名済みの JWT を出力します。

eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJNTC1EU0EtNjUifQ.eyJpc3MiOiJqb2UiLA0KICJleHAiOjE3NDg5NTIwMDAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.<base64url of the signature as per RFC7519>

external mu モードでの ML-DSA 署名

AWS KMS では、Sign API 使用時のレスポンスレイテンシーを最小限に抑えるため、RAW メッセージのサイズを 4,096 バイトに制限しています。署名対象のメッセージが 4,096 バイトを超える場合や、external mu のプリハッシュによるパフォーマンス上のメリットを活用したい場合は、RAW の代わりに EXTERNAL_MU メッセージタイプを使用する必要があります。

AWS KMS Sign API で EXTERNAL_MU メッセージタイプを使用するには、事前にローカルでメッセージのプリハッシュ計算を行う必要があります。まず、以下のコマンドで AWS KMS から公開鍵を取得し、DER 形式に変換します。下記の例のキー ID は、実際の AWS アカウントの有効なキー ID に置き換えてください。

aws kms get-public-key \
    --key-id <1234abcd-12ab-34cd-56ef-1234567890ab> \
    --output text \
    --query PublicKey | base64 --decode > public_key.der

external mu ダイジェストの作成手順は以下のとおりです。

  1. メッセージプレフィックス (M`) を作成します M` = (domain separator || context length || context || Message)

    この例では、ドメインセパレータの値とコンテキスト長をゼロに設定します。これにより、署名で使用されるコンテキストが空文字列 (デフォルト) になります。

  2. 公開鍵をハッシュし、メッセージプレフィックスの先頭に付加します
    (SHAKE256(pk) || M')
  3. ハッシュして 64 バイトの mu を生成します
    Mu = SHAKE256(SHAKE256(pk) || M')

OpenSSL 3.5 では、以下の単一コマンドでダイジェストを作成できます。

{
    openssl asn1parse -inform DER -in public_key.der -strparse 17 -noout -out - 2>/dev/null |
    openssl dgst -provider default -shake256 -xoflen 64 -binary;
    printf '\x00\x00';
    echo -n "eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJNTC1EU0EtNjUifQ.eyJpc3MiOiJqb2UiLA0KICJleHAiOjE3NDg5NTIwMDAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ"
} | openssl dgst -provider default -shake256 -xoflen 64 -binary > mu.bin

これで、AWS KMS を呼び出して 64 バイトのダイジェストに署名し、ML-DSA 署名をファイル ExampleSignature.bin に出力できます。MessageTypeEXTERNAL_MU に設定してください。

aws kms sign \
    --key-id 1234abcd-12ab-34cd-56ef-1234567890ab \
    --message fileb://mu.bin \
    --message-type EXTERNAL_MU \
    --signing-algorithm ML_DSA_SHAKE_256 \
    --output text \
    --query Signature | base64 --decode > ExampleSignature.bin

最終的に署名された JWT トークンは、前述の RAW モードで生成されたものと同一です。

AWS KMS を使用した署名検証

このセクションでは、AWS KMS またはローカル環境で ML-DSA 署名を検証する方法を説明します。ここでは、AWS KMS 内のプライベートキーを使用して JWT コンテンツに対して生成された ML-DSA 署名が ExampleSignature.bin に格納されており、KEY_ARN で識別されることを前提とします。

以下の例では、AWS KMS から直接取得した公開鍵を使用した署名検証を示していますが、これらの原則はプライベート PKI などの証明書ベースのシステムにも適用できます。プライベート PKI では、公開鍵は署名者のエンドエンティティ証明書に埋め込まれています。このようなシナリオでは、検証者はまず証明書チェーンが信頼されたルート証明書に結びついていることを検証して署名者の身元を確認し、次にエンドエンティティ証明書の公開鍵を使用してコンテンツの ML-DSA 署名を検証します。IETF は、RFC ドラフト draft-ietf-lamps-dilithium-certificates を通じて、X.509 証明書での ML-DSA の使用を標準化しています。

RAW モードでの ML-DSA 検証

AWS KMS を使用して署名を検証するには、以下のコマンドを実行します。例の key-id は、署名時に使用したものと同じキー ID に置き換えてください。

aws kms verify \
    --key-id <1234abcd-12ab-34cd-56ef-1234567890ab> \
    --message "eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJNTC1EU0EtNjUifQ.eyJpc3MiOiJqb2UiLA0KICJleHAiOjE3NDg5NTIwMDAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ" \
    --message-type RAW \
    --signing-algorithm ML_DSA_SHAKE_256 \
    --signature fileb://ExampleSignature.bin

以下のようなレスポンスが返されます。

{
    "KeyId": "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab",
    "SignatureValid": true,
    "SigningAlgorithm": "ML_DSA_SHAKE_256"
}

検証結果は SignatureValid フィールドで確認できます。

external mu モードでの ML-DSA 検証

JWT コンテンツの external mu ダイジェストが mu.bin に格納されており、署名と対応するキーペアが AWS KMS にある場合、メッセージ全体にアクセスしたりダイジェストを再計算したりすることなく、このダイジェストを使用して検証できます。

aws kms verify \
    --key-id <1234abcd-12ab-34cd-56ef-1234567890ab> \
    --message fileb://mu.bin \
    --message-type EXTERNAL_MU \
    --signing-algorithm ML_DSA_SHAKE_256 \
    --signature fileb://ExampleSignature.bin

メッセージと公開鍵から external mu mu.bin を再生成する方法については、前述の 「external mu モードでの ML-DSA 署名」セクションを参照してください。

OpenSSL 3.5 を使用したローカル署名検証

ML-DSA 署名の生成には AWS KMS で生成・保管されたキーのセキュリティを維持しつつ、API の呼び出しコストを削減し、API クォータの使用をより細かく制御したい場合は、AWS KMS の外部でローカルに ML-DSA 署名を検証できます。

この例では、OpenSSL 3.5 を使用して ExampleSignature.bin の署名を検証します。まず、「external mu モードでの ML-DSA 署名」セクションで示したように、AWS KMS から DER エンコードされた公開鍵を取得し、ファイル public_key.der に保存する必要があります。OpenSSL 3.5 では、この公開鍵を使用してメッセージの署名を検証できます。

echo -n "eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJNTC1EU0EtNjUifQ.eyJpc3MiOiJqb2UiLA0KICJleHAiOjE3NDg5NTIwMDAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ" | \
	openssl dgst -verify public_key.der -signature ExampleSignature.bin

検証が成功すると、Verified OK と出力されます。

まとめ

本日 (2025 年 6 月 13 日) の AWS KMS における ML-DSA サポートの開始は、ポスト量子暗号に対する AWS の取り組みにおける重要なマイルストーンです。3 段階のセキュリティレベルと RAW・external mu の 2 つの署名モードにより、量子コンピューティング時代を見据えたセキュリティ要件に柔軟に対応できます。既存の AWS KMS API とシームレスに統合できるため、量子コンピュータに耐性のある署名を今すぐアプリケーションに組み込むことが可能です。この実装は、以下のようなユースケースで特に効果を発揮します。

  • ポスト量子暗号の使用時に FIPS 140-3 準拠要件を満たす必要がある場合
  • コード、アーティファクト、ドキュメントなどに対して、暗号解読能力を持つ量子コンピュータ (CRQC) が実現した後も長期間にわたって検証可能な署名を付与する必要がある場合
  • AWS KMS のような承認済みの暗号サービスを活用し、アプリケーション開発プロセスの一環としてポスト量子暗号のテストを開始する場合

ポスト量子暗号全般、および AWS のポスト量子暗号への移行計画の詳細についてはリンク先をご覧ください。

Jake Massimo

Jake Massimo

Jake は AWS Cryptography チームの Applied Scientist です。国際会議、学術研究、標準化団体への積極的な参加を通じて、Amazon とグローバルな暗号コミュニティの橋渡し役を担っています。クラウド規模でのポスト量子暗号技術の導入推進に取り組んでおり、現在は AWS 暗号ライブラリにおいて、最適化され形式的に検証されたポスト量子アルゴリズムの開発をリードしています。

Panos Kampanakis

Panos Kampanakis

Panos はサイバーセキュリティ、応用暗号、セキュリティ自動化、脆弱性管理に関する豊富な経験を持っています。長年にわたり、技術イベントでさまざまなセキュリティトピックに関するトレーニングやプレゼンテーションを行ってきました。サイバーセキュリティに関する出版物を共同執筆し、セキュリティ情報共有、暗号、PKI のための共通の相互運用可能なプロトコルや言語を提供するさまざまなセキュリティ標準化団体に参加しています。

Mayank Ambaliya

Mayank Ambaliya

Mayank は AWS Key Management Service (AWS KMS) の Software Development Manager です。AWS KMS の暗号 API およびカスタムキーストアの開発をリードしています。AWS CloudHSM のお客様向け暗号 API および暗号 SDK の開発経験があり、最近では AWS KMS でのポスト量子アルゴリズムサポートや新しい暗号 API の追加に取り組んでいます。

本ブログは Security Solutions Architect の 中島 章博 が翻訳しました。