Zum Inhalt springen
ecdsa.com
C · Befehlszeile

GnuTLS

GnuTLS, die TLS- und X.509-Bibliothek des GNU-Projekts: ECDSA mit DER auf den NIST-Kurven, RFC 6979 über ein Flag, Ed25519 und Ed448 – und im geprüften Distributions-Build kein secp256k1 und keine funktionierenden Post-Quanten-Algorithmen.
Lizenz
LGPL-2.1-or-later
Geprüfte Version
3.8.13 ·
Quellcode
gitlab.com/gnutls/gnutls
Dokumentation
www.gnutls.org/manual/

Kompatibilität auf einen Blick

ECDSAEdDSA

ECDSA-Kurven
P-224P-256P-384P-521
EdDSA
Ed25519Ed448

GnuTLS übernimmt TLS, X.509 und PKCS für viele GNU- und Linux-Komponenten und liefert certtool und gnutls-cli mit. Seine abstrakten Schnittstellen gnutls_privkey_* und gnutls_pubkey_* funktionieren für Software-Schlüssel, PKCS#11-Tokens und TPMs gleich. Die Fakten auf dieser Seite wurden mit dem Paket aus Alpine 3.24.2 geprüft: GnuTLS 3.8.13, das für die Arithmetik Nettle verwendet. Seit GnuTLS 3.8.10 kommen Post-Quanten-Algorithmen nur aus der optionalen Bibliothek leancrypto, und dieses Paket bindet sie nicht ein.

gnutls_privkey_sign_data liefert ECDSA-Signaturen als DER mit zufälliger Nonce; das Flag GNUTLS_PRIVKEY_FLAG_REPRODUCIBLE schaltet auf RFC 6979 um, und damit wurde der P-256-Testvektor des RFC exakt reproduziert. s wird nicht normalisiert, und High-S-Signaturen bestehen die Prüfung. gnutls_privkey_sign_hash2 signiert einen Digest, den du selbst berechnet hast.

Die Prüfung liefert bei einem Fehlschlag einen negativen Fehlercode, und jede Art von Fehlschlag sah gleich aus: Eine rohe r‖s-Signatur, ein 3-Byte-Blob und eine gültige Signatur über andere Daten ergaben alle GNUTLS_E_PK_SIG_VERIFY_FAILED (-89). Schließe mit dem Konverter DER ⇄ Raw ein Kodierungsproblem aus.

ECDSA ist auf die NIST-Kurven P-224 bis P-521 beschränkt – gnutls_ecc_curve_get_id("SECP256K1") gab 0 zurück, also unbekannt –, während Signieren und Prüfen mit Ed25519 und Ed448 funktionierten. Die Header deklarieren GNUTLS_PK_MLKEM768 und GNUTLS_PK_MLDSA65, doch dieser Build implementiert keines von beiden: Beide fehlen in gnutls_pk_list(), das Erzeugen eines ML-DSA-65-Schlüssels scheitert mit GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM, und die TLS-Gruppen, die gnutls-cli --list auflistet, enthalten X25519 und X448, aber keine hybride Gruppe mit ML-KEM. Code, der gegen diese Konstanten kompiliert, kann zur Laufzeit trotzdem scheitern; prüfe daher die Liste, die die Bibliothek zur Laufzeit liefert. Untersuche Zertifikate, die certtool erzeugt, mit dem Zertifikats-Decoder.

Fakten und die Prüfungen dahinter

