Pythonの暗号ライブラリcryptographyに、楕円曲線暗号の公開鍵検証を行わない脆弱性 CVE-2026-26007が発見されました。
攻撃者は小さな部分群に属する点を公開鍵として送り込むことで、秘密鍵の一部情報を取得でき、これを繰り返して中国剰余定理で組み合わせれば秘密鍵全体を復元できます。
影響を受けるのはSECT系の2進体楕円曲線のみで実運用ではほとんど使われていませんが、同様の検証漏れは他の実装でも起こりうる構造的な問題です。
バージョン46.0.5で修正済みなので、利用者は速やかにアップデートすべきです。
1. cryptographyに見つかったCVE-2026-26007とは
Pythonの暗号ライブラリ cryptography に関する脆弱性の話題になっています。
CVE-2026-26007 という番号が付いたもので、「楕円曲線暗号の根幹が揺らぐ」とも言われています。
- CVE-2026-26007: Python Cryptography Flaw (CVSS 8.2) Leaks Private Keys( February 12, 2026)
- 「OpenSSLの問題が深刻化している」と暗号ライブラリの開発者らが指摘 – GIGAZINE(2026年01月15日)
楕円曲線暗号(Elliptic Curve Cryptography, ECC)は、長年研究され、実運用でも広く使われている仕組みです。
もし、それが「公開鍵を受け取るだけで秘密鍵が漏れる」というのでは、大問題。
ただ、その脆弱性には、前提や条件があります。
見えてきたのは、暗号理論そのものではなく「実装」の話でした。
今回問題になったのは、Pythonの cryptography パッケージが提供する楕円曲線暗号の処理です12。
焦点は「外部から渡される公開鍵を、どこまで信用してよいのか」という点でした。
公開鍵というと、安全に配布できる情報という印象があります。
ただしそれは、「正しい形式の公開鍵である」という前提があってこそ成り立ちます。
今回の脆弱性では、load_pem_public_key や public_key_from_numbers といった関数が、
その公開鍵が
- 本当に指定された楕円曲線上の点か
- 想定している大きな位数(order)を持つ部分群に属しているか
といった検証を行っていませんでした3。
その結果、攻撃者は「見た目は公開鍵だが、暗号としては不正な点」を送り込めてしまいます。
1.1. 楕円曲線暗号と部分群
ここで、楕円曲線暗号の前提を少し整理します。
ECCでは、楕円曲線上の「点」を使って計算を行います。
秘密鍵は数値で、公開鍵は「ある基準点を秘密鍵の回数だけ足し算した点」です。
重要なのは、その計算が行われる「集合の大きさ」です。
安全なECCでは、位数が非常に大きい「素数位数の部分群(prime-order subgroup)」を使います4。
位数とは、その集合に含まれる点の数だと考えると分かりやすいです。
一方、楕円曲線全体を見ると、位数が極端に小さい部分群も存在します5。
今回問題になったサブグループ攻撃(subgroup attack)は、
この「小さすぎる集合」を使って秘密情報を引き出す攻撃です。
1.2. サブグループ攻撃
cryptography の脆弱な実装では、攻撃者が小さな位数を持つ点を公開鍵として渡せます。
すると、被害者側で行われる ECDH(Elliptic Curve Diffie-Hellman:楕円曲線を使った鍵共有)の計算結果が、
「秘密鍵 mod 小さな位数」に依存する値になります。
少し噛み砕くと、こういう話です。
本来、秘密鍵は非常に大きな数で、外から推測するのは現実的に不可能です。
しかし「mod(余り)」という制約がかかると、候補の数が一気に減ります。
ここで重要な概念が「cofactor(補因子)」です。
cofactorは、楕円曲線全体の点の数を、
安全な素数位数部分群の点の数で割った値です6。
cofactor = 1 の曲線では、曲線全体が安全な部分群そのものなので、
小さな部分群は存在しません。NIST P-256やP-384などの主要な曲線はこのタイプです。
一方、cofactor > 1 の曲線では、安全な部分群以外に、
位数の小さい部分群も数学的に存在してしまいます。
今回問題になったSECT曲線は、cofactorが2または4であり、
位数2、4、8などの小さな部分群が存在します。
Curve25519の例:
- 曲線全体の位数 = 8 × p (p は約2²⁵²の素数)
- 安全な素数位数部分群 = p
- cofactor = 8
攻撃者はこの小さな部分群に属する点を公開鍵として送り込むことで、
秘密鍵の情報を少しずつ抜き出すことができるのです。
位数8の部分群を使われた場合、秘密鍵の下位3ビット(秘密鍵 mod 8)の情報が漏れ、
候補は8通りにまで絞られます。これは瞬時に総当たりできる規模です7。
1.3. 繰り返すことで秘密鍵全体が見えてくる
さらに厄介なのは、この攻撃を何度も繰り返せる点です。
攻撃者が異なる小さな位数の点を順番に送り込むと、
「秘密鍵 mod r₁」「秘密鍵 mod r₂」…という情報が少しずつ集まります。
これらを中国剰余定理(Chinese Remainder Theorem:複数の余り条件から元の数を復元する方法)で組み合わせると、
最終的に秘密鍵全体が復元できてしまう可能性があります8。
計算量の観点で見ると、
本来は 2¹²⁸ 回規模の計算が必要だったものが、
実際には「通信を何回か行い、2¹⁶程度の計算を数回繰り返す」という世界に落ちてきます。
暗号理論が破られたというより、
暗号が成り立つ前提が実装によって満たされていなかったことが明らかになったわけです。
1.4. ECDSAにも及ぶ影響
同じ楕円曲線を使う ECDSA(Elliptic Curve Digital Signature Algorithm:電子署名)でも、
小さな部分群上では数式が単純になり、署名の偽造や鍵推定が容易になると指摘されています9。
ここでも重要なのは、
「ECDSAという方式が弱い」のではなく、
「不正な公開鍵を受け入れる実装が危険」という点です。
2. 影響の範囲とリスク
今回のCVEは、SECT系と呼ばれる2進体の楕円曲線を使っている実装に限られます1011。
そのため、すべてのECC利用者が直ちに危険、という話ではありません。
ただ、個人的に怖いと感じたのは、
「同じ構造の問題は、別の実装でも起こり得る」という点でした。
公開鍵検証は仕様書には書いてあります。
しかしAPIの使い方次第では、呼び出し側の責任として省略されてしまうことがあります。
独自実装や古いコード、組み込み機器などでは、
同様の前提崩れがあっても不思議ではありません。
2.1. 修正と利用者としてできること
cryptography では、この問題はバージョン 46.0.5 で修正されています12。
つまり、Pythonを利用している環境では、アップデートが大事です。
ライブラリ側で公開鍵の検証が追加され、
小さな部分群に属する点は拒否されるようになりました13。
実は、公開鍵は安全、という裏には、多くの前提条件があったのです。
今回の話は、そのことを強く意識させられる出来事でした。
暗号は数学だけで完結しているわけではありません。
コードになった瞬間に、また別のリスクが生まれます14。
- cryptographyは、Pythonで暗号化プリミティブを扱うための広く利用されているライブラリです。PyCA(Python Cryptographic Authority)プロジェクトによって開発されています。 – pyca/cryptography – GitHub
- この脆弱性はCVSS(Common Vulnerability Scoring System)で8.2(High)と評価されており、深刻度の高い問題として認識されています。cryptographyは、Pythonアプリケーションにおける暗号化処理の事実上の標準ライブラリとして広く利用されています。 – CVE-2026-26007: Python Cryptography Flaw (CVSS 8.2) Leaks Private Keys
- 公式セキュリティアドバイザリでは、load_der_public_key()、load_pem_public_key()、public_key_from_numbers()、EllipticCurvePublicNumbers.public_key()、およびEllipticCurvePublicKey.from_encoded_point()の各関数が影響を受けると記載されています。 – GHSA-r6ph-v2qm-q3c2 Security Advisory
- NIST FIPS 186やSECG、X9.62などの標準規格では、公開鍵が素数位数部分群に属することを検証するよう推奨しています。具体的には、受け取った点Pに対してn·P = O(無限遠点)となることを確認します。 – An Illustrated Guide to Elliptic Curve Cryptography Validation
- 楕円曲線の位数は、素数位数部分群の位数とcofactorの積で表されます。cofactorが1より大きい曲線では、位数2、4、8などの小さな部分群が存在します。SECT曲線ではcofactorが2または4であることが多く、これらの小さな部分群を利用した攻撃が可能になります。 – Cofactor Explained: Clearing Elliptic Curves’ dirty little secret
- cofactor(補因子)は、楕円曲線全体の位数を素数位数部分群の位数で割った値です。cofactor = 1 の曲線(NIST P-256など)には小さな部分群が存在しませんが、cofactor > 1 の曲線(SECT曲線など)には位数の小さい部分群が存在し、これがサブグループ攻撃の標的となります。Curve25519はcofactor = 8ですが、clamping(鍵の下位ビットをクリア)という対策により攻撃を防いでいます。
- SECT曲線のcofactorは通常2または4であり、位数2、4、8などの小さな部分群が存在します。例えば位数8の部分群を使った攻撃では、秘密鍵の下位3ビット(秘密鍵 mod 8)が漏洩し、候補が8通りに絞られます。- Clamping & Cofactor clearing in Curve25519
- 中国剰余定理は、互いに素な複数の法に対する合同式の系から、それらの積を法とする一意の解を求める定理です。暗号解析では、異なる小さな部分群からの情報を組み合わせて秘密鍵を復元する手法として利用されます。 – Chinese Remainder Theorem – Stanford Crypto
- 公式のセキュリティアドバイザリでは、「小さな部分群上でECDSAを使用すると、署名の偽造が容易になる」と明記されています。小さな部分群では点の数が限られているため、署名に使われる乱数の選択肢が制限され、署名スキームの安全性が損なわれます。 – CVE-2026-26007 Debian Bug Report
- SECT曲線は、GF(2^m)(2の累乗の有限体)上で定義される楕円曲線で、binary curves(2進曲線)やKoblitz curvesとも呼ばれます。NISTが標準化したSECT163k1、SECT233k1、SECT283k1などがあります。一方、広く使われているNIST P-256やP-384などの曲線は素数体上で定義されており、cofactorが1であるため今回の脆弱性の影響を受けません。 – Software Implementation of Elliptic Curve Cryptography over Binary Fields
- cryptographyライブラリの公式発表では、「SECT binary elliptic curvesのサポートは非推奨となり、次のリリースで削除される予定」と発表されています。SECT曲線は実運用ではほとんど使用されていません。 – PyCA cryptography 46.0.5 released
- 修正は、新しい集中コンストラクタECPublicKey::newを導入し、cofactorが1より大きい曲線に対してec.check_key()による検証を追加することで実装されました。これにより、小さな部分群に属する点は拒否されるようになりました。 – cryptography commit 0eebb9d
- この脆弱性はTencent Xuanwu LabのXlabAIチームとAtuin自動脆弱性発見エンジンによって発見・報告されました。適切な公開鍵検証の重要性を示す事例となっています。 – CVE-2026-26007 Miggo Vulnerability Database
- cryptographyの開発チームは、OpenSSLのパフォーマンス低下や複雑化の問題を背景に、暗号処理の実装をRustベースの独自コードに移行する動きを進めています。証明書解析をRustに移行したことで10倍のパフォーマンス向上を実現し、公開鍵解析の移行によりエンドツーエンドのパス検証が60%高速化したと報告されています。この動きは、暗号ライブラリ全体のエコシステムにおける大きな転換点となる可能性があります。 – 「OpenSSLの問題が深刻化している」と暗号ライブラリの開発者らが指摘