Pular para o conteúdo
ecdsa.com
Linha de comando

GnuPG (gpg)

O GnuPG 2.4, a implementação de OpenPGP por trás do gpg: chaves Ed25519 que expiram após três anos por padrão, ECDSA determinístico RFC 6979 nas curvas do NIST, Brainpool e secp256k1, assinaturas Ed25519 sobre um digest e, por enquanto, nenhum algoritmo pós-quântico.
Licença
GPL-3.0-or-later
Versão verificada
2.4.9 ·
Código-fonte
dev.gnupg.org/source/gnupg/
Documentação
www.gnupg.org/documentation/manuals/gnupg/

Visão geral da compatibilidade

ECDSAEdDSA

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

O GnuPG implementa o OpenPGP para assinatura e criptografia de arquivos e e-mails, assinatura de pacotes em muitas distribuições Linux e assinatura de commits do git. Os fatos desta página foram verificados no pacote do Alpine 3.24.2, GnuPG 2.4.9 com libgcrypt 1.12.2. gpg --quick-gen-key só com um ID de usuário cria uma chave primária Ed25519 para assinatura e certificação, mais uma subchave de criptografia Curve25519 (cv25519), ambas como chaves da versão 4, e a chave primária expira após 1.095 dias — três anos — a menos que você informe outra expiração. Inspecione chaves e assinaturas com o inspetor de OpenPGP.

É possível criar chaves ECDSA na P-256, P-384, P-521, secp256k1 e nas três curvas Brainpool r1; nistp224 falha com “Unknown elliptic curve”. O pacote de assinatura traz r e s como dois MPIs do OpenPGP, nem DER nem r‖s de largura fixa. As assinaturas P-256 usam SHA-256 por padrão; pedir SHA-256 com uma chave P-384 falha com “signing failed: Invalid length”, enquanto SHA-512 com uma chave P-256 é aceito.

Os nonces são determinísticos: com o relógio congelado (--faked-system-time), duas assinaturas de um mesmo arquivo ficaram idênticas byte a byte, e o r coincidiu com uma implementação independente da RFC 6979; portanto, assinar os mesmos dados duas vezes não reutiliza um nonce de forma perigosa. O s não é normalizado, e uma assinatura com s substituído por n − s foi verificada como válida — algo relevante sempre que se espera que as assinaturas sejam únicas.

As assinaturas Ed25519 usam o formato EdDSA legado (algoritmo 22): R e S são MPIs, e o que o Ed25519 assina é o digest SHA-512 do arquivo e dos campos da assinatura incluídos no hash, não o próprio arquivo. Com R e S preenchidos à esquerda até 32 bytes cada, o R‖S foi verificado com o OpenSSL contra esse digest e falhou contra o arquivo — verificar assinaturas do gpg com uma biblioteca Ed25519 de uso geral exige calcular antes o digest OpenPGP. As chaves Ed448 são criadas como pacotes de chave da versão 5, o formato do rascunho LibrePGP que o GnuPG segue, enquanto as chaves padrão, ECDSA e Ed25519 testadas eram todas da versão 4; confirme que o outro lado lê a versão 5 antes de escolher Ed448. Esta versão não tem nenhum algoritmo pós-quântico: a lista de algoritmos de chave pública é RSA, ELG, DSA, ECDH, ECDSA e EDDSA, e ky768_cv25519 é rejeitado como curva desconhecida.

Em scripts, leia a saída legível por máquina de --status-fd em vez do texto: uma assinatura válida gerou GOODSIG e VALIDSIG com código de saída 0; uma assinatura sobre outros dados, BADSIG com código de saída 1; e um pacote truncado, NODATA com código de saída 2. gpg --export-ssh-key com uma impressão digital e ! grava uma linha de chave pública OpenSSH para chaves ECDSA e Ed25519, enquanto --export e --export-secret-keys gravam pacotes OpenPGP.

Os fatos e as verificações por trás deles

Nada abaixo foi copiado da documentação. A verificação content/libraries/verify/gnupg/run.sh executou GnuPG (gpg) 2.4.9 na imagem de contêiner alpine:3.24.2 em 20 de outubro de 2026; a página precisa corresponder ao que a verificação imprimiu, e cada fato lista essas linhas.

  • Tipo de chave padrão

    ed25519cv25519

    --quick-gen-key só com um ID de usuário criou uma chave primária ed25519 (uso sc) e uma subchave cv25519 (uso e).

    Registrado pela verificação
    fact default-key-type = ed25519, cv25519
    evidence default-key-type: pub ed25519 (algorithm 22, usage scESC); sub cv25519 (algorithm 18, usage e)
  • Expiração padrão da chave

    1095d

    A data de expiração da chave primária era 1.095 dias após a criação.

    Registrado pela verificação
    fact default-key-expiry = 1095d
    evidence default-key-expiry: expiration minus creation of the primary key: 1095 days
  • Versão da chave OpenPGP

    v4

    A chave padrão foi exportada como um pacote de chave da versão 4.

    Registrado pela verificação
    fact openpgp-key-version = v4
  • Versão da chave Ed448

    v5

    Uma chave ed448 foi exportada como um pacote de chave da versão 5; a chave padrão e as chaves ECDSA e ed25519, como versão 4.

    Registrado pela verificação
    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

    As sete curvas geraram chaves que assinaram e verificaram; nistp224 retornou “Unknown elliptic curve”.

    Registrado pela verificação
    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

    Assinatura e verificação funcionaram com chaves ed25519 e ed448.

    Registrado pela verificação
    fact eddsa = Ed25519, Ed448
  • Algoritmos pós-quânticos

    none

    A linha Pubkey: de gpg --version não lista nenhum algoritmo pós-quântico, e a geração de chave ky768_cv25519 falhou.

    Registrado pela verificação
    fact pqc = none
    evidence pqc: --quick-gen-key with ky768_cv25519: gpg: Key generation failed: Unknown elliptic curve
  • Codificação da assinatura ECDSA

    openpgp-mpi

    O pacote de assinatura P-256 (algoritmo 19) termina em dois MPIs, r e s.

    Registrado pela verificação
    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 padrão

    sha256

    A assinatura P-256 padrão indica o algoritmo de hash 8, SHA-256.

    Registrado pela verificação
    fact ecdsa-default-hash = sha256
  • Nonce do ECDSA

    rfc6979

    Duas assinaturas com o relógio congelado foram idênticas, e o r coincidiu com o do signatário de referência da RFC 6979.

    Registrado pela verificação
    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 ao assinar

    either

    O s não é normalizado: valores high-S apareceram entre 32 assinaturas.

    Registrado pela verificação
    fact ecdsa-low-s-sign = either
    evidence ecdsa-low-s-sign: signatures with s > n/2 among 32: yes
  • High-S ao verificar

    accepts-high-s

    Uma assinatura com s substituído por n − s foi verificada com GOODSIG e código de saída 0.

    Registrado pela verificação
    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 à curva

    enforced

    --digest-algo SHA256 com uma chave P-384 falhou com “Invalid length”; a assinatura com SHA-512 e uma chave P-256 funcionou.

    Registrado pela verificação
    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
  • Saída da verificação em caso de falha

    distinguishable

    BADSIG e código de saída 1 para uma mensagem errada; NODATA e código de saída 2 para um pacote truncado.

    Registrado pela verificação
    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
  • O que a assinatura Ed25519 cobre

    digest

    R‖S foi verificado com openssl pkeyutl sobre o digest da assinatura OpenPGP e falhou sobre o arquivo.

    Registrado pela verificação
    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 chave pública

    opensshopenpgp

    gpg --export grava pacotes OpenPGP; --export-ssh-key gravou linhas ecdsa-sha2-nistp256 e ssh-ed25519.

    Registrado pela verificação
    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 chave privada

    openpgp

    gpg --export-secret-keys grava pacotes de chave secreta do OpenPGP.

    Registrado pela verificação
    fact private-key-formats = openpgp
    evidence private-key-formats: gpg --export-secret-keys: secret key packet

Uso

Crie uma chave padrão, gere uma assinatura desanexada em armadura ASCII e verifique-a pela saída de status.
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

O executor de trechos de código roda cada exemplo literalmente na imagem de contêiner alpine:3.24.2, e a execução falha se a saída não corresponder.

Configuração
apk add --no-cache -q gnupg=2.4.9-r1 >/dev/null
Comando
sh sign.sh
A saída deve corresponder a (expressão regular)
GOODSIG\nVALIDSIG

Bibliotecas