本文へスキップ
ecdsa.com

Ed25519 鍵と RSA 鍵の比較|どの SSH 鍵を生成すべきか

新しい SSH 鍵なら、答えは何年も前から Ed25519 です。RSA を生成する理由として残っているのは互換性の欠落だけで、それも少なくなりつつあります。
比較対象Ed25519RSA

Ed25519 と RSA の比較が最もよく話題になるのは、ssh-keygen を実行するときに -t に何を渡すか迷う場面です。同じ比較は、コードやファイルへの署名にも当てはまります。Ed25519 は、非常に小さな鍵と高速で決定的な署名によって 128 ビットセキュリティを実現します。RSA は、はるかに大きなサイズと、より遅く壊れやすい鍵生成と引き換えに、あらゆる環境での互換性を提供します。

比較表

Ed25519RSA-3072
セキュリティ約 128 ビット約 128 ビット(RSA-2048 は 112)
秘密鍵32 バイトのシード3,072 ビットのモジュラスと CRT 値
公開鍵(生データ)32 バイト384 バイトのモジュラスと指数
OpenSSH の .pub の行(実測)86 バイト558 バイト
署名64 バイト384 バイト
署名 1 つの SSHSIG ファイル(実測)294 バイト1,211 バイト
鍵生成マイクロ秒単位平均約 100 ms、ばらつきが大きい
毎秒の署名・検証回数(OpenSSL 3.6.5)約 60,000 / 25,000約 1,000 / 54,000
SSH のアルゴリズム名ssh-ed25519、sk-ssh-ed25519@openssh.com鍵タイプは ssh-rsa、署名は rsa-sha2-256、rsa-sha2-512
OpenSSH の対応6.5(2014年)以降、9.5(2023年)以降はデフォルト当初から対応
決定的な署名ありPKCS #1 v1.5 はあり、PSS はランダム化
NIST IR 8547(ドラフト)2035年より後は使用禁止RSA-2048 は 2030年より後に非推奨、すべての RSA が 2035年より後は使用禁止

Apple M4 Max の 1 コアで、OpenSSH 10.3p1 と OpenSSL 3.6.5 を使って測定しました。

サイズと速度

同じ 128 ビットのセキュリティレベルで、Ed25519 の公開鍵は 32 バイト、RSA-3072 のモジュラスは 384 バイトです。SSH では、この差が authorized_keys、known_hosts、証明書、そしてすべてのハンドシェイクに現れます。公開鍵の行は Ed25519 が 86 バイトなのに対して RSA-3072 は 558 バイト、分離された SSH 署名ファイルは 294 バイトに対して 1,211 バイトです。

速度は非対称です。RSA は検証では Ed25519 より速い(この環境では毎秒約 54,000 回対 25,000 回)ものの、署名は約 60 倍遅く、鍵生成では 2 つの大きな素数を探索しなければなりません。この探索には、このマシンで RSA-3072 鍵 1 つあたり平均約 100 ミリ秒かかり、小型のデバイスでは大幅に長くかかることがあります。接続ごとにハンドシェイクに署名する SSH サーバーでは、Ed25519 のホスト鍵のほうが CPU 負荷が小さくなります。ユーザーにとっては、どちらも一瞬です。

表のサイズの数値は、次のスクリプトで得たものです。使っているのは OpenSSH だけです。

Ed25519 と RSA-3072 の SSH 鍵と署名を比較する
#!/bin/sh
dir=$(mktemp -d)
cd "$dir" || exit 1
ssh-keygen -q -t ed25519 -N "" -C demo -f id_ed25519
ssh-keygen -q -t rsa -b 3072 -N "" -C demo -f id_rsa
for k in id_ed25519 id_rsa; do
  echo "$k.pub: $(wc -c < $k.pub | tr -d ' ') bytes"
  printf 'hello\n' > "msg-$k"
  ssh-keygen -q -Y sign -f "$k" -n file "msg-$k"
  echo "signature file: $(wc -c < "msg-$k.sig" | tr -d ' ') bytes"
done
cd / && rm -rf "$dir"
OpenSSH 10.3p1 での出力
id_ed25519.pub: 86 bytes
signature file: 294 bytes
id_rsa.pub: 558 bytes
signature file: 1211 bytes

堅牢性と破綻のしかた

Ed25519 には調整項目がほとんどありません。曲線は 1 つ、ハッシュも 1 つ、nonce は決定的で、署名のエンコーディングも 1 つです。選ぶべきパディングはなく、誤って弱いパラメーターセットを選んでしまうこともありません。

