Zum Inhalt springen
ecdsa.com
Befehlszeile

GnuPG (gpg)

GnuPG 2.4, die OpenPGP-Implementierung hinter gpg: Ed25519-Schlüssel, die standardmäßig nach drei Jahren ablaufen, deterministisches ECDSA nach RFC 6979 auf NIST-, Brainpool- und secp256k1-Kurven, Ed25519-Signaturen über einen Digest und noch keine Post-Quanten-Algorithmen.
Lizenz
GPL-3.0-or-later
Geprüfte Version
2.4.9 ·
Quellcode
dev.gnupg.org/source/gnupg/
Dokumentation
www.gnupg.org/documentation/manuals/gnupg/

Kompatibilität auf einen Blick

ECDSAEdDSA

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

GnuPG implementiert OpenPGP zum Signieren und Verschlüsseln von Dateien und E-Mails, für Paketsignaturen in vielen Linux-Distributionen und zum Signieren von Git-Commits. Die Fakten auf dieser Seite wurden mit dem Paket aus Alpine 3.24.2 geprüft: GnuPG 2.4.9 mit libgcrypt 1.12.2. gpg --quick-gen-key nur mit einer User-ID erzeugt einen Ed25519-Primärschlüssel zum Signieren und Zertifizieren sowie einen Curve25519-Unterschlüssel (cv25519) zur Verschlüsselung, beide als Schlüssel der Version 4, und der Primärschlüssel läuft nach 1095 Tagen – drei Jahren – ab, sofern kein Ablaufdatum angegeben wird. Untersuche Schlüssel und Signaturen mit dem OpenPGP-Inspektor.

ECDSA-Schlüssel lassen sich auf P-256, P-384, P-521, secp256k1 und den drei Brainpool-r1-Kurven erzeugen; nistp224 scheitert mit „Unknown elliptic curve“. Das Signaturpaket enthält r und s als zwei OpenPGP-MPIs, also weder DER noch r‖s mit fester Breite. P-256-Signaturen verwenden standardmäßig SHA-256; wer für einen P-384-Schlüssel SHA-256 anfordert, erhält „signing failed: Invalid length“, während SHA-512 mit einem P-256-Schlüssel akzeptiert wird.

Die Nonces sind deterministisch: Bei eingefrorener Uhr (--faked-system-time) waren zwei Signaturen derselben Datei byteidentisch, und r stimmte mit einer unabhängigen Implementierung von RFC 6979 überein – zweimaliges Signieren derselben Daten verwendet eine Nonce also nicht auf gefährliche Weise wieder. s wird nicht normalisiert, und eine Signatur, in der s durch n − s ersetzt war, wurde als gültig gemeldet – wichtig überall dort, wo Signaturen eindeutig sein sollen.

Ed25519-Signaturen verwenden das ältere EdDSA-Format (Algorithmus 22): R und S sind MPIs, und was Ed25519 signiert, ist der SHA-512-Digest über die Datei und die gehashten Felder der Signatur, nicht die Datei selbst. Links auf jeweils 32 Byte aufgefüllt, bestand R‖S mit OpenSSL die Prüfung gegen diesen Digest, die Prüfung gegen die Datei dagegen nicht – wer gpg-Signaturen mit einer allgemeinen Ed25519-Bibliothek prüfen will, muss zuerst den OpenPGP-Digest berechnen. Ed448-Schlüssel werden als Schlüsselpakete der Version 5 erzeugt, im Format des LibrePGP-Entwurfs, dem GnuPG folgt, während die geprüften Standard-, ECDSA- und Ed25519-Schlüssel alle Version 4 hatten; stelle sicher, dass die Gegenseite Version 5 liest, bevor du Ed448 wählst. Dieses Release hat keinen Post-Quanten-Algorithmus: Die Liste der Algorithmen für öffentliche Schlüssel lautet RSA, ELG, DSA, ECDH, ECDSA und EDDSA, und ky768_cv25519 wird als unbekannte Kurve abgelehnt.

Lies in Skripten die maschinenlesbare Ausgabe von --status-fd statt des Texts: Eine gültige Signatur ergab GOODSIG und VALIDSIG mit Exit-Status 0, eine Signatur über andere Daten BADSIG mit Exit-Status 1 und ein abgeschnittenes Paket NODATA mit Exit-Status 2. gpg --export-ssh-key mit einem Fingerabdruck und ! schreibt für ECDSA- und Ed25519-Schlüssel eine Zeile mit dem öffentlichen Schlüssel im OpenSSH-Format, während --export und --export-secret-keys OpenPGP-Pakete schreiben.

Fakten und die Prüfungen dahinter

