Pular para o conteúdo
ecdsa.com
← Todos os artigos

OpenPGP em 2026: RFC 9580, chaves v6 e a cisão do GnuPG

O OpenPGP tem dois dialetos que se afastam cada vez mais e um novo padrão pós-quântico. Geramos chaves v4, v6 e pós-quânticas com o Sequoia sq 1.4.1, o GnuPG 2.4.9 e o GnuPG 2.5.24 compilado a partir do código-fonte assinado, e passamos as chaves de cada um para os outros. Os resultados determinam o que você pode publicar com segurança.

Resposta curta. O IETF revisou o OpenPGP na RFC 9580 (julho de 2024): chaves v6 com impressões digitais SHA-256, Ed25519 e X25519 como algoritmos obrigatórios, assinaturas com salt, Argon2 e criptografia autenticada. Os algoritmos pós-quânticos vieram depois, na RFC 9980 (2026), principalmente para chaves v6. O GnuPG não adotou a RFC 9580: ele segue o LibrePGP, uma continuação própria com chaves v5 e sua própria criptografia com Kyber, e oferece suporte apenas parcial à RFC 9980, ativado pela opção --allow-9980. O Sequoia implementa a RFC 9580 e a RFC 9980, mas ainda cria chaves v4 por padrão. Na prática: para chaves que terceiros precisam verificar com o que tiverem à mão (plataformas de hospedagem Git, gerenciadores de pacotes, páginas de releases), use hoje uma chave v4 Ed25519/Cv25519; ela funciona em todos os ambientes que testamos. Use chaves v6 ou pós-quânticas apenas em ecossistemas em que todos os verificadores rodam o Sequoia ou outra implementação da RFC 9580.

O laboratório rodou em debian:forky-20261005-slim com os pacotes Debian sq 1.4.1 (sequoia-openpgp 2.4.1, backend Nettle) e gnupg 2.4.9, além do GnuPG 2.5.24 compilado na mesma imagem a partir do tarball da versão, depois que o gpg --verify informou uma assinatura válida de “Werner Koch (dist signing 2020)”. Todas as chaves foram geradas para este artigo.

Dois padrões desde 2023

A especificação anterior do OpenPGP, a RFC 4880, é de 2007. A revisão dessa especificação dividiu a comunidade. O grupo de trabalho do IETF produziu o que se tornou a RFC 9580; os desenvolvedores do GnuPG, que discordavam de partes dela, deram continuidade ao rascunho anterior como LibrePGP (draft-koch-librepgp, um Internet-Draft individual de Werner Koch e Ronald Henry Tse, revisão 06, de setembro de 2026), com chaves versão 5 e um modo diferente de criptografia autenticada. Os dois são incompatíveis nos novos formatos de chave e de mensagem e compatíveis nos antigos: todos ainda leem e gravam chaves v4 e assinaturas v4.

A RFC 9580 é direta sobre o formato antigo: “As implementações de OpenPGP DEVERIAM criar chaves no formato versão 6. As chaves versão 4 estão descontinuadas; uma implementação NÃO DEVERIA gerar uma chave versão 4, mas DEVERIA aceitá-la” (§5.5.2). Ela define as versões 2, 3, 4 e 6 do pacote de chave; a versão 5 existe apenas no LibrePGP. As outras mudanças:

  • O Ed25519 (algoritmo 27) e o X25519 (25) são de implementação obrigatória; as chaves RSA “estão descontinuadas e NÃO DEVERIAM ser geradas, mas podem ser interpretadas”, e chaves DSA e ElGamal não devem ser geradas (§9.1).
  • As impressões digitais v6 são “o hash SHA2-256 de 256 bits” da chave (§5.5.4.3); as impressões digitais v4 são SHA-1 de 160 bits.
  • As assinaturas v6 levam um salt aleatório, de modo que o hash assinado não pode ser previsto com antecedência.
  • Os dados criptografados usam o SEIPD versão 2 com AEAD (OCB obrigatório), e as frases secretas podem usar Argon2.

Sequoia: chaves v6 sob demanda

O sq key generate cria uma chave v4 por padrão. O texto de ajuda explica por quê: “Atualmente, o padrão é RFC4880. No entanto, quando o suporte à RFC9580 estiver mais difundido, o padrão mudará em uma versão futura do sq.” Com --profile rfc9580, ele cria uma chave v6:

Duas chaves com o sq 1.4.1: o perfil padrão e a 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
Saída (filtrada)
### 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

A diferença aparece nas impressões digitais: 40 dígitos hexadecimais (SHA-1) na v4, 64 (SHA-256) na v6. A chave v4 usa o identificador de algoritmo EdDSA, mais antigo (22, “EdDSALegacy” na RFC 9580), e a chave v6, os novos identificadores dedicados Ed25519 (27) e X25519 (25). Uma assinatura desanexada feita com a chave v6 mostra o salt:

sq sign, depois sq packet dump da assinatura e 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.

A biblioteca tem chaves pós-quânticas: o sequoia-openpgp 2.4.0 “adiciona suporte à criptografia pós-quântica conforme definida na RFC 9980”, e o sq lista as cipher suites mldsa65-ed25519 e mldsa87-ed448. Mas o código de PQC existe apenas nos backends OpenSSL e RustCrypto, e o Debian compila o Sequoia com o Nettle:

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

É o backend criptográfico escolhido pela sua distribuição que decide se você tem OpenPGP pós-quântico ou não; o sq version mostra qual é.

GnuPG: LibrePGP, Kyber e a transição da 2.4 para a 2.5

O GnuPG 2.5 se tornou a série estável em 30 de dezembro de 2025, quando o GnuPG anunciou que “a série oldstable 2.4 chegará ao fim da vida útil em apenas 6 meses” (gnupg.org); a versão atual é a 2.5.24 (23 de setembro de 2026). As distribuições andam devagar: o branch testing do Debian ainda distribui a 2.4.9. A chave padrão dessa versão é uma chave v4 Ed25519 com uma subchave Cv25519:

gpg 2.4.9 --quick-gen-key 'Bob <bob@example.org>' default default 1y, depois --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

O GnuPG adicionou criptografia pós-quântica na 2.5: uma construção composta de ML-KEM (Kyber) e uma curva clássica, no formato do LibrePGP. Até agora, o trabalho pós-quântico do GnuPG cobre a criptografia; as notas de versão não listam chaves de assinatura pós-quânticas. A documentação descreve o suporte à RFC 9980, adicionado na 2.5.23 e ativado por --allow-9980, com uma franqueza incomum: “Devido à especificação inchada, o uso desta opção não é sugerido. O modo padrão do GnuPG é mais orientado à especificação clássica do PGP e, portanto, à do LibrePGP, que também oferece suporte a PQC, mas de um jeito mais enxuto e no estilo do PGP.”

Interoperabilidade posta à prova

Trocamos todas as chaves entre as três implementações. Primeiro, o GnuPG 2.4.9 lendo as chaves e as assinaturas do Sequoia:

gpg 2.4.9 --import e --verify das chaves v4 e v6 do sq
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

Depois, as chaves pós-quânticas do GnuPG 2.5.24, lidas pelo GnuPG 2.4.9 e pelo sq 1.4.1:

Três chaves pós-quânticas do gpg 2.5.24 (algoritmo e versão do pacote segundo o --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

O que isso mostra:

  • Chaves e assinaturas v4 funcionam em todo lugar. A chave padrão do sq e as assinaturas dela passaram na verificação do GnuPG 2.4.9.
  • As chaves v6 param no GnuPG 2.4, com packet(6) with unknown version 6. Quem importar sua chave v6 em um chaveiro da 2.4 não recebe nada; uma assinatura v6 vira “no signature found”.
  • A chave PQC padrão do GnuPG é exclusiva do LibrePGP. O pqc criou uma chave primária brainpoolP384r1 com uma subchave Kyber-768 mais brainpoolP256r1 (algoritmo 8) em um pacote v5. O GnuPG 2.4.9 a importa, mas lista a subchave como unknown_8 e, por isso, não consegue criptografar para ela; o Sequoia rejeita o pacote v5.
  • Nem o “modo 9980” produziu algo que o Sequoia leia. Com --allow-9980, o GnuPG 2.5.24 criou uma chave primária v6, mas gravou as subchaves ML-KEM, inclusive a mlk768 (algoritmo 35, ML-KEM-768+X25519, da RFC 9980), como pacotes versão 5, que a RFC 9580 não define e o Sequoia recusa. Além disso, a escolha padrão de pqc9980 é o algoritmo 39, ML-KEM-768 com brainpoolP384r1, que não está entre os algoritmos da própria RFC 9980. No GnuPG 2.5.24, uma chave RFC 9980 gerada pelo GnuPG e uma implementação da RFC 9980 não se entendem.

A criptografia e a descriptografia dentro do GnuPG 2.5 funcionaram com todas essas chaves; o problema está apenas entre implementações diferentes.

OpenPGP pós-quântico: o que a RFC 9980 define

A RFC 9980 (padrão proposto, 2026) adiciona algoritmos compostos e independentes:

IDAlgoritmoRequisitoChaves
30ML-DSA-65+Ed25519obrigatório (MUST)v6
31ML-DSA-87+Ed448recomendado (SHOULD)v6
32–34SLH-DSA-SHAKE-128s, 128f e 256sopcional (MAY)v6
35ML-KEM-768+X25519obrigatório (MUST)v4 ou v6
36ML-KEM-1024+X448recomendado (SHOULD)v6

Composto significa que as duas partes precisam ser bem-sucedidas: um atacante tem que quebrar o ML-KEM e o X25519, ou o ML-DSA e o Ed25519. A criptografia é a metade urgente, porque mensagens criptografadas podem ser armazenadas agora e descriptografadas depois (coletar agora, descriptografar depois, em inglês harvest now, decrypt later). As assinaturas podem esperar até que os verificadores ofereçam suporte a elas, e assinaturas de longa duração podem ser refeitas mais tarde. Como o ID 35 também é permitido em subchaves v4, uma chave v4 existente pode ganhar uma subchave de criptografia pós-quântica sem substituir a chave primária.

Recomendações práticas

  1. Chaves de assinatura para releases, commits do Git e pacotes: v4 Ed25519, criadas pelo GnuPG 2.4/2.5 (default) ou pelo sq (perfil padrão). Todos os verificadores que testamos as aceitam. O APT do Debian agora verifica por padrão as assinaturas dos repositórios com o sqv do Sequoia (APT 3.0, Debian 13) e, desde 1º de fevereiro de 2026, rejeita assinaturas vinculadas a SHA-1 e assinaturas v3; por isso, assine de novo tudo o que for antigo (LWN sobre o APT 3.0).
  2. Não publique chaves v6 para um público que você não controla até que as ferramentas desse público usem o Sequoia, o OpenPGP.js 6 (que implementa a RFC 9580) ou outra implementação da RFC 9580; os usuários do GnuPG 2.4 não conseguem importá-las.
  3. A criptografia com proteção pós-quântica hoje só funciona dentro de um mesmo dialeto: de GnuPG para GnuPG com o Kyber do LibrePGP, ou o Sequoia com um backend OpenSSL ou RustCrypto para a RFC 9980. Decida com base em quem vai descriptografar.
  4. Confira o backend e as versões (gpg --version, sq version); os pacotes das distribuições ficam um ano ou mais atrás do upstream.
  5. Prefira ferramentas mais simples quando a flexibilidade do OpenPGP não for necessária: assinaturas SSH para commits do Git, Sigstore para a proveniência de releases, age para criptografar arquivos. As comparações SSH vs GPG para assinar commits, Sigstore vs GPG e age vs GPG tratam dos prós e contras; o artigo ssh-keygen em 2026 cobre o lado do SSH.
  6. Publique a impressão digital completa onde as pessoas possam conferi-la (seu site, as notas de versão) e distribua a chave por WKD ou pelo keys.openpgp.org. Um servidor de chaves entrega chaves; ele não atesta a autenticidade delas.

Como verificar um download do jeito certo

O F-Droid publica uma assinatura desanexada ao lado do APK e a impressão digital da chave de assinatura no próprio site. A verificação leva três comandos:

Verificar o F-Droid.apk com o .asc correspondente (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
Saída (filtrada)
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

A linha “WARNING: This key is not certified” é normal: a rede de confiança do GnuPG não tem nenhum caminho até essa chave. O que dá sentido à verificação é comparar a impressão digital da chave primária com a da página de verificação do F-Droid (são idênticas) e exigir a impressão digital completa ao buscar a chave, já que o servidor de chaves entrega qualquer chave que corresponda. A assinatura em si é uma assinatura RSA v4 (algoritmo 1) sobre SHA-512 (algoritmo de digest 10): formato antigo, hash atual, legível por todas as implementações. Se a chave estiver faltando, você recebe Can't check signature: No public key; se o arquivo foi alterado, BAD signature.

Fontes