RSA の歴史は、パラメーターとパディングの誤りの連続です。SSH の元来の ssh-rsa 署名アルゴリズムは SHA-1 でハッシュしますが、SHA-1 は選択プレフィックス衝突攻撃によって破られています。OpenSSH 8.8(2021年9月)はこれをデフォルトで無効にし、現在では RSA 鍵は rsa-sha2-256 または rsa-sha2-512(RFC 8332)で署名します。これは現行のクライアントとサーバーであれば自動的に行われます。短い鍵も落とし穴です。NIST は 2013年以降、署名用の 1024 ビット RSA を認めておらず、2048 ビットは NIST の 112 ビットのセキュリティレベルにあたります。NIST IR 8547 のドラフトは、これを 2030年より後に非推奨とすることを提案しています。欠陥のある鍵生成器は、共有された素数や構造を持つ素数を生み出してきました(ROCA の欠陥や、バッチ GCD で素因数分解できる鍵)。乱数生成器が正常に動作している限り、この種の失敗は Ed25519 のシードには存在しません。

互換性

Ed25519 は、OpenSSH 6.5 以降、PuTTY、Windows 組み込みの OpenSSH、GitHub、GitLab、Bitbucket、大半のクラウドコンソール、Linux の EC2 インスタンス、Git の SSH によるコミット署名で使えます。目立つ例外は、Amazon EC2 の Windows インスタンス(鍵で初期の Administrator パスワードを復号するため、鍵ペアは RSA でなければなりません)、一部のネットワークアプライアンスと組み込みの SSH 実装、そして非常に古いエンタープライズソフトウェアです。FIDO を利用する ed25519-sk 鍵には、EdDSA に対応した認証器が必要です。ハードウェアの選択肢としては、ecdsa-sk のほうが広くサポートされています。

RSA は SSH が動くあらゆる環境で使え、それが唯一の実質的な利点です。TLS 証明書では状況が逆になります。公的に信頼される CA は RSA と ECDSA の証明書を発行しますが、Ed25519 の証明書は発行しません。そのため、この比較は HTTPS ではなく SSH と署名を対象としています。

どちらを選ぶべきか

  • 個人の SSH 鍵と CI のデプロイキー:Ed25519 を使い、パスフレーズで保護するか、セキュリティキー上に保持します(ssh-keygen -t ed25519-sk)。
  • SSH のホスト鍵:Ed25519 を最初に提示します。古いクライアントが接続してくる間は RSA のホスト鍵(rsa-sha2-* のみ)を残し、その削除を計画します。
  • SSH 鍵によるコミットとファイルの署名:Ed25519 を使います。署名のサイズは 5 分の 1 で、検証のコマンドは同じです。
  • Windows の EC2 インスタンス、レガシーアプライアンス、更新できないシステム:RSA-3072 または RSA-4096 を使います。
  • PIV モードのハードウェアトークン:トークンが対応しているものを使います。多くの場合、Ed25519 ではなく RSA か ECDSA P-256 です。
  • 長期的な計画:どちらも量子コンピューターには耐えられません。OpenSSH はすでにポスト量子ハイブリッド鍵交換でセッション鍵を保護しており、OpenSSH 10.4 では署名用に ML-DSA-44 と Ed25519 を組み合わせた実験的な複合鍵タイプが追加されました。

移行時の注意点

RSA 鍵を Ed25519 に置き換える作業は、通常の鍵のローテーションです。

  1. ssh-keygen -t ed25519 -a 100(パスフレーズ用の KDF ラウンド数を増やす)で、またはセキュリティキー上で、新しい鍵を生成します。
  2. 古い鍵と並べて新しい鍵を配置します:各サーバーの authorized_keys に追記し、Git ホスティングのアカウントと構成管理にも追加して、ssh -i ~/.ssh/id_ed25519 でログインできることを確認します。
  3. ホスト鍵については、sshd_config に HostKey /etc/ssh/ssh_host_ed25519_key を追加します。UpdateHostKeys(現行の OpenSSH ではデフォルトで有効)を使うクライアントは新しい鍵を自動的に学習し、known_hosts のエントリーは RSA 鍵を削除する前に更新できます。
  4. 依存するものがなくなったら、authorized_keys、アカウント、エージェントから RSA 鍵を削除し、まだ RSA をネゴシエートしているクライアントがないかログを確認します。
  5. RSA を残さなければならない場合は、ssh-rsa(SHA-1)がどこでも再有効化されていないことを確認します。HostKeyAlgorithms や PubkeyAcceptedAlgorithms に +ssh-rsa がないかを探してください。ssh -Q HostKeyAlgorithms はクライアントが対応しているアルゴリズムを、nmap --script ssh2-enum-algos はサーバーが提示しているアルゴリズムを一覧表示し、SSH キーインスペクターは鍵の種類、サイズ、フィンガープリントを表示します。

参考資料

すべての比較