本文へスキップ
ecdsa.com

P-256 と P-384 の比較|192 ビットの ECDSA が割に合う場面

P-384 は、ほとんどのシステムには不要なセキュリティマージンと引き換えに、署名ごとに約 10 倍の CPU 時間と少し多めの容量を必要とします。それでも P-384 を要求するポリシーはあります。

P-256 と P-384 のどちらを使うかは、同じファミリーに属する 2 つの NIST 曲線から選ぶ問題です。アルゴリズム(ECDSA と ECDH)も、エンコーディングも、ツールも共通です。P-384 は古典的セキュリティを約 128 ビットから約 192 ビットに引き上げ、P-256 は数倍高速で、対応するハードウェアも多くあります。ほとんどのシステムでは、リスクよりもポリシーによって判断が決まります。

比較表

P-256(secp256r1)P-384(secp384r1)
有限体のサイズ、群の位数256 ビット384 ビット
古典的セキュリティ約 128 ビット(AES-128 相当)約 192 ビット(AES-192 相当)
通常組み合わせるハッシュ関数SHA-256SHA-384
秘密鍵32 バイト48 バイト
公開鍵非圧縮形式で 65 バイト、SPKI DER で 91 バイト非圧縮形式で 97 バイト、SPKI DER で 120 バイト
署名生形式で 64 バイト、DER で 70〜72 バイト生形式で 96 バイト、DER で約 102〜104 バイト
1 秒あたりの署名数・検証数(OpenSSL 3.6.5)約 87,000 / 29,000約 9,700 / 4,500
JOSE / COSEES256 / −7ES384 / −35
TLS 1.3ecdsa_secp256r1_sha256(0x0403)、グループ 23ecdsa_secp384r1_sha384(0x0503)、グループ 24
ハイブリッド TLS グループSecP256r1MLKEM768SecP384r1MLKEM1024
Secure Enclave、Android Keystore、TPM 2.0対応製品による(Secure Enclave は非対応)
NIST IR 8547(ドラフト)2035年より後は禁止2035年より後は禁止

速度は Apple M4 Max の 1 コアで openssl speed を使って測定しました。後述のサイズを調べるスクリプトは OpenSSL 3.6.5 で実行しました。

必要なセキュリティの水準

NIST SP 800-57 Part 1 は、256〜383 ビットの曲線を 128 ビットセキュリティに、384〜511 ビットの曲線を 192 ビットセキュリティに位置付けています。128 ビットは、予見できるどのような古典的攻撃もはるかに及ばない水準です。P-256 に対する既知の最良の攻撃でも、2¹²⁸ のオーダーの群演算が必要です。P-384 の追加のマージンは、総当たり攻撃ではなく、楕円曲線の暗号解読が予想外に進歩した場合への備えです。また、2 つの曲線をほぼ同じ労力で破る Shor のアルゴリズムに対しては、何の効果もありません。そのため NIST IR 8547(初期公開ドラフト)は両者を同じように扱っています。どちらも 2030年に非推奨になることはなく(非推奨の対象は RSA-2048 や P-224 のような 112 ビットのアルゴリズムだけです)、どちらも 2035年より後は禁止されます。

実際に判断を左右するのはポリシーです。NSA が当初定めた Commercial National Security Algorithm Suite(CNSA 1.0)は ECDH と ECDSA に P-384 を要求していたため、米国の国家安全保障システム向けの製品とそのサプライチェーンでは P-384 がデフォルトになっています。CNSA 2.0 では、これが ML-KEM-1024 と ML-DSA-87 に置き換えられます。認証局は、10 年以上にわたって信頼に足る状態を保たなければならないルート CA と中間 CA の鍵に、P-384 を選ぶことがよくあります。Let's Encrypt の ISRG Root X2 と ECDSA の中間証明書は P-384 ですが、サブスクライバー証明書にはどちらの曲線も使えます。

性能とサイズのコスト

OpenSSL には P-256 向けに手作業で最適化されたアセンブリコードが含まれているため、差が大きくなります。Apple M4 Max の 1 コアで、署名は P-256 が毎秒約 87,000 回、P-384 が約 9,700 回、検証は約 29,000 回と 4,500 回です。TLS サーバーでは、証明書の鍵による署名はフルハンドシェイクごとに 1 回なので、P-384 にするとハンドシェイクのその部分のコストが約 9 倍になります。毎秒数枚の証明書に署名する程度の認証局にとっては、この差は問題になりません。