Nichts im Folgenden ist aus einer Dokumentation abgeschrieben. Das Prüfskript content/libraries/verify/gnupg/run.sh hat GnuPG (gpg) 2.4.9 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.

  • Standard-Schlüsseltyp

    ed25519cv25519

    --quick-gen-key nur mit einer User-ID erzeugte einen Primärschlüssel ed25519 (Verwendung sc) und einen Unterschlüssel cv25519 (Verwendung e).

    Von der Prüfung aufgezeichnet
    fact default-key-type = ed25519, cv25519
    evidence default-key-type: pub ed25519 (algorithm 22, usage scESC); sub cv25519 (algorithm 18, usage e)
  • Standard-Ablauf von Schlüsseln

    1095d

    Das Ablaufdatum des Primärschlüssels lag 1095 Tage nach seiner Erzeugung.

    Von der Prüfung aufgezeichnet
    fact default-key-expiry = 1095d
    evidence default-key-expiry: expiration minus creation of the primary key: 1095 days
  • Version von OpenPGP-Schlüsseln

    v4

    Der Standardschlüssel wurde als Schlüsselpaket der Version 4 exportiert.

    Von der Prüfung aufgezeichnet
    fact openpgp-key-version = v4
  • Version von Ed448-Schlüsseln

    v5

    Ein Schlüssel ed448 wurde als Schlüsselpaket der Version 5 exportiert, der Standardschlüssel und die Schlüssel vom Typ ECDSA und ed25519 als Version 4.

    Von der Prüfung aufgezeichnet
    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
  • ECDSA-Kurven

    P-256P-384P-521secp256k1brainpoolP256r1brainpoolP384r1brainpoolP512r1

    Mit allen sieben Kurven ließen sich Schlüssel erzeugen, mit denen Signieren und Prüfen funktionierten; nistp224 ergab „Unknown elliptic curve“.

    Von der Prüfung aufgezeichnet
    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

    Signieren und Prüfen funktionierten mit Schlüsseln vom Typ ed25519 und ed448.

    Von der Prüfung aufgezeichnet
    fact eddsa = Ed25519, Ed448
  • Post-Quanten-Algorithmen

    none

    Die Zeile Pubkey: von gpg --version nennt keinen Post-Quanten-Algorithmus, und das Erzeugen eines Schlüssels ky768_cv25519 schlug fehl.

    Von der Prüfung aufgezeichnet
    fact pqc = none
    evidence pqc: --quick-gen-key with ky768_cv25519: gpg: Key generation failed: Unknown elliptic curve
  • Kodierung von ECDSA-Signaturen

    openpgp-mpi

    Das P-256-Signaturpaket (Algorithmus 19) endet mit zwei MPIs, r und s.

    Von der Prüfung aufgezeichnet
    fact ecdsa-signature-encoding = openpgp-mpi
    evidence ecdsa-signature-encoding: P-256 detached signature: version=4 pubkey-algo=19 hash-algo=8 mpis=2
  • Standard-Hash

    sha256

    Die standardmäßige P-256-Signatur nennt den Hash-Algorithmus 8, SHA-256.

    Von der Prüfung aufgezeichnet
    fact ecdsa-default-hash = sha256
  • ECDSA-Nonce

    rfc6979

    Zwei Signaturen bei eingefrorener Uhr waren identisch, und r stimmte mit dem Referenz-Signierer für RFC 6979 überein.

    Von der Prüfung aufgezeichnet
    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 beim Signieren

    either

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

    Von der Prüfung aufgezeichnet
    fact ecdsa-low-s-sign = either
    evidence ecdsa-low-s-sign: signatures with s > n/2 among 32: yes
  • High-S bei der Prüfung

    accepts-high-s

    Eine Signatur, in der s durch n − s ersetzt war, bestand die Prüfung mit GOODSIG und Exit-Status 0.

    Von der Prüfung aufgezeichnet
    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
  • An die Kurve gebundener Hash

    enforced

    --digest-algo SHA256 mit einem P-384-Schlüssel scheiterte mit „Invalid length“; SHA-512 mit einem P-256-Schlüssel funktionierte.

    Von der Prüfung aufgezeichnet
    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
  • Ausgabe bei fehlgeschlagener Prüfung

    distinguishable

    BADSIG und Exit-Status 1 bei einer falschen Nachricht; NODATA und Exit-Status 2 bei einem abgeschnittenen Paket.

    Von der Prüfung aufgezeichnet
    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
  • Was die Ed25519-Signatur abdeckt

    digest

    R‖S bestand mit openssl pkeyutl die Prüfung über den Digest der OpenPGP-Signatur, die Prüfung über die Datei dagegen nicht.

    Von der Prüfung aufgezeichnet
    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
  • Formate öffentlicher Schlüssel

    opensshopenpgp

    gpg --export schreibt OpenPGP-Pakete; --export-ssh-key schrieb Zeilen mit ecdsa-sha2-nistp256 und ssh-ed25519.

    Von der Prüfung aufgezeichnet
    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
  • Formate privater Schlüssel

    openpgp

    gpg --export-secret-keys schreibt OpenPGP-Pakete mit geheimen Schlüsseln.

    Von der Prüfung aufgezeichnet
    fact private-key-formats = openpgp
    evidence private-key-formats: gpg --export-secret-keys: secret key packet

Verwendung

Erzeuge einen Standardschlüssel, erstelle eine abgetrennte Signatur mit ASCII-Armor und prüfe sie über die Statusausgabe.
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

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 gnupg=2.4.9-r1 >/dev/null
Befehl
sh sign.sh
Ausgabe muss passen (regulärer Ausdruck)
GOODSIG\nVALIDSIG

Bibliotheken