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

LibreSSL

O LibreSSL do OpenBSD, o fork do OpenSSL de 2014 usado pelo OpenBSD e pelas ferramentas de sistema do macOS: o mesmo ECDSA em DER e os mesmos formatos de chave, Ed25519 mas não Ed448, ML-KEM por meio de uma API própria, sem ML-DSA e sem RFC 6979.
Licença
OpenSSL AND ISC
Versão verificada
4.3.1 ·
Código-fonte
github.com/libressl/portable
Documentação
man.openbsd.org/

Visão geral da compatibilidade

ECDSAEdDSAPós-quântica

Curvas ECDSA
P-224P-256P-384P-521secp256k1brainpoolP256r1brainpoolP384r1brainpoolP512r1
EdDSA
Ed25519
Formatos de chave pública
spki-pemspki-derx509
Formatos de chave privada
pkcs8-pempkcs8-derencrypted-pkcs8sec1-pemsec1-der

O LibreSSL mantém a conhecida API libcrypto/libssl e a linha de comando do OpenSSL, removendo código legado, e acrescenta sua própria libtls. O macOS traz um LibreSSL mais antigo como criptografia do sistema: no macOS 27.0.1, /usr/bin/openssl version imprimiu LibreSSL 3.3.6, e ssh -V citou a mesma biblioteca. Os fatos desta página foram verificados no pacote do Alpine 3.24.2, LibreSSL 4.3.1 (o projeto original já estava na 4.3.3), em que o comando é instalado como libressl — scripts que chamam openssl falham ali, a menos que o pacote de compatibilidade seja adicionado.

O ECDSA se comporta como nos padrões do OpenSSL: assinaturas DER, nonces aleatórios, nenhuma normalização low-S e uma verificação que aceita high-S. Ao contrário do OpenSSL 3.2+, não há opção determinística da RFC 6979. EVP_DigestVerify retornou -1 para uma assinatura r‖s bruta, e a linha de comando imprimiu Error Verifying Data para ela, contra Verification Failure para uma assinatura válida sobre outros dados — repare que o uso de maiúsculas difere das mensagens do OpenSSL, o que quebra scripts que fazem grep pelo texto exato.

As curvas vão da P-224 à P-521, além de secp256k1 e das curvas Brainpool r1; o Ed25519 funciona por meio de EVP_PKEY_ED25519, e não há Ed448 de forma alguma. Os arquivos de chave são interoperáveis com o OpenSSL: SPKI e certificados para chaves públicas, PKCS#8 (simples e criptografado) e SEC1 para chaves privadas; ecparam -genkey grava SEC1 EC PRIVATE KEY, então converta com pkcs8 -topk8 quando outra ferramenta exigir PKCS#8, como faz o exemplo.

O suporte pós-quântico é parcial: ML-KEM-768 e ML-KEM-1024 estão disponíveis pelas funções MLKEM_* do próprio LibreSSL em <openssl/mlkem.h>, e não pela EVP nem pela linha de comando, e o ML-DSA não existe (Algorithm ML-DSA-65 not found). Compare os algoritmos no playground de KEM pós-quântico; para assinaturas com ML-DSA, use o OpenSSL 3.5 ou posterior.

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

Nada abaixo foi copiado da documentação. A verificação content/libraries/verify/libressl/run.sh executou LibreSSL 4.3.1 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.

  • Codificação da assinatura ECDSA

    der

    EVP_DigestSign e libressl dgst -sign produzem ASN.1 DER.

    Registrado pela verificação
    fact ecdsa-signature-encoding = der
  • Nonce do ECDSA

    random

    Nonce aleatório: duas assinaturas da mesma mensagem são diferentes; não há opção determinística.

    Registrado pela verificação
    fact ecdsa-nonce = random
  • Low-S ao assinar

    either

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

    Registrado pela verificação
    fact ecdsa-low-s-sign = either
  • High-S ao verificar

    accepts-high-s

    Uma assinatura DER com s substituído por n − s foi verificada.

    Registrado pela verificação
    fact ecdsa-low-s-verify = accepts-high-s
  • Entrada do hash na chamada de assinatura

    hashes-message-or-digest

    EVP_DigestSign calcula o hash; ECDSA_sign assina um digest, e essa assinatura foi verificada contra a mensagem.

    Registrado pela verificação
    fact ecdsa-prehash = hashes-message-or-digest
  • Assinatura ECDSA malformada

    returns-error

    EVP_DigestVerify retornou -1 para uma assinatura r‖s bruta e para um blob de 3 bytes.

    Registrado pela verificação
    fact ecdsa-malformed-signature = returns-error
    evidence ecdsa-malformed-signature: EVP_DigestVerify returned -1 for raw r||s and -1 for 3 bytes
  • Saída da verificação em caso de falha

    distinguishable

    dgst -verify imprimiu Error Verifying Data para uma assinatura que não está em DER e Verification Failure para uma assinatura válida sobre outros dados.

    Registrado pela verificação
    fact cli-verify-output = distinguishable
    evidence cli-verify-output: valid: Verified OK; 64 zero bytes: Error Verifying Data; valid signature over other data: Verification Failure
  • Curvas ECDSA

    P-224P-256P-384P-521secp256k1brainpoolP256r1brainpoolP384r1brainpoolP512r1

    Assinatura e verificação funcionaram com P-224, P-256, P-384, P-521, secp256k1 e brainpoolP256r1/P384r1/P512r1.

    Registrado pela verificação
    fact ecdsa-curves = P-224, P-256, P-384, P-521, secp256k1, brainpoolP256r1, brainpoolP384r1, brainpoolP512r1
  • EdDSA

    Ed25519

    Ed25519 por meio de EVP_PKEY_ED25519; EVP_PKEY_ED448 não está definido.

    Registrado pela verificação
    fact eddsa = Ed25519
    evidence eddsa: EVP_PKEY_ED448 is not defined in the headers
  • Algoritmos pós-quânticos

    ML-KEM

    O ciclo completo de ida e volta do ML-KEM-768 e do ML-KEM-1024 funcionou pela API MLKEM_*; genpkey -algorithm ML-DSA-65 falhou com Algorithm ML-DSA-65 not found.

    Registrado pela verificação
    fact pqc = ML-KEM
    evidence pqc: ML-KEM rank 3: public key 1184 bytes, ciphertext 1088 bytes, round trip ok
    evidence pqc: ML-KEM rank 4: public key 1568 bytes, ciphertext 1568 bytes, round trip ok
    evidence pqc: genpkey -algorithm ML-DSA-65: Algorithm ML-DSA-65 not found
    evidence pqc: ML-KEM names in s_client help: none
  • Formatos de chave pública

    spki-pemspki-derx509

    Chaves públicas SPKI em PEM e DER e chaves públicas de certificados verificaram a mesma assinatura.

    Registrado pela verificação
    fact public-key-formats = spki-pem, spki-der, x509
  • Formatos de chave privada

    pkcs8-pempkcs8-derencrypted-pkcs8sec1-pemsec1-der

    A assinatura funcionou com PKCS#8 em PEM e DER, PKCS#8 criptografado e SEC1 em PEM e DER; ecparam -genkey grava SEC1.

    Registrado pela verificação
    fact private-key-formats = pkcs8-pem, pkcs8-der, encrypted-pkcs8, sec1-pem, sec1-der
    evidence private-key-formats: genpkey -algorithm EC: works
    evidence private-key-formats: ecparam -genkey writes -----BEGIN EC PRIVATE KEY-----

Uso

Crie uma chave P-256 com o comando libressl, converta-a para PKCS#8, assine e verifique e mostre que o Ed25519 funciona e o ML-DSA, não.
# Alpine and some distributions install LibreSSL's tool as "libressl", not "openssl".
L=libressl
$L ecparam -name prime256v1 -genkey -noout -out key.pem   # SEC1 "EC PRIVATE KEY"
$L pkcs8 -topk8 -nocrypt -in key.pem -out key.p8.pem       # PKCS#8 for other tools
$L pkey -in key.pem -pubout -out pub.pem

printf 'order #1042 approved' > msg.txt
$L dgst -sha256 -sign key.p8.pem -out sig.der msg.txt
$L dgst -sha256 -verify pub.pem -signature sig.der msg.txt

# Ed25519 works; ML-DSA does not exist in LibreSSL.
$L genpkey -algorithm ED25519 -out ed.pem && echo "Ed25519 key: $(head -1 ed.pem)"
$L genpkey -algorithm ML-DSA-65 2>&1 | grep -i "not found"

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 libressl=4.3.1-r0 >/dev/null
Comando
OPENSSL_CONF=/dev/null sh usage.sh
A saída deve corresponder a (expressão regular)
Verified OK\nEd25519 key: -----BEGIN PRIVATE KEY-----\nAlgorithm ML-DSA-65 not found

Bibliotecas