サイズの増加はわずかです。署名は生形式で 32 バイト、公開鍵は 32 バイト、証明書は約 60 バイト大きくなります。

P-256 と P-384 の鍵、署名、証明書のサイズ
#!/bin/sh
dir=$(mktemp -d)
cd "$dir" || exit 1
printf 'hello' > msg
for curve in P-256 P-384; do
  openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:$curve -out key.pem 2>/dev/null
  openssl req -new -x509 -key key.pem -subj "/CN=example.com" -days 90 -outform DER -out cert.der 2>/dev/null
  openssl dgst -sha256 -sign key.pem -out sig.der msg
  printf '%s: SPKI %s bytes, DER signature %s bytes, self-signed certificate %s bytes\n' "$curve" \
    "$(openssl pkey -in key.pem -pubout -outform DER | wc -c | tr -d ' ')" \
    "$(wc -c < sig.der | tr -d ' ')" \
    "$(wc -c < cert.der | tr -d ' ')"
done
cd / && rm -rf "$dir"
出力(DER のサイズは実行ごとに 1〜2 バイト変わります)
P-256: SPKI 91 bytes, DER signature 71 bytes, self-signed certificate 388 bytes
P-384: SPKI 120 bytes, DER signature 102 bytes, self-signed certificate 451 bytes

対応状況

どちらの曲線も、FIPS 186-5 と SP 800-186、すべての TLS ライブラリ、WebCrypto、JOSE と COSE、PIV スマートカード、そして CA/Browser Forum が証明書に認める鍵のリスト(P-256、P-384、P-521)に含まれています。差があるのはセキュアハードウェアと認証器です。Apple の Secure Enclave が古典的な鍵として提供するのは P-256 だけで、パスキーはほぼ例外なく ES256 を使い、IoT 向けのセキュアエレメントには P-256 しか実装していないものもあります。サーバー側では、HSM とクラウドの KMS サービスが両方に対応しています。

それぞれの用途

  • 公開 TLS 証明書:P-256 を使います。ハンドシェイクが高速で、どこでも受け入れられます。P-384 のリーフ証明書にしても、クライアントが検証できる利点は何も得られません。
  • CA のルート鍵と中間鍵:長期間使う鍵には P-384 が一般的で妥当な選択です。その鍵で P-256 のリーフ証明書に署名してもかまいません。
  • JWT と API トークン:ES256 を使います。ただし、一部の政府機関や金融業界の仕様のようなプロファイルが ES384 を要求する場合は別です。
  • パスキーとデバイスの鍵:P-256 を使います。ハードウェアが提供しているのが P-256 だからです。
  • CNSA 1.0 のシステムとそのベンダー:P-384 と SHA-384、そして AES-256 を使います。CNSA 2.0 に基づく ML-KEM-1024 と ML-DSA-87 への移行を計画してください。
  • ハイブリッドのポスト量子 TLS:一般的な用途には X25519MLKEM768 を使います。CNSA のようなポリシーが NIST 曲線とカテゴリ 5 のパラメーターを求める場合は SecP384r1MLKEM1024 を使います。

移行時の注意点

曲線を変更すると鍵は新しくなりますが、ツールはそのまま使えます。

  1. 新しい鍵を生成する:鍵を保管する HSM または KMS の内部で、openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-384(または P-256)を使って生成します。
  2. ハッシュ関数を正しく組み合わせる:P-384 は通常 SHA-384 と組み合わせて使います(ES384、ecdsa-with-SHA384)。ECDSA は長いハッシュ値を位数の長さに切り詰めますが、組み合わせが一致していないと、ポリシーのチェックや一部の検証者が混乱します。
  3. 識別子を更新する:JOSE の alg と crv、COSE のアルゴリズム、TLS の署名方式、証明書プロファイルを更新します。鍵のローテーション中は、別々の kid 値を付けた両方の鍵を JWKS で公開してください。
  4. 固定長バッファーのサイズを変更する:生形式の署名は 64 バイトから 96 バイトに、座標は 32 バイトから 48 バイトに大きくなります。
  5. ハンドシェイクのベンチマークを取る:負荷の高い TLS エンドポイントを P-384 の証明書に切り替える前に計測してください。ポリシー上の理由で P-384 に移行する環境の多くは、ポリシーが適用されない部分では P-256 を使い続けています。

参考資料

すべての比較