【2026年最新】SSL証明書の鍵はECDSAとRSAどっちを選ぶ?実測したら署名は約16倍、検証は逆にRSAが4倍だった

※本ページには広告(アフィリエイトプログラム等)が含まれます。

※本ページには広告(アフィリエイトプログラム等)が含まれます。数値は 2026年8月17日時点で稼働中のさくらの VPS(Debian 12.15・2 vCPU・メモリ 958MB)で採取した実測値です。

🎯 結論:迷ったら ECDSA。ただし「速い」のは署名だけ

結論から書きます。2026年8月時点で一般的な Web サイトを運用するなら ECDSA P-256 です。理由は「ECDSA のほうが速いから」ではありません。TLS ハンドシェイクで重い仕事=署名がサーバー側にあり、そこが約 16 倍速いからです。

手元の本番機で openssl speed を叩いたところ、署名は RSA 2048 の 2,414.2 回/秒に対して ECDSA P-256 が 37,711.4 回/秒でした。ところが検証は逆転して、RSA が 48,826.3 回/秒、ECDSA は 12,078.9 回/秒しか出ません。

この非対称が今回いちばん面白かった点です。ネットでよく見る「ECDSA は速い」は、サーバー側の署名についてだけ正しい

観点 速いのは 実測比
署名(サーバーが毎回やる仕事) ECDSA 約 16 倍
署名・同じ強度で比較(RSA 3072 対 P-256) ECDSA 約 80 倍
検証(ブラウザ側がやる仕事) RSA 4.0 倍
鍵の生成 ECDSA 約 59 倍
秘密鍵のファイルサイズ ECDSA 7.5 倍小さい
フルハンドシェイク(TLS 1.3・同一機) ECDSA 約 1.4 倍
  • 普通の Web サイト → ECDSA P-256(certbot 2.x なら何もしなくてもこれになる)
  • 同時接続が多いサイト → ECDSA P-256(署名 2,414.2 → 37,711.4 回/秒の差がそのまま効く)
  • ⚠️ Windows XP 世代の相手が実在する → RSA 2048 を併用
  • とりあえず強度を上げたい → RSA 3072 は署名が 474.0 回/秒まで落ちる。P-256 のほうが強度も速度も上

以下、測り方と生の出力を全部載せます。同じスクリプトを自分のサーバーで走らせれば再現できます。

検証環境と、きっかけ

Let's Encrypt の証明書を更新したついでに「そもそも今どっちの鍵で運用しているのか」を確認したのが発端でした。42 枚あるすべてが ECDSA でした。certbot 2.x の既定がそうなっているためで、意識して選んだ覚えはありません。