Nichts im Folgenden ist aus einer Dokumentation abgeschrieben. Das Prüfskript content/libraries/verify/gnutls/run.sh hat GnuTLS 3.8.13 am 20. Oktober 2026 im Container-Image alpine:3.24.2 ausgeführt; die Seite muss mit seiner Ausgabe übereinstimmen, und jeder Fakt führt die zugehörigen Zeilen auf.

  • Kodierung von ECDSA-Signaturen

    der

    gnutls_privkey_sign_data liefert ASN.1-DER.

    Von der Prüfung aufgezeichnet
    fact ecdsa-signature-encoding = der
  • ECDSA-Nonce

    rfc6979-opt-in

    Standardmäßig zufällig; GNUTLS_PRIVKEY_FLAG_REPRODUCIBLE lieferte identische Signaturen und reproduzierte RFC 6979, Anhang A.2.5.

    Von der Prüfung aufgezeichnet
    fact ecdsa-nonce = rfc6979-opt-in
    evidence ecdsa-nonce: default repeats: no; GNUTLS_PRIVKEY_FLAG_REPRODUCIBLE repeats: yes and reproduces the RFC 6979 A.2.5 r: yes
  • Low-S beim Signieren

    either

    s wird nicht normalisiert: Unter 64 Signaturen traten High-S-Werte auf.

    Von der Prüfung aufgezeichnet
    fact ecdsa-low-s-sign = either
  • High-S bei der Prüfung

    accepts-high-s

    Eine DER-Signatur, in der s durch n − s ersetzt war, bestand die Prüfung.

    Von der Prüfung aufgezeichnet
    fact ecdsa-low-s-verify = accepts-high-s
  • Was der Signaturaufruf hasht

    hashes-message-or-digest

    gnutls_privkey_sign_data hasht; gnutls_privkey_sign_hash2 signiert einen Digest, und diese Signatur bestand die Prüfung gegen die Nachricht.

    Von der Prüfung aufgezeichnet
    fact ecdsa-prehash = hashes-message-or-digest
  • Fehlerhafte ECDSA-Signatur

    returns-false

    Eine rohe r‖s-Signatur, ein 3-Byte-Blob und eine gültige Signatur über andere Daten ergaben alle GNUTLS_E_PK_SIG_VERIFY_FAILED (-89).

    Von der Prüfung aufgezeichnet
    fact ecdsa-malformed-signature = returns-false
    evidence ecdsa-malformed-signature: gnutls_pubkey_verify_data2: raw r||s -89 (GNUTLS_E_PK_SIG_VERIFY_FAILED), 3 bytes -89 (GNUTLS_E_PK_SIG_VERIFY_FAILED), wrong message -89 (GNUTLS_E_PK_SIG_VERIFY_FAILED)
  • ECDSA-Kurven

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

    P-224, P-256, P-384 und P-521; SECP256K1 ist keine bekannte Kurve.

    Von der Prüfung aufgezeichnet
    fact ecdsa-curves = P-224, P-256, P-384, P-521
    evidence ecdsa-curves: gnutls_ecc_curve_get_id("SECP256K1") = 0 (0 = unknown)
  • EdDSA

    Ed25519Ed448

    Erzeugen, Signieren und Prüfen funktionierten mit Ed25519- und Ed448-Schlüsseln.

    Von der Prüfung aufgezeichnet
    fact eddsa = Ed25519, Ed448
    evidence eddsa: Ed25519: keygen GNUTLS_E_SUCCESS, sign ok, verify ok
    evidence eddsa: Ed448: keygen GNUTLS_E_SUCCESS, sign ok, verify ok
  • Post-Quanten-Algorithmen

    none

    ML-DSA und ML-KEM sind in den Headern deklariert, fehlen aber in gnutls_pk_list(); das Erzeugen eines ML-DSA-65-Schlüssels schlug fehl, und X25519-MLKEM768 ist eine unbekannte Gruppe.

    Von der Prüfung aufgezeichnet
    fact pqc = none
    evidence pqc: the headers declare GNUTLS_PK_MLKEM768 = 14 and GNUTLS_PK_MLDSA65 = 16; gnutls_pk_list(): RSA, RSA-PSS, RSA-OAEP, RSA, DSA, GOST R 34.10-2012-512, GOST R 34.10-2012-256, GOST R 34.10-2001, EC/ECDSA, EdDSA (Ed25519), EdDSA (Ed448), DH, ECDH (X25519), ECDH (X448)
    evidence pqc: ML-DSA-65: in gnutls_pk_list: no; key generation GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM, sign and verify failed
    evidence pqc: ML-KEM-768: in gnutls_pk_list: no; gnutls_group_get_id("X25519-MLKEM768") = 0 (0 = unknown)
    evidence pqc: gnutls-cli --list Groups: GROUP-SECP192R1, GROUP-SECP224R1, GROUP-SECP256R1, GROUP-SECP384R1, GROUP-SECP521R1, GROUP-X25519, GROUP-GC256B, GROUP-GC512A, GROUP-X448, GROUP-FFDHE2048, GROUP-FFDHE3072, GROUP-FFDHE4096, GROUP-FFDHE6144, GROUP-FFDHE8192
    evidence pqc: shared libraries the gnutls package depends on: libbrotlidec.so.1 libbrotlienc.so.1 libc.musl-aarch64.so.1 libgmp.so.10 libhogweed.so.6 libidn2.so.0 libnettle.so.8 libp11-kit.so.0 libtasn1.so.6 libunistring.so.5 libz.so.1 libzstd.so.1 (GnuTLS 3.8.10 NEWS: PQC is only provided through leancrypto)

Verwendung

Erzeuge einen P-256-Schlüssel, signiere zweimal mit dem Flag für reproduzierbare Signaturen, prüfe sie und stelle sicher, dass beide Signaturen identisch sind.
#include <gnutls/abstract.h>
#include <gnutls/gnutls.h>
#include <stdio.h>
#include <string.h>

int main(void) {
    gnutls_global_init();
    gnutls_privkey_t priv;
    gnutls_pubkey_t pub;
    gnutls_privkey_init(&priv);
    gnutls_privkey_generate(priv, GNUTLS_PK_ECDSA, GNUTLS_CURVE_TO_BITS(GNUTLS_ECC_CURVE_SECP256R1), 0);
    gnutls_pubkey_init(&pub);
    gnutls_pubkey_import_privkey(pub, priv, 0, 0);

    gnutls_datum_t msg = {(unsigned char *)"order #1042 approved", 20}, sig1, sig2;
    /* REPRODUCIBLE switches ECDSA to RFC 6979 nonces; the default is random. */
    gnutls_privkey_sign_data(priv, GNUTLS_DIG_SHA256, GNUTLS_PRIVKEY_FLAG_REPRODUCIBLE, &msg, &sig1);
    gnutls_privkey_sign_data(priv, GNUTLS_DIG_SHA256, GNUTLS_PRIVKEY_FLAG_REPRODUCIBLE, &msg, &sig2);

    /* Negative return codes mean failure; any malformed input is GNUTLS_E_PK_SIG_VERIFY_FAILED. */
    int rc = gnutls_pubkey_verify_data2(pub, GNUTLS_SIGN_ECDSA_SHA256, 0, &msg, &sig1);
    printf("verified: %d, deterministic: %d\n", rc >= 0, sig1.size == sig2.size && memcmp(sig1.data, sig2.data, sig1.size) == 0);
    gnutls_global_deinit();
    return 0;
}

Die Snippet-Testumgebung führt jedes Beispiel unverändert im Container-Image alpine:3.24.2 aus, und der Lauf schlägt fehl, wenn die Ausgabe nicht übereinstimmt.

Einrichtung
apk add --no-cache -q build-base gnutls-dev=3.8.13-r0 >/dev/null
Befehl
cc -o usage usage.c -lgnutls && ./usage
Ausgabe muss passen (regulärer Ausdruck)
verified: 1, deterministic: 1

Bibliotheken