Saltar al contenido
ecdsa.com
Línea de comandos

GnuPG (gpg)

GnuPG 2.4, la implementación de OpenPGP detrás de gpg: claves Ed25519 que caducan a los tres años por defecto, ECDSA determinista RFC 6979 en las curvas NIST, Brainpool y secp256k1, firmas Ed25519 sobre un resumen y, por ahora, ningún algoritmo poscuántico.
Licencia
GPL-3.0-or-later
Versión comprobada
2.4.9 ·
Código fuente
dev.gnupg.org/source/gnupg/
Documentación
www.gnupg.org/documentation/manuals/gnupg/

Compatibilidad de un vistazo

ECDSAEdDSA

Curvas ECDSA
P-256P-384P-521secp256k1brainpoolP256r1brainpoolP384r1brainpoolP512r1
EdDSA
Ed25519Ed448

GnuPG implementa OpenPGP para firmar y cifrar archivos y correo electrónico, para la firma de paquetes en muchas distribuciones Linux y para la firma de commits de git. Los datos de esta página se comprobaron con el paquete de Alpine 3.24.2, GnuPG 2.4.9 con libgcrypt 1.12.2. gpg --quick-gen-key con solo un ID de usuario crea una clave principal Ed25519 para firma y certificación más una subclave de cifrado Curve25519 (cv25519), ambas como claves de versión 4, y la clave principal caduca a los 1095 días —tres años— salvo que se indique una caducidad. Inspecciona claves y firmas con el inspector de OpenPGP.

Se pueden crear claves ECDSA en P-256, P-384, P-521, secp256k1 y las tres curvas Brainpool r1; nistp224 falla con «Unknown elliptic curve». El paquete de firma lleva r y s como dos MPI de OpenPGP, ni DER ni r‖s de ancho fijo. Las firmas P-256 usan SHA-256 por defecto; pedir SHA-256 con una clave P-384 falla con «signing failed: Invalid length», mientras que SHA-512 con una clave P-256 se acepta.

Los nonces son deterministas: con el reloj congelado (--faked-system-time), dos firmas de un mismo archivo fueron idénticas byte a byte, y r coincidió con una implementación independiente de RFC 6979, así que firmar dos veces los mismos datos no reutiliza un nonce de forma peligrosa. s no se normaliza, y una firma con s sustituido por n − s se verificó como correcta, algo relevante allí donde se espera que las firmas sean únicas.

Las firmas Ed25519 usan el formato EdDSA heredado (algoritmo 22): R y S son MPI, y lo que firma Ed25519 es el resumen SHA-512 del archivo y de los campos de la firma incluidos en el hash, no el archivo en sí. Rellenados por la izquierda a 32 bytes cada uno, R‖S se verificó con OpenSSL contra ese resumen y falló contra el archivo: verificar firmas de gpg con una biblioteca Ed25519 de uso general exige calcular primero el resumen OpenPGP. Las claves Ed448 se crean como paquetes de clave de versión 5, el formato del borrador LibrePGP que sigue GnuPG, mientras que la clave predeterminada y las claves ECDSA y Ed25519 comprobadas eran todas de versión 4; asegúrate de que la otra parte lea la versión 5 antes de elegir Ed448. Esta versión no tiene ningún algoritmo poscuántico: la lista de algoritmos de clave pública es RSA, ELG, DSA, ECDH, ECDSA y EDDSA, y ky768_cv25519 se rechaza como curva desconocida.

En scripts, lee la salida legible por máquina de --status-fd en lugar del texto: una firma válida dio GOODSIG y VALIDSIG con código de salida 0, una firma sobre otros datos, BADSIG con código de salida 1, y un paquete truncado, NODATA con código de salida 2. gpg --export-ssh-key con una huella digital y ! escribe una línea de clave pública OpenSSH para claves ECDSA y Ed25519, mientras que --export y --export-secret-keys escriben paquetes OpenPGP.

Datos y las comprobaciones que los respaldan