$ grep -h "^key_type" /etc/letsencrypt/renewal/*.conf | sort | uniq -c
     42 key_type = ecdsa

$ ls /etc/letsencrypt/renewal/*.conf | wc -l
42

知らないうちに既定値に乗っていたわけです。それなら差を数字で押さえておこうと考えて計測しました。

項目
サーバー さくらの VPS(本番稼働中)
OS Debian 12.15(bookworm)
CPU 2 vCPU / Intel Xeon(Sapphire Rapids)
メモリ 958MB
OpenSSL 3.0.20
Web サーバー nginx 1.22.1 / certbot 2.1.0
測定日 2026年8月17日

CPU の拡張命令は aes rdrand avx2 bmi2 avx512f adx sha_ni が有効でした。AES-NI と SHA-NI があるので、対称暗号の側は十分速い環境です。

本番機ですが、設定は一切変更していません。証明書は /tmp に自己署名を作り、待受はループバックの高番ポートだけ。終了時に消しています。

検証方法(使ったスクリプト全文)

署名と検証の素の速度

$ openssl speed -seconds 3 rsa2048 ecdsap256

鍵の生成時間とファイルサイズ

ms() { date +%s%3N; }

s=$(ms); for i in $(seq 10); do openssl genrsa -out rsa.key 2048 2>/dev/null; done; e=$(ms)
echo "RSA2048 keygen x10: $((e-s)) ms"

s=$(ms); for i in $(seq 10); do openssl ecparam -name prime256v1 -genkey -noout -out ec.key 2>/dev/null; done; e=$(ms)
echo "EC P-256 keygen x10: $((e-s)) ms"

openssl req -x509 -new -key rsa.key -out rsa.crt -days 90 -subj "/CN=bench.local"
openssl req -x509 -new -key ec.key  -out ec.crt  -days 90 -subj "/CN=bench.local"
openssl x509 -in rsa.crt -outform DER -out rsa.der
openssl x509 -in ec.crt  -outform DER -out ec.der
stat -c "%n %s" rsa.key ec.key rsa.crt ec.crt rsa.der ec.der

フルハンドシェイクの回数

for pair in "rsa:14431" "ec:14432"; do
  n="${pair%%:*}"; p="${pair##*:}"
  openssl s_server -accept "127.0.0.1:$p" -cert "$n.crt" -key "$n.key" -tls1_3 -www -quiet &
  sp=$!; sleep 1
  openssl s_time -connect "127.0.0.1:$p" -new -time 5
  kill $sp; wait $sp 2>/dev/null
done

-tls1_3-tls1_2 に替えれば TLS 1.2 も同じ手順で測れます。

実測 1:署名は ECDSA、検証は RSA

生の出力

                  sign    verify    sign/s verify/s
rsa 2048 bits 0.000414s 0.000020s   2414.2  48826.3
                              sign    verify    sign/s verify/s
 256 bits ecdsa (nistp256)   0.0000s   0.0001s  37711.4  12078.9

数字に直すとこうなる

項目 RSA 2048 ECDSA P-256
署名 2,414.2 回/秒 37,711.4 回/秒 ECDSA が約 16 倍
検証 48,826.3 回/秒 12,078.9 回/秒 RSA が 4.0 倍
署名 1 回あたり 0.414 ms 0.027 ms −0.387 ms
検証 1 回あたり 0.020 ms 0.083 ms +0.063 ms

どちらが自分の負担になるのか

TLS ハンドシェイクでサーバーがやるのは署名ブラウザがやるのは検証です。つまりサーバー運用者から見れば、遅くなるほうの仕事は相手のマシンで動きます。

しかも ECDSA の検証は 12,078.9 回/秒=1 回 0.083 ms です。絶対値がこれだけ小さいと、閲覧者の体感には出てきません。一方でサーバー側は 1 ハンドシェイクあたり 0.414 ms が 0.027 ms になります。2 コアしかない箱では、この差がそのまま同時接続の余力になります。

実測 2:同じ強度で比べると差が桁で開く

RSA 3072 と P-384 も足して測り直した

RSA 2048 と ECDSA P-256 は、そもそも強度が違います。P-256 は約 128 bit 相当で、RSA でいえば 3072 に近い。条件を揃えるために 4 種類まとめて計測しました。

$ openssl speed -seconds 3 rsa2048 rsa3072 ecdsap256 ecdsap384

                  sign    verify    sign/s verify/s
rsa 2048 bits 0.000435s 0.000020s   2297.3  48807.4
rsa 3072 bits 0.002110s 0.000044s    474.0  22570.9
                              sign    verify    sign/s verify/s
 256 bits ecdsa (nistp256)   0.0000s   0.0001s  37903.4  12131.8
 384 bits ecdsa (nistp384)   0.0008s   0.0007s   1189.6   1363.2
鍵の種類 概算強度 署名(回/秒) 検証(回/秒)
RSA 2048 約 112 bit 2,297.3 48,807.4
RSA 3072 約 128 bit 474.0 22,570.9
ECDSA P-256 約 128 bit 37,903.4 12,131.8
ECDSA P-384 約 192 bit 1,189.6 1,363.2

⛔ 「楕円曲線だから速い」ではない

ここで 3 つ分かりました。

ひとつ、RSA は鍵長を伸ばすと急に重くなる。2048 から 3072 にしただけで署名が 2,297.3 → 474.0 回/秒、マイナス 79.4% です。検証も 53.8% 落ちました。

ふたつ、同じ約 128 bit で並べると差が桁で開く。RSA 3072 の 474.0 に対して P-256 は 37,903.4 回/秒、約 80 倍です。

みっつ、ECDSA も P-384 にすると激減する。署名は 37,903.4 → 1,189.6 回/秒で約 32 倍遅くなりました。OpenSSL が P-256 にだけ専用の最適化実装を持っているためです。速いのは楕円曲線だからではなく、P-256 だから。ここを取り違えると「より強い曲線にしておこう」で性能を捨てます。

実測 3:鍵の生成とファイルサイズ

鍵の生成は約 59 倍の差

RSA2048 keygen x10 total: 2755 ms  (avg 275 ms)
EC P-256 keygen x10 total:   47 ms  (avg   4 ms)

10 回まわした合計です。RSA の鍵生成は素数を探す処理なので、実行ごとのブレが大きく、平均で見ないと意味がありません。それでも 275 ms 対 4 ms は動かしようのない差でした。証明書を大量に扱うほど効いてきます。

ファイルは小さいが、期待したほどではない

ファイル RSA 2048 ECDSA P-256
秘密鍵(PEM) 1,704 B 227 B 7.5 倍
証明書(PEM) 1,119 B 583 B 1.9 倍
証明書(DER・実際に流れる形式) 785 B 389 B 2.0 倍

「小さいから転送量が減る」とよく言われます。ただし実際に流れるのは証明書 1 枚ではなくチェーン全体で、そこを確認したら話が変わりました(後述)。

実測 4:フルハンドシェイクでは 1.4 倍まで縮む

ベンチの結果

プロトコル RSA 2048 ECDSA P-256
TLS 1.3 2,826 接続 / 6 秒 3,959 接続 / 6 秒 約 1.4 倍
TLS 1.2 2,270 接続 / 6 秒 2,831 接続 / 6 秒 約 1.25 倍

署名単体では約 16 倍だったのに、ハンドシェイク全体では 1.4 倍まで縮みました。TCP の確立、鍵交換(ECDHE)、対称暗号、証明書の転送が共通コストとして乗るので、比率が縮むのは当然です。

逆に言えば、倍率だけを切り出した記事は測定条件を書いていないと意味がありません。自分の数字ですら、測り方次第で 1.4 倍にも 16 倍にも 80 倍にもなりました。

⚠️ この数字は ECDSA に不利な条件で出ている

s_time はクライアントも同じ 2 vCPU の上で動きます。つまり RSA が得意な「検証」まで同じ CPU を食っている状態での 1.4 倍です。クライアントが別マシンにいる実運用では、サーバー側の差はもっと開きます。

🔥 ハマった点:user sec を読むと逆の結論になる

ここで一度、逆の結論を出しかけました。s_time の出力には connections/user sec という行があり、こちらは RSA のほうが大きい(1527 対 1394)のです。

この値はユーザー CPU 時間あたりの接続数です。クライアント側の検証コストまで込みで割っているので、検証が速い RSA が有利に出ます。見るべきは N connections in 6 real seconds、つまり実時間あたりのほうでした。

ついでに curl でループバック越しのハンドシェイク実時間も 20 回計測して 40.3 ms という値を得ましたが、これは記事には使えない数字です。比較対象がなく、クライアントとサーバーが同じ 2 コアを奪い合っているだけなので。測ったけれど捨てた、という判断もそのまま書いておきます。

実測 5:配信中のチェーンを覗いたら 4 枚あった

ループバックから自分の証明書に聞く

$ echo | openssl s_client -connect 127.0.0.1:443 -servername serverlog.jp -showcerts 2>/dev/null \
  | awk '/BEGIN CERT/,/END CERT/' > chain.pem
$ csplit -z -f c -b "%d.pem" chain.pem '/BEGIN CERT/' '{*}'
$ for f in c*.pem; do openssl x509 -in "$f" -noout -subject -issuer; done

subject=CN = serverlog.jp        issuer=Let's Encrypt YE2    1,306 B  prime256v1 (256bit)
subject=Let's Encrypt YE2        issuer=ISRG Root YE           944 B  secp384r1  (384bit)
subject=ISRG Root YE             issuer=ISRG Root X2           981 B  secp384r1  (384bit)
subject=ISRG Root X2             issuer=ISRG Root X1         1,598 B  secp384r1  (384bit)

127.0.0.1-servername を付けて聞くのがコツです。CDN の後ろにサイトを置いていると、外から測ってもエッジ側の証明書しか見えません。オリジンの実物を確認したいならループバックから SNI 指定で叩きます。

「小さいから軽い」がチェーン長で相殺されていた

意外だったのがこれです。Let's Encrypt の ECDSA 系は YE2 → Root YE → ISRG Root X2 → ISRG Root X1 とクロス署名で繋がっていて、合計 4 枚・4,829 B ありました。証明書 1 枚は確かに半分ですが、チェーン全体で見ると期待したほど減りません。

ネゴシエート結果は TLSv1.3 / TLS_AES_256_GCM_SHA384Peer signature type: ECDSAServer public key is 256 bit。有効期限は Nov 14 2026 でした。ですので「ECDSA にすれば転送量が半分」とは書けません。実際に流れているものを数えると、そうなっていないからです。

メリットとデメリットの整理

ECDSA P-256

  • 署名が約 16 倍速い(2,414.2 → 37,711.4 回/秒)=同じ CPU でさばける HTTPS 接続が増える
  • 鍵の生成が約 59 倍速い(275 ms → 4 ms)
  • 鍵と証明書が小さい(秘密鍵 1,704 → 227 B / 証明書 DER 785 → 389 B)
  • 同じ強度なら約 80 倍軽い(RSA 3072 の 474.0 対 P-256 の 37,903.4 回/秒)
  • certbot 2.x の既定なので追加作業が要らない
  • ⚠️ 検証は RSA の 1/4(12,078.9 対 48,826.3 回/秒)=負荷はクライアント側に移る
  • ⚠️ 速いのは P-256 だから。P-384 にすると署名が約 32 倍遅くなる
  • ⚠️ Windows XP や Android 4.0 未満では繋がらない

RSA 2048

  • 検証が 4.0 倍速い(クライアントの CPU に優しい)
  • 互換性が最強。事実上どんな古い環境でも繋がる
  • ✅ 実装が枯れていて、機器やミドルウェアの対応漏れがない
  • ⚠️ 署名が約 16 倍遅い=同時接続が増えるほど CPU を食う
  • ⚠️ 鍵の生成が遅い(平均 275 ms・ブレ大)
  • 強度を上げると急激に重くなる。3072 で署名 474.0 回/秒(マイナス 79.4%)

サーバー側でスペックを上げずに接続数を稼ぎたいなら、鍵の種類を確認するのは費用ゼロの改善です。さくらのVPS公式サイトでプランと料金を確認する(2 週間の無料お試しつき)

用途別の選び方

個人ブログ・企業サイト・API

ECDSA P-256 で問題ありません。certbot でそのまま取れば既定でこれになります。うちの 42 枚も、意識せずに全部この構成でした。

官公庁向けや、古い端末が相手に含まれる場合

ここだけは RSA を残す理由があります。判断材料が手元にないなら、両方配って nginx に出し分けさせる手があります。

# 2 系統を併記すると、nginx がクライアントの対応に応じて出し分ける
ssl_certificate     /etc/letsencrypt/live/example.com-ecdsa/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com-ecdsa/privkey.pem;
ssl_certificate     /etc/letsencrypt/live/example.com-rsa/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com-rsa/privkey.pem;

⚠️ この併記はうちでは動かしていません(42 枚すべて ECDSA 単独のため)。試すなら本番に入れる前に 1 サイトで確認してください。実測していない設定を「動きます」とは書けないので、ここは未検証と明記しておきます。

アクセスの多いサイト

ECDSA 一択です。ただし過大な期待は禁物で、ssl_session_cache が効いているとフルハンドシェイク自体が減るため、実サイトでの差はベンチの倍率より小さくなります。うちの設定は次のとおりです。

ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:50m;

よくある質問

Q1. ECDSA と RSA はどちらが安全ですか?

結論:強度で選ぶなら ECDSA P-256 です。P-256 は約 128 bit 相当で、RSA 2048(約 112 bit)より上、RSA 3072 と同等です。しかも署名の速度は RSA 3072 の 474.0 回/秒に対して 37,903.4 回/秒でした。強度も速度も上回ります。

Q2. ECDSA に変えるとサイトは速くなりますか?

結論:ハンドシェイクの部分だけ、約 1.4 倍です。2026年8月17日に同一機で計測した TLS 1.3 のフルハンドシェイクは 2,826 対 3,959 接続 / 6 秒でした。ページの表示速度そのものが 1.4 倍になるわけではありません。効くのは接続処理の CPU 負荷です。

Q3. 今どちらを使っているか確認する方法は?

結論:grep "^key_type" /etc/letsencrypt/renewal/*.conf で分かります。certbot 管理下ならこれが一番早い。配信中の実物を見るなら openssl s_client -connect 127.0.0.1:443 -servername ドメイン名 を叩いて、Server public key is 256 bit と出れば ECDSA です。

Q4. 既存の RSA から乗り換えるとき、証明書は取り直しですか?

結論:取り直しです。鍵の種類は再発行でしか変わりません。certbot なら --key-type ecdsa を付けて再取得します。⛔ 対話で「既存の証明書を保持する」を選ぶと方式が変わらないので、必ず更新して置き換える側を選んでください。

Q5. ECDSA だと古い端末で見られなくなりませんか?

結論:Windows XP と Android 4.0 未満が切れます。2026年8月時点の一般的な Web サイトなら、実質的な影響はほぼありません。切れると困る相手が具体的に分かっている場合だけ、RSA を併記する構成を検討してください。

Q6. P-384 にすればもっと安全で速いのでは?

結論:安全ですが、大幅に遅くなります。手元の計測では署名が 37,903.4 → 1,189.6 回/秒、約 32 倍の低下でした。OpenSSL が P-256 だけを専用実装で最適化しているためです。「曲線が大きいほうが良い」という発想は、性能面では逆に働きます。

Q7. ECDSA は乱数が弱いと鍵が漏れると聞きました

結論:実装が壊れていた過去の事故の話です。ECDSA は署名に乱数を使うため、生成器が壊れていると秘密鍵を復元されます(PS3 や初期の Android で実際に起きました)。OpenSSL 3.0 は決定的な処理を備えているので、通常の運用で気にする話ではありません。

まとめ

速い・遅いの一言で片づけると取り違えます。数字で押さえると判断は単純でした。

  • 🎯 基本 → ECDSA P-256。重い仕事(署名)がサーバー側にあり、そこが約 16 倍速い
  • 🎯 ただし → 検証は RSA が 4.0 倍速い。ECDSA はあらゆる場面で速いわけではない
  • 🎯 強度で揃えるなら → RSA 3072 の 474.0 回/秒に対し P-256 は 37,903.4 回/秒(約 80 倍
  • やりがちな失敗 → 「より強い曲線を」で P-384 にして署名が約 32 倍遅くなる

実際のところ、certbot 2.x を使っていれば何もしなくても ECDSA になっています。うちも 42 枚すべてがそうでした。確認だけしておいて、RSA のままだった場合に取り直すかを決めれば十分です。

数値は 2026年8月17日時点で稼働中のさくらの VPS から採取したものです。同じスクリプトを走らせれば、お使いの環境の数字が出ます。サーバーの初期設定はさくらの VPS の初期セットアップ、通信の遮断はUFW でのファイアウォール設定、常駐プロセスの管理はsystemd のユニットファイル自作にまとめています。OS を新しくする話はDebian 13 で変わったことをどうぞ。

読んで頂いて有り難うございます!