Saltar al contenido
ecdsa.com
← Todos los artículos

OpenPGP en 2026: RFC 9580, claves v6 y el cisma de GnuPG

OpenPGP tiene dos dialectos que divergen y un nuevo estándar poscuántico. Generamos claves v4, v6 y poscuánticas con Sequoia sq 1.4.1, GnuPG 2.4.9 y GnuPG 2.5.24, compilado a partir de su código fuente firmado, y pasamos cada una de ellas a las otras dos implementaciones. Los resultados deciden qué puedes publicar sin riesgo.

Respuesta breve. El IETF revisó OpenPGP en el RFC 9580 (julio de 2024): claves v6 con huellas digitales SHA-256, Ed25519 y X25519 como algoritmos obligatorios, firmas con sal, Argon2 y cifrado autenticado. Los algoritmos poscuánticos llegaron después con el RFC 9980 (2026), sobre todo para claves v6. GnuPG no adoptó el RFC 9580: sigue LibrePGP, una continuación propia con claves v5 y su propio cifrado con Kyber, y solo admite una parte del RFC 9980, que se activa con --allow-9980. Sequoia implementa el RFC 9580 y el RFC 9980, pero sigue creando claves v4 de forma predeterminada. En la práctica: para las claves que otros deben verificar con lo que tengan a mano (plataformas de Git, gestores de paquetes, páginas de versiones), usa hoy una clave v4 Ed25519/Cv25519; funciona en todos los lugares donde la probamos. Usa claves v6 o poscuánticas solo dentro de ecosistemas en los que todos los verificadores ejecuten Sequoia u otra implementación del RFC 9580.

Las pruebas se hicieron en debian:forky-20261005-slim con los paquetes de Debian sq 1.4.1 (sequoia-openpgp 2.4.1, backend Nettle) y gnupg 2.4.9, además de GnuPG 2.5.24, compilado en la misma imagen a partir del tarball de la versión después de que gpg --verify informara de una firma correcta de «Werner Koch (dist signing 2020)». Todas las claves se generaron para este artículo.

Dos estándares desde 2023

La especificación anterior de OpenPGP, el RFC 4880, data de 2007. Su revisión dividió a la comunidad. El grupo de trabajo del IETF produjo lo que acabó siendo el RFC 9580; los desarrolladores de GnuPG, en desacuerdo con partes de él, continuaron el borrador anterior como LibrePGP (draft-koch-librepgp, un Internet-Draft individual de Werner Koch y Ronald Henry Tse, revisión 06, de septiembre de 2026), con claves de la versión 5 y otro modo de cifrado autenticado. Los dos son incompatibles en los formatos nuevos de clave y de mensaje, y compatibles en los antiguos: todos siguen leyendo y escribiendo claves v4 y firmas v4.

El RFC 9580 es claro sobre el formato antiguo: «Las implementaciones de OpenPGP deberían (SHOULD) crear claves con el formato de la versión 6. Las claves de la versión 4 están obsoletas; una implementación no debería (SHOULD NOT) generar una clave de la versión 4, pero sí debería (SHOULD) aceptarla» (§5.5.2). Define las versiones 2, 3, 4 y 6 del paquete de clave; la versión 5 solo existe en LibrePGP. Sus otros cambios:

  • Ed25519 (algoritmo 27) y X25519 (25) son de implementación obligatoria; las claves RSA «están obsoletas y no deberían (SHOULD NOT) generarse, pero pueden interpretarse», y las claves DSA y ElGamal no deben generarse (§9.1).
  • Las huellas digitales v6 son «el hash SHA2-256 de 256 bits» de la clave (§5.5.4.3); las huellas v4 son SHA-1 de 160 bits.
  • Las firmas v6 llevan una sal aleatoria, de modo que el hash firmado no se puede predecir de antemano.
  • Los datos cifrados usan SEIPD versión 2 con AEAD (OCB obligatorio), y las frases de contraseña pueden usar Argon2.

Sequoia: claves v6 a petición

sq key generate crea de forma predeterminada una clave v4. Su texto de ayuda explica por qué: «Actualmente, el valor predeterminado es RFC4880. Sin embargo, cuando la compatibilidad con RFC9580 esté más extendida, el valor predeterminado cambiará en una versión futura de sq». Con --profile rfc9580 crea una clave v6:

Dos claves con sq 1.4.1: el perfil predeterminado y 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
Salida (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

La diferencia se ve en las huellas digitales: 40 dígitos hexadecimales (SHA-1) en v4 y 64 (SHA-256) en v6. La clave v4 usa el identificador de algoritmo EdDSA, más antiguo (22, «EdDSALegacy» en el RFC 9580), y la clave v6, los nuevos identificadores específicos Ed25519 (27) y X25519 (25). Una firma separada hecha con la clave v6 muestra la sal:

sq sign, luego sq packet dump de la firma y 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.

Las claves poscuánticas están en la biblioteca: sequoia-openpgp 2.4.0 «añade compatibilidad con la criptografía poscuántica tal como la define el RFC 9980», y sq ofrece los conjuntos de cifrado mldsa65-ed25519 y mldsa87-ed448. Pero el código PQC solo existe en los backends OpenSSL y RustCrypto, y Debian compila Sequoia con Nettle:

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

El backend criptográfico que eligió tu distribución decide si tienes OpenPGP poscuántico o no; sq version lo muestra.

GnuPG: LibrePGP, Kyber y la transición de 2.4 a 2.5

GnuPG 2.5 pasó a ser la serie estable el 30 de diciembre de 2025, cuando GnuPG anunció que «la serie oldstable 2.4 llegará al final de su vida útil en solo 6 meses» (gnupg.org); la versión actual es la 2.5.24 (23 de septiembre de 2026). Las distribuciones avanzan despacio: la rama testing de Debian sigue distribuyendo la 2.4.9. La clave predeterminada de esta versión es una clave v4 Ed25519 con una subclave Cv25519:

gpg 2.4.9 --quick-gen-key 'Bob <bob@example.org>' default default 1y, luego --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 añadió el cifrado poscuántico en la 2.5: una combinación de ML-KEM (Kyber) y una curva clásica, en el formato de LibrePGP. Hasta ahora, su trabajo poscuántico abarca el cifrado; las notas de la versión no mencionan claves de firma poscuánticas. Su documentación describe la compatibilidad con el RFC 9980, añadida en la 2.5.23 y disponible con la opción --allow-9980, con una franqueza poco habitual: «Por lo inflado de la especificación, no se recomienda usar esta opción. El modo estándar de GnuPG se orienta más a la especificación clásica de PGP y, por tanto, a la de LibrePGP, que también admite PQC, pero de una forma más ligera y al estilo de PGP».

Interoperabilidad, puesta a prueba

Intercambiamos cada clave entre las tres implementaciones. Primero, GnuPG 2.4.9 lee las claves y las firmas de Sequoia:

gpg 2.4.9 --import y --verify de las claves v4 y v6 de 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

Después, las claves poscuánticas de GnuPG 2.5.24, leídas por GnuPG 2.4.9 y por sq 1.4.1:

Tres claves poscuánticas de gpg 2.5.24 (algoritmo y versión de paquete según --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

Lo que esto muestra:

  • Las claves y las firmas v4 funcionan en todas partes. La clave predeterminada de sq y sus firmas se verificaron en GnuPG 2.4.9.
  • Las claves v6 fallan en GnuPG 2.4, con packet(6) with unknown version 6. Quien importe tu clave v6 en un anillo de claves de la 2.4 no obtiene nada; para una firma v6, el resultado es «no signature found».
  • La clave PQC predeterminada de GnuPG es exclusiva de LibrePGP. pqc creó una clave principal brainpoolP384r1 con una subclave Kyber-768 más brainpoolP256r1 (algoritmo 8) en un paquete v5. GnuPG 2.4.9 la importa, pero muestra la subclave como unknown_8, así que no puede cifrar para ella; Sequoia rechaza el paquete v5.
  • Ni siquiera el «modo 9980» produjo algo que Sequoia pueda leer. Con --allow-9980, GnuPG 2.5.24 creó una clave principal v6, pero escribió sus subclaves ML-KEM, incluida mlk768 (algoritmo 35, ML-KEM-768+X25519 del RFC 9980), como paquetes de la versión 5, que el RFC 9580 no define y que Sequoia rechaza. Además, el valor predeterminado de pqc9980 elige el algoritmo 39, ML-KEM-768 con brainpoolP384r1, que no figura entre los algoritmos propios del RFC 9980. En GnuPG 2.5.24, una clave RFC 9980 creada por GnuPG y una implementación del RFC 9980 todavía no llegan a entenderse.

El cifrado y el descifrado dentro de GnuPG 2.5 funcionaron con todas estas claves; el problema solo aparece entre implementaciones.

OpenPGP poscuántico: qué define el RFC 9980

El RFC 9980 (estándar propuesto, 2026) añade algoritmos compuestos e independientes:

IDAlgoritmoRequisitoClaves
30ML-DSA-65+Ed25519MUSTv6
31ML-DSA-87+Ed448SHOULDv6
32–34SLH-DSA-SHAKE-128s, 128f, 256sMAYv6
35ML-KEM-768+X25519MUSTv4 o v6
36ML-KEM-1024+X448SHOULDv6

Compuesto significa que las dos partes deben completarse con éxito: un atacante tiene que romper ML-KEM y X25519, o ML-DSA y Ed25519. El cifrado es la mitad urgente, porque los mensajes cifrados pueden almacenarse ahora y descifrarse más adelante («cosechar ahora, descifrar después», en inglés harvest now, decrypt later). Las firmas pueden esperar hasta que los verificadores las admitan, y las firmas de larga duración pueden volver a hacerse más adelante. Como el ID 35 también se permite en subclaves v4, una clave v4 existente puede añadir una subclave de cifrado poscuántica sin sustituir su clave principal.

Recomendaciones prácticas

  1. Claves de firma para versiones, commits de Git y paquetes: v4 Ed25519, creadas con GnuPG 2.4/2.5 (default) o con sq (perfil predeterminado). Todos los verificadores que probamos las aceptan. APT de Debian verifica ahora de forma predeterminada las firmas de los repositorios con sqv de Sequoia (APT 3.0, Debian 13) y, desde el 1 de febrero de 2026, rechaza las firmas ligadas a SHA-1 y las firmas v3, así que vuelve a firmar todo lo antiguo (LWN sobre APT 3.0).
  2. No publiques claves v6 para destinatarios que no controlas hasta que sus herramientas usen Sequoia, OpenPGP.js 6 (que implementa el RFC 9580) u otra implementación del RFC 9580; los usuarios de GnuPG 2.4 no pueden importarlas.
  3. El cifrado con protección poscuántica funciona hoy solo dentro de un mismo dialecto: de GnuPG a GnuPG con el Kyber de LibrePGP, o Sequoia con un backend OpenSSL o RustCrypto para el RFC 9980. Decide según quién vaya a descifrar.
  4. Comprueba tu backend y tus versiones (gpg --version, sq version); los paquetes de las distribuciones van un año o más por detrás del proyecto original.
  5. Prefiere herramientas más sencillas donde no necesites la flexibilidad de OpenPGP: firmas SSH para los commits de Git, Sigstore para la procedencia de las versiones, age para cifrar archivos. Las comparativas SSH o GPG para firmar commits, Sigstore o GPG y age frente a GPG analizan las ventajas y los inconvenientes de cada opción; ssh-keygen en 2026 cubre la parte de SSH.
  6. Publica la huella digital completa donde la gente pueda comprobarla (tu sitio web, las notas de la versión) y distribuye la clave mediante WKD o keys.openpgp.org. Un servidor de claves entrega claves; no las avala.

Cómo verificar una descarga como es debido

F-Droid publica una firma separada junto a su APK, y la huella digital de su clave de firma, en su sitio web. La verificación requiere tres comandos:

Verificar F-Droid.apk con su .asc (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
Salida (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

La línea «WARNING: This key is not certified» es normal: la red de confianza de GnuPG no tiene ningún camino hasta esta clave. Lo que da sentido a la comprobación es comparar la huella digital de la clave principal con la de la página de verificación de F-Droid (idéntica) y exigir la huella completa al obtener la clave, porque el servidor de claves entrega cualquier clave que coincida. La firma en sí es una firma RSA v4 (algoritmo 1) sobre SHA-512 (algoritmo de resumen 10): formato antiguo, hash actual, legible para todas las implementaciones. Si falta la clave, obtienes Can't check signature: No public key; si el archivo cambió, BAD signature.

Fuentes