本文へスキップ
ecdsa.com
← すべての記事

2026年の OpenPGP:RFC 9580、v6 鍵、GnuPG による分裂

OpenPGP には分岐しつつある 2 つの方言と、新しいポスト量子の標準があります。Sequoia sq 1.4.1、GnuPG 2.4.9、そして署名付きのソースからビルドした GnuPG 2.5.24 で v4、v6、ポスト量子の鍵を生成し、それぞれを他の実装に読み込ませました。その結果から、何を安全に公開できるかが決まります。

要点:IETF は RFC 9580(2024年7月)で OpenPGP を改訂しました。SHA-256 のフィンガープリントを持つ v6 鍵、必須アルゴリズムとしての Ed25519 と X25519、ソルト付きの署名、Argon2、認証付き暗号が導入されています。続いて RFC 9980(2026年)でポスト量子アルゴリズムが追加され、その多くは v6 鍵を対象としています。GnuPG は RFC 9580 を採用していません。GnuPG が準拠しているのは独自の後継仕様である LibrePGP で、v5 鍵と独自の Kyber 暗号化を備えています。RFC 9980 への対応は一部にとどまり、--allow-9980 を指定したときだけ有効になります。Sequoia は RFC 9580 と RFC 9980 を実装していますが、デフォルトでは今も v4 鍵を作成します。実際の運用では、他者が手元にあるツールで検証しなければならない鍵(Git のホスティングサービス、パッケージマネージャー、リリースページ)には、現時点では v4 Ed25519/Cv25519 鍵を使ってください。今回テストしたすべての環境で動作しました。v6 鍵やポスト量子鍵は、すべての検証者が Sequoia などの RFC 9580 実装を使っているエコシステムの中でだけ使ってください。

実験は debian:forky-20261005-slim 上で行いました。使用したのは Debian パッケージの sq 1.4.1(sequoia-openpgp 2.4.1、Nettle バックエンド)と gnupg 2.4.9、さらに同じイメージ内でリリースの tarball からコンパイルした GnuPG 2.5.24 です。コンパイルは、gpg --verify が「Werner Koch (dist signing 2020)」による正しい署名を報告したことを確認してから行いました。鍵はすべて、この記事のために生成したものです。

2023年から並立する 2 つの標準

OpenPGP の旧仕様である RFC 4880 は 2007年のものです。その改訂をめぐって、コミュニティは分裂しました。IETF のワーキンググループが作成した仕様は、後に RFC 9580 となりました。一方、その一部に同意しなかった GnuPG の開発者は、それ以前のドラフトを LibrePGP(draft-koch-librepgp。Werner Koch と Ronald Henry Tse による個人のインターネットドラフトで、2026年9月のリビジョン 06)として引き継ぎ、バージョン 5 の鍵と別の認証付き暗号モードを採用しました。両者は新しい鍵形式とメッセージ形式では互換性がなく、古い形式では互換性があります。どの実装も、v4 鍵と v4 署名は今も読み書きできます。

RFC 9580 は旧形式について率直に述べています。「OpenPGP の実装は、バージョン 6 形式で鍵を作成すべきです(SHOULD)。バージョン 4 の鍵は非推奨です。実装はバージョン 4 の鍵を生成すべきではありません(SHOULD NOT)が、受け入れるべきです(SHOULD)」(§5.5.2)。RFC 9580 は鍵パケットのバージョンとして 2、3、4、6 を定義しており、バージョン 5 は LibrePGP にしか存在しません。その他の変更点は次のとおりです。

  • Ed25519(アルゴリズム 27)と X25519(25)は実装必須です。RSA は「鍵が非推奨であり、生成すべきではありません(SHOULD NOT)が、解釈してもかまいません」とされ、DSA と ElGamal は生成してはいけません(§9.1)。
  • v6 のフィンガープリントは鍵の「256 ビットの SHA2-256 ハッシュ」です(§5.5.4.3)。v4 のフィンガープリントは 160 ビットの SHA-1 です。
  • v6 署名にはランダムなソルトが含まれるため、署名対象のハッシュを事前に予測できません。
  • 暗号化データには AEAD 付きの SEIPD バージョン 2(OCB が必須)を使い、パスフレーズには Argon2 を使えます。

Sequoia:指定すれば v6 鍵を作成

sq key generate はデフォルトで v4 鍵を作成します。その理由はヘルプテキストに書かれています。「現在、デフォルトは RFC4880 です。ただし、RFC9580 への対応がさらに広がれば、将来のバージョンの sq でデフォルトが変更されます」。--profile rfc9580 を指定すると、v6 鍵が作成されます。

sq 1.4.1 で作成する 2 つの鍵:デフォルトのプロファイルと RFC 9580
sq key generate --own-key --without-password --name "Alice" --email alice@example.org --output alice-v4.pgp --rev-cert alice-v4.rev
sq key generate --own-key --without-password --profile rfc9580 --name "Alice" --email alice@example.org --output alice-v6.pgp --rev-cert alice-v6.rev
sq inspect alice-v4.pgp
sq inspect alice-v6.pgp
sq packet dump alice-v6.pgp
出力(抜粋)
### default profile (RFC 4880)
      Fingerprint: D3AE271931915949BEC2B3EBE329E5163B93B0F5
  Public-key algo: EdDSA
           Subkey: 0C7A47DD70202F80B0FA90B4E5C2206CA540055E
  Public-key algo: EdDSA
           Subkey: 8E35A51EC584304842AD4D13528B152570EC6FAC
  Public-key algo: EdDSA
### --profile rfc9580
      Fingerprint: 01117FE27C0ACB8EEBCE0D6FE03730724C57DA9E25D0963276EAB7A9F7EE2FB3
  Public-key algo: Ed25519
           Subkey: 23542B454F5CEDE06B81D42A874CFCF5CAB1E1D59E905CF0FC11AC21DE44A9F0
  Public-key algo: X25519
Secret-Key Packet, new CTB, 75 bytes
    Version: 6
    Pk algo: Ed25519

違いはフィンガープリントに表れています。v4 は 16 進数で 40 桁(SHA-1)、v6 は 64 桁(SHA-256)です。v4 鍵は従来の EdDSA アルゴリズム識別子(22。RFC 9580 での名称は「EdDSALegacy」)を使い、v6 鍵は新たに設けられた専用の Ed25519(27)と X25519(25)を使います。v6 鍵で作成した分離署名には、ソルトが含まれています。

sq sign の後、署名の sq packet dump と sq verify
Signature Packet, new CTB, 152 bytes
    Version: 6
    Pk algo: Ed25519
    Hash algo: SHA512
      Issuer Fingerprint: A3B490FC8C54F12C1E4955E520071CDC4ECA7F76BC87729C2F7BA5305EAC6FC7
    Salt: 62A29ACDACACD8ACF2D7ECDAAF3A10A6F577EDA3338E349D537190C437875B0F
Authenticated signature made by 01117FE27C0ACB8EEBCE0D6FE03730724C57DA9E25D0963276EAB7A9F7EE2FB3 (Alice)
1 authenticated signature.

ポスト量子鍵はライブラリには実装されています。sequoia-openpgp 2.4.0 は「RFC 9980 で定義されたポスト量子暗号のサポートを追加」しており、sq には mldsa65-ed25519 と mldsa87-ed448 の暗号スイートが表示されます。ただし PQC のコードは OpenSSL と RustCrypto のバックエンドにしかなく、Debian は Sequoia を Nettle でビルドしています。

sq key generate --profile rfc9580 --cipher-suite mldsa65-ed25519(Debian の sq 1.4.1)
  Error: Unsupported public key algorithm: ML-DSA-65+Ed25519

そもそもポスト量子の OpenPGP を使えるかどうかは、ディストリビューションがどの暗号バックエンドを選んだかで決まります。バックエンドは sq version で表示できます。

GnuPG:LibrePGP、Kyber、2.4 から 2.5 への移行

GnuPG 2.5 は 2025年12月30日に安定版シリーズになりました。このとき GnuPG は「旧安定版(oldstable)の 2.4 シリーズは、わずか 6 か月でサポート終了を迎えます」と発表しています(gnupg.org)。現在のリリースは 2.5.24(2026年9月23日)です。ディストリビューションの移行は遅く、Debian の testing ブランチは今も 2.4.9 を提供しています。2.4.9 のデフォルトの鍵は、Cv25519 の副鍵を持つ v4 Ed25519 鍵です。

gpg 2.4.9 --quick-gen-key 'Bob <bob@example.org>' default default 1y の後に --list-packets
pub   ed25519 2026-10-22 [SC] [expires: 2027-10-22]
sub   cv25519 2026-10-22 [E]
	version 4, algo 22, created 1792651599, expires 0
	version 4, algo 18, created 1792651599, expires 0

GnuPG は 2.5 でポスト量子暗号化を追加しました。ML-KEM(Kyber)と古典的な曲線を組み合わせた複合方式で、形式は LibrePGP です。ポスト量子対応はこれまでのところ暗号化だけで、リリースノートにはポスト量子の署名鍵が記載されていません。2.5.23 で追加され、--allow-9980 を指定したときだけ有効になる RFC 9980 対応について、GnuPG のドキュメントは異例なほど率直に説明しています。「仕様が肥大化しているため、このオプションの使用は推奨しません。GnuPG の標準モードは、従来の PGP、ひいては LibrePGP の仕様に重きを置いています。LibrePGP も PQC に対応していますが、より簡潔で PGP らしい方法をとっています」。

相互運用性のテスト

3 つの実装の間で、すべての鍵をやり取りしました。まずは GnuPG 2.4.9 で Sequoia の鍵と署名を読み込んだ結果です。

sq の v4 鍵と v6 鍵に対する gpg 2.4.9 の --import と --verify
gpg: key E329E5163B93B0F5: public key "Alice" imported
gpg:               imported: 1
gpg: packet(6) with unknown version 6
gpg: read_block: read error: Invalid packet
--- gpg --verify of a v4 signature made by sq
gpg:                using EDDSA key 0C7A47DD70202F80B0FA90B4E5C2206CA540055E
gpg: Good signature from "Alice" [unknown]
--- gpg --verify of the v6 signature
gpg: packet(2) with unknown version 6
gpg: no signature found

次に、GnuPG 2.5.24 のポスト量子鍵を GnuPG 2.4.9 と sq 1.4.1 で読み込んだ結果です。

gpg 2.5.24 で作成した 3 つのポスト量子鍵(アルゴリズムとパケットのバージョンは --list-packets の出力)
### gpg --quick-gen-key ... pqc
pub   brainpoolP384r1 2026-10-22 [SC] [expires: 2027-10-22]
sub   ky768_bp256 2026-10-22 [E]
version 4, algo 19, created 1792651785, expires 0
version 5, algo 8, created 1792651785, expires 0, pkbytes 1265
  gpg 2.4.9 --import, then --list-keys:
    gpg:               imported: 1
    pub   brainpoolP384r1 2026-10-22 [SC] [expires: 2027-10-22]
    sub   unknown_8 2026-10-22 [E]
  sq 1.4.1 inspect:
    Public-key algo: ECDSA
    Unknown component: ... tag: PublicSubkey, error: Malformed packet: unknown version ...
### gpg --allow-9980 --quick-gen-key ... pqc9980
pub   ietf27 2026-10-22 [SC] [expires: 2027-10-22]
sub   mlk768_bp384 2026-10-22 [E]
version 6, algo 27, created 1792651785, expires 0, pkbytes 32
version 5, algo 39, created 1792651785, expires 0, pkbytes 1281
  gpg 2.4.9 --import, then --list-keys:
    gpg: packet(6) with unknown version 6
    gpg: import from 'frank.pgp' failed: Invalid keyring
  sq 1.4.1 inspect:
    Public-key algo: Ed25519
    Unknown component: ... tag: PublicSubkey, error: Malformed packet: unknown version ...
### gpg --allow-9980: v6 Ed25519 primary + mlk768 and mlk768_bp384 subkeys
version 6, algo 27, created 1792651848, expires 0, pkbytes 32
version 5, algo 35, created 1792651848, expires 0, pkbytes 1216
version 5, algo 39, created 1792651848, expires 0, pkbytes 1281

この結果からわかることは次のとおりです。

  • v4 の鍵と署名はどこでも動作します。sq のデフォルトの鍵とその署名は、GnuPG 2.4.9 で検証できました。
  • v6 鍵は GnuPG 2.4 で読み込めず、packet(6) with unknown version 6 と表示されます。v6 鍵を 2.4 のキーリングにインポートしても何も取り込まれず、v6 署名は「no signature found」になります。
  • GnuPG のデフォルトの PQC 鍵は LibrePGP 専用です。pqc が作成したのは、brainpoolP384r1 の主鍵と、Kyber-768 と brainpoolP256r1 を組み合わせた副鍵(アルゴリズム 8)で、副鍵は v5 パケットに格納されています。GnuPG 2.4.9 はこの鍵をインポートしますが、副鍵を unknown_8 と表示するため、その副鍵に宛てて暗号化できません。Sequoia は v5 パケットを拒否します。
  • 「9980 モード」でも、Sequoia が読める鍵はできませんでした。--allow-9980 を指定すると、GnuPG 2.5.24 は v6 の主鍵を作成しましたが、mlk768(アルゴリズム 35。RFC 9980 の ML-KEM-768+X25519)を含む ML-KEM の副鍵はバージョン 5 のパケットとして書き出しました。バージョン 5 は RFC 9580 で定義されておらず、Sequoia はこのパケットを受け付けません。また、pqc9980 のデフォルトはアルゴリズム 39(ML-KEM-768 と brainpoolP384r1 の組み合わせ)を選びますが、これは RFC 9980 自体が定めるアルゴリズムではありません。GnuPG 2.5.24 の時点では、GnuPG が作る RFC 9980 の鍵と RFC 9980 の実装は噛み合いません。

GnuPG 2.5 の内部では、これらすべての鍵で暗号化と復号が動作しました。問題が起きるのは実装の間だけです。

ポスト量子 OpenPGP:RFC 9980 の定義内容

RFC 9980(Proposed Standard、2026年)は、複合アルゴリズムと単独のアルゴリズムを追加しています。

IDアルゴリズム要件鍵
30ML-DSA-65+Ed25519MUSTv6
31ML-DSA-87+Ed448SHOULDv6
32〜34SLH-DSA-SHAKE-128s、128f、256sMAYv6
35ML-KEM-768+X25519MUSTv4 または v6
36ML-KEM-1024+X448SHOULDv6

複合方式では、両方の要素がともに成功しなければなりません。攻撃者は ML-KEM と X25519 の両方、または ML-DSA と Ed25519 の両方を破る必要があります。急を要するのは暗号化のほうです。暗号化されたメッセージは今のうちに保存しておき、後で解読できるからです(harvest now, decrypt later、今収集し、後で解読)。署名は検証者が対応するまで待てますし、長期間使われる署名は後から作り直せます。ID 35 は v4 の副鍵にも使えるため、既存の v4 鍵に、主鍵を置き換えずにポスト量子の暗号化用副鍵を追加できます。

実践的な推奨事項

  1. リリース、Git コミット、パッケージの署名鍵には v4 Ed25519 を使ってください。GnuPG 2.4/2.5(default)または sq(デフォルトのプロファイル)で作成できます。今回テストしたすべての検証者が、この鍵を受け入れます。Debian の APT は現在、デフォルトで Sequoia の sqv を使ってアーカイブの署名を検証しており(APT 3.0、Debian 13)、2026年2月1日以降は SHA-1 で結び付けられた署名と v3 署名を拒否します。古いものはすべて署名し直してください(APT 3.0 に関する LWN の記事)。
  2. 環境を管理できない相手には v6 鍵を公開しないでください。公開してよいのは、相手のツールが Sequoia、OpenPGP.js 6(RFC 9580 を実装)などの RFC 9580 実装になってからです。GnuPG 2.4 のユーザーは v6 鍵をインポートできません。
  3. ポスト量子の保護を備えた暗号化が現時点で機能するのは、1 つの方言の中だけです。LibrePGP の Kyber を使う GnuPG どうしか、OpenSSL または RustCrypto バックエンドで RFC 9980 を使う Sequoia です。誰が復号するかで決めてください。
  4. バックエンドとバージョンを確認してください(gpg --version、sq version)。ディストリビューションのパッケージは、アップストリームより 1 年以上遅れています。
  5. OpenPGP の柔軟性が不要な場面では、よりシンプルなツールを選んでください:Git コミットには SSH 署名、リリースの来歴には Sigstore、ファイルの暗号化には age です。それぞれのトレードオフは比較記事の SSH と GPG のコミット署名の比較、Sigstore と GPG の比較、age と GPG の比較で、SSH 側については 2026年の ssh-keygen で解説しています。
  6. 完全なフィンガープリントを公開してください。公開先は誰もが確認できる場所(自分の Web サイトやリリースノート)にし、鍵は WKD または keys.openpgp.org で配布してください。鍵サーバーは鍵を配るだけで、その鍵を保証するものではありません。

ダウンロードしたファイルの正しい検証方法

F-Droid は、APK の隣に分離署名を置き、署名鍵のフィンガープリントを Web サイトで公開しています。検証に必要なコマンドは 3 つです。

.asc で F-Droid.apk を検証する(GnuPG 2.4.9)
gpg --keyserver hkps://keyserver.ubuntu.com --recv-keys 37D2C98789D8311948394E3E41E7044E1DBA2E89
gpg --verify F-Droid.apk.asc F-Droid.apk
gpg --list-packets F-Droid.apk.asc
出力(抜粋)
gpg: key 41E7044E1DBA2E89: public key "F-Droid <admin@f-droid.org>" imported
gpg: Signature made Mon Oct 12 12:58:48 2026 UTC
gpg:                using RSA key 802A9799016112346E1FEFF47A029E54DD5DCE7A
gpg: Good signature from "F-Droid <admin@f-droid.org>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
Primary key fingerprint: 37D2 C987 89D8 3119 4839  4E3E 41E7 044E 1DBA 2E89
     Subkey fingerprint: 802A 9799 0161 1234 6E1F  EFF4 7A02 9E54 DD5D CE7A
:signature packet: algo 1, keyid 7A029E54DD5DCE7A
	version 4, created 1791809928, md5len 0, sigclass 0x00
	digest algo 10, begin of digest 4b be

「WARNING: This key is not certified」という警告の行が出るのは正常です。GnuPG の信用の輪には、この鍵に至る経路がないためです。この検証を意味のあるものにするのは、主鍵のフィンガープリントを F-Droid の検証ページに掲載されたものと照合すること(一致しました)と、鍵の取得時に完全なフィンガープリントを指定することです。鍵サーバーは、一致するものを何でも渡してしまうからです。署名自体は、ハッシュに SHA-512(ダイジェストアルゴリズム 10)を使った v4 RSA 署名(アルゴリズム 1)です。形式は古いもののハッシュは現行のもので、どの実装でも読めます。鍵がない場合は Can't check signature: No public key が、ファイルが変更されている場合は BAD signature が表示されます。

参考資料