Nada de lo que sigue está copiado de la documentación. La comprobación content/libraries/verify/gnupg/run.sh ejecutó GnuPG (gpg) 2.4.9 en la imagen de contenedor alpine:3.24.2 el 20 de octubre de 2026; la página debe coincidir con lo que imprimió, y cada dato cita esas líneas.

  • Tipo de clave predeterminado

    ed25519cv25519

    --quick-gen-key con solo un ID de usuario creó una clave principal ed25519 (uso sc) y una subclave cv25519 (uso e).

    Registrado por la comprobación
    fact default-key-type = ed25519, cv25519
    evidence default-key-type: pub ed25519 (algorithm 22, usage scESC); sub cv25519 (algorithm 18, usage e)
  • Caducidad predeterminada de la clave

    1095d

    La caducidad de la clave principal quedó fijada 1095 días después de su creación.

    Registrado por la comprobación
    fact default-key-expiry = 1095d
    evidence default-key-expiry: expiration minus creation of the primary key: 1095 days
  • Versión de clave OpenPGP

    v4

    La clave predeterminada se exportó como paquete de clave de versión 4.

    Registrado por la comprobación
    fact openpgp-key-version = v4
  • Versión de las claves Ed448

    v5

    Una clave ed448 se exportó como paquete de clave de versión 5; la clave predeterminada y las claves ECDSA y ed25519, como versión 4.

    Registrado por la comprobación
    fact ed448-key-version = v5
    evidence ed448-key-version: key packet versions: default v4, nistp256 v4, nistp384 v4, nistp521 v4, secp256k1 v4, brainpoolP256r1 v4, brainpoolP384r1 v4, brainpoolP512r1 v4, ed25519 v4, ed448 v5
  • Curvas ECDSA

    P-256P-384P-521secp256k1brainpoolP256r1brainpoolP384r1brainpoolP512r1

    Las siete curvas generaron claves con las que se firmó y se verificó; nistp224 devolvió «Unknown elliptic curve».

    Registrado por la comprobación
    fact ecdsa-curves = P-256, P-384, P-521, secp256k1, brainpoolP256r1, brainpoolP384r1, brainpoolP512r1
    evidence ecdsa-curves: nistp224: gpg: Key generation failed: Unknown elliptic curve
  • EdDSA

    Ed25519Ed448

    Con claves ed25519 y ed448 se firmó y se verificó.

    Registrado por la comprobación
    fact eddsa = Ed25519, Ed448
  • Algoritmos poscuánticos

    none

    La línea Pubkey: de gpg --version no incluye ningún algoritmo poscuántico, y la generación de claves ky768_cv25519 falló.

    Registrado por la comprobación
    fact pqc = none
    evidence pqc: --quick-gen-key with ky768_cv25519: gpg: Key generation failed: Unknown elliptic curve
  • Codificación de la firma ECDSA

    openpgp-mpi

    El paquete de firma P-256 (algoritmo 19) termina en dos MPI, r y s.

    Registrado por la comprobación
    fact ecdsa-signature-encoding = openpgp-mpi
    evidence ecdsa-signature-encoding: P-256 detached signature: version=4 pubkey-algo=19 hash-algo=8 mpis=2
  • Hash predeterminado

    sha256

    La firma P-256 predeterminada indica el algoritmo hash 8, SHA-256.

    Registrado por la comprobación
    fact ecdsa-default-hash = sha256
  • Nonce de ECDSA

    rfc6979

    Dos firmas con el reloj congelado fueron idénticas, y r coincidió con el firmante de referencia RFC 6979.

    Registrado por la comprobación
    fact ecdsa-nonce = rfc6979
    evidence ecdsa-nonce: two signatures of one file with a frozen clock are identical; r equals the RFC 6979 reference signer's r: yes
  • Low-S al firmar

    either

    s no se normaliza: aparecieron valores high-S entre 32 firmas.

    Registrado por la comprobación
    fact ecdsa-low-s-sign = either
    evidence ecdsa-low-s-sign: signatures with s > n/2 among 32: yes
  • High-S al verificar

    accepts-high-s

    Una firma con s sustituido por n − s se verificó con GOODSIG y código de salida 0.

    Registrado por la comprobación
    fact ecdsa-low-s-verify = accepts-high-s
    evidence ecdsa-low-s-verify: s replaced by n - s: exit 0, status NEWSIG KEY_CONSIDERED SIG_ID GOODSIG VALIDSIG TRUST_ULTIMATE
  • Hash vinculado a la curva

    enforced

    --digest-algo SHA256 con una clave P-384 falló con «Invalid length»; con SHA-512 y una clave P-256 se firmó.

    Registrado por la comprobación
    fact ecdsa-hash-curve-binding = enforced
    evidence ecdsa-hash-curve-binding: --digest-algo SHA256 with a P-384 key: gpg: signing failed: Invalid length; --digest-algo SHA512 with a P-256 key: signed
  • Salida de la verificación en caso de fallo

    distinguishable

    BADSIG y código de salida 1 para un mensaje incorrecto; NODATA y código de salida 2 para un paquete truncado.

    Registrado por la comprobación
    fact cli-verify-output = distinguishable
    evidence cli-verify-output: valid: exit 0, status NEWSIG KEY_CONSIDERED SIG_ID GOODSIG VALIDSIG TRUST_ULTIMATE
    evidence cli-verify-output: wrong message: exit 1, status NEWSIG KEY_CONSIDERED BADSIG FAILURE
    evidence cli-verify-output: truncated signature packet: exit 2, status NODATA FAILURE
  • Qué cubre la firma Ed25519

    digest

    R‖S se verificó con openssl pkeyutl sobre el resumen de la firma OpenPGP y falló sobre el archivo.

    Registrado por la comprobación
    fact ed25519-signed-input = digest
    evidence ed25519-signed-input: version=4 pubkey-algo=22 hash-algo=10 mpis=2; R || S checked by openssl pkeyutl over the signature digest: Signature Verified Successfully; over the file: Signature Verification Failure
  • Formatos de clave pública

    opensshopenpgp

    gpg --export escribe paquetes OpenPGP; --export-ssh-key escribió líneas ecdsa-sha2-nistp256 y ssh-ed25519.

    Registrado por la comprobación
    fact public-key-formats = openssh, openpgp
    evidence public-key-formats: gpg --export: public key packet; gpg --export-ssh-key: P-256 key ecdsa-sha2-nistp256, Ed25519 key ssh-ed25519
  • Formatos de clave privada

    openpgp

    gpg --export-secret-keys escribe paquetes de clave secreta OpenPGP.

    Registrado por la comprobación
    fact private-key-formats = openpgp
    evidence private-key-formats: gpg --export-secret-keys: secret key packet

Uso

Crea una clave predeterminada, genera una firma separada con armadura ASCII y compruébala a través de la salida de estado.
export GNUPGHOME="$(mktemp -d)"
# With only a user ID: an Ed25519 signing key plus a Curve25519 encryption subkey, expiring in 3 years.
gpg --batch --pinentry-mode loopback --passphrase '' --quick-gen-key 'Alice <alice@example.com>'

printf 'order #1042 approved\n' > order.txt
gpg --batch --yes --armor --detach-sign order.txt   # writes order.txt.asc

# Scripts should read --status-fd: GOODSIG and VALIDSIG for a valid signature, BADSIG otherwise.
gpg --batch --status-fd 1 --verify order.txt.asc order.txt 2>/dev/null | grep -E '^\[GNUPG:\] (GOODSIG|VALIDSIG)' | cut -d' ' -f2

El arnés de pruebas de fragmentos de código ejecuta cada ejemplo tal cual en la imagen de contenedor alpine:3.24.2, y la ejecución falla si la salida no coincide.

Configuración
apk add --no-cache -q gnupg=2.4.9-r1 >/dev/null
Comando
sh sign.sh
La salida debe coincidir (expresión regular)
GOODSIG\nVALIDSIG

Bibliotecas