本文へスキップ
ecdsa.com
C · コマンドライン

LibreSSL

OpenBSD の LibreSSL は、2014年に OpenSSL からフォークされたライブラリで、OpenBSD と macOS のシステムツールで使われています。ECDSA の DER 形式と鍵の形式は OpenSSL と同じで、Ed25519 はありますが Ed448 はなく、ML-KEM は独自の API で提供され、ML-DSA と RFC 6979 には対応していません。
ライセンス
OpenSSL AND ISC
確認したバージョン
4.3.1 ·
ソースコード
github.com/libressl/portable
ドキュメント
man.openbsd.org/

互換性の概要

ECDSAEdDSAポスト量子暗号

ECDSA の曲線
P-224P-256P-384P-521secp256k1brainpoolP256r1brainpoolP384r1brainpoolP512r1
EdDSA
Ed25519
公開鍵の形式
spki-pemspki-derx509
秘密鍵の形式
pkcs8-pempkcs8-derencrypted-pkcs8sec1-pemsec1-der

LibreSSL は、レガシーなコードを削除しつつ、OpenSSL でおなじみの libcrypto/libssl の API とコマンドラインを維持し、独自の libtls を追加しています。macOS はシステムの暗号ライブラリとして古い LibreSSL を同梱しており、macOS 27.0.1 では /usr/bin/openssl version が LibreSSL 3.3.6 と出力し、ssh -V も同じライブラリ名を表示しました。ここに挙げる事実は、Alpine 3.24.2 のパッケージである LibreSSL 4.3.1(アップストリームは 4.3.3 に達していました)で確認したものです。このパッケージではコマンドが libressl としてインストールされるため、互換パッケージを追加しない限り、openssl を呼び出すスクリプトは失敗します。

ECDSA は OpenSSL のデフォルトと同じように動作します。署名は DER、nonce はランダム、low-S 正規化はなく、検証は high-S も受け入れます。OpenSSL 3.2 以降と異なり、RFC 6979 による決定的署名のオプションはありません。EVP_DigestVerify は生の r‖s 署名に -1 を返し、コマンドラインはその署名に対して Error Verifying Data を、別のデータに対する有効な署名に対して Verification Failure を出力しました。大文字と小文字の使い方が OpenSSL のメッセージと異なる点に注意してください。正確な文字列を grep するスクリプトは、この違いで動かなくなります。

曲線は P-224 から P-521 まで、secp256k1、Brainpool の r1 曲線に対応しています。Ed25519 は EVP_PKEY_ED25519 で動作し、Ed448 はまったくありません。鍵ファイルは OpenSSL と相互運用でき、公開鍵は SPKI と証明書、秘密鍵は PKCS#8(暗号化なし・暗号化あり)と SEC1 に対応します。ecparam -genkey は SEC1 の EC PRIVATE KEY を書き出すため、ほかのツールが PKCS#8 を求める場合は、サンプルのように pkcs8 -topk8 で変換してください。

ポスト量子暗号への対応は部分的です。ML-KEM-768 と ML-KEM-1024 は、EVP やコマンドラインではなく、<openssl/mlkem.h> にある LibreSSL 独自の MLKEM_* 関数で利用でき、ML-DSA は存在しません(Algorithm ML-DSA-65 not found)。アルゴリズムはポスト量子 KEM ラボで比較してください。ML-DSA で署名するには、OpenSSL 3.5 以降を使ってください。

事実とその根拠となるチェック

以下の内容はドキュメントからの転記ではありません。2026年10月20日に、チェック content/libraries/verify/libressl/run.sh がコンテナイメージ alpine:3.24.2 内で LibreSSL 4.3.1 を実行しました。このページの内容はその出力と一致していなければならず、各事実には該当する出力行を示しています。

  • ECDSA 署名のエンコーディング

    der

    EVP_DigestSign と libressl dgst -sign は ASN.1 DER を生成します。

    チェックによる記録
    fact ecdsa-signature-encoding = der
  • ECDSA の nonce

    random

    nonce はランダムです。同じメッセージの 2 つの署名は異なり、決定的 nonce のオプションはありません。

    チェックによる記録
    fact ecdsa-nonce = random
  • 署名時の low-S

    either

    s は正規化されません。64 個の署名の中に high-S の値が現れました。

    チェックによる記録
    fact ecdsa-low-s-sign = either
  • 検証時の high-S

    accepts-high-s

    s を n − s に置き換えた DER 署名も検証を通りました。

    チェックによる記録
    fact ecdsa-low-s-verify = accepts-high-s
  • 署名呼び出しがハッシュする対象

    hashes-message-or-digest

    EVP_DigestSign はハッシュを計算します。ECDSA_sign はダイジェストに署名し、その署名はメッセージに対して検証できました。

    チェックによる記録
    fact ecdsa-prehash = hashes-message-or-digest
  • 不正な形式の ECDSA 署名

    returns-error

    EVP_DigestVerify は、生の r‖s 署名と 3 バイトのデータに対して -1 を返しました。

    チェックによる記録
    fact ecdsa-malformed-signature = returns-error
    evidence ecdsa-malformed-signature: EVP_DigestVerify returned -1 for raw r||s and -1 for 3 bytes
  • 検証失敗時の出力

    distinguishable

    dgst -verify は、DER でない署名に対して Error Verifying Data を、別のデータに対する有効な署名に対して Verification Failure を出力しました。

    チェックによる記録
    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
  • ECDSA の曲線

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

    P-224、P-256、P-384、P-521、secp256k1、brainpoolP256r1/P384r1/P512r1 で署名と検証ができました。

    チェックによる記録
    fact ecdsa-curves = P-224, P-256, P-384, P-521, secp256k1, brainpoolP256r1, brainpoolP384r1, brainpoolP512r1
  • EdDSA

    Ed25519

    EVP_PKEY_ED25519 による Ed25519 です。EVP_PKEY_ED448 は定義されていません。

    チェックによる記録
    fact eddsa = Ed25519
    evidence eddsa: EVP_PKEY_ED448 is not defined in the headers
  • ポスト量子アルゴリズム

    ML-KEM

    ML-KEM-768 と ML-KEM-1024 は、MLKEM_* API でカプセル化とデカプセル化が一通り動作しました。genpkey -algorithm ML-DSA-65 は Algorithm ML-DSA-65 not found で失敗しました。

    チェックによる記録
    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
  • 公開鍵の形式

    spki-pemspki-derx509

    SPKI の PEM と DER、証明書の公開鍵のいずれでも、同じ署名を検証できました。

    チェックによる記録
    fact public-key-formats = spki-pem, spki-der, x509
  • 秘密鍵の形式

    pkcs8-pempkcs8-derencrypted-pkcs8sec1-pemsec1-der

    PKCS#8 の PEM と DER、暗号化された PKCS#8、SEC1 の PEM と DER のいずれでも署名できました。ecparam -genkey は SEC1 を書き出します。

    チェックによる記録
    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-----

使い方

libressl コマンドで P-256 の鍵を作成して PKCS#8 に変換し、署名と検証を行って、Ed25519 は動作し ML-DSA は動作しないことを示します。
# 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"

スニペットのテストハーネスは、すべてのサンプルをコンテナイメージ alpine:3.24.2 内でそのまま実行し、出力が一致しなければ実行は失敗します。

セットアップ
apk add --no-cache -q libressl=4.3.1-r0 >/dev/null
コマンド
OPENSSL_CONF=/dev/null sh usage.sh
一致すべき出力(正規表現)
Verified OK\nEd25519 key: -----BEGIN PRIVATE KEY-----\nAlgorithm ML-DSA-65 not found

ライブラリ