Fehlermeldung
x509: failed to parse private key (use ParsePKCS1PrivateKey instead for this key format)
Auch ausgegeben als
- x509: failed to parse private key (use ParseECPrivateKey instead for this key format)
- x509: failed to parse private key (use ParsePKCS8PrivateKey instead for this key format)
- x509: failed to parse public key (use ParsePKCS1PublicKey instead for this key format)
Die Funktion in Klammern hängt davon ab, was Go erkannt hat: `ParsePKCS1PrivateKey`, `ParseECPrivateKey` oder `ParsePKCS8PrivateKey`. Das Gegenstück für öffentliche Schlüssel lautet „x509: failed to parse public key (use ParsePKCS1PublicKey instead for this key format)“. Bytes, die zu keinem der Formate passen, ergeben stattdessen einen `asn1: structure error`.
Go crypto/x509 — ParsePKCS8PrivateKey / ParsePKCS1PrivateKey / ParseECPrivateKey / ParsePKIXPublicKey
Was der Fehler bedeutet
Du hast die DER-Bytes eines Containers für private Schlüssel an den Parser für einen anderen Container übergeben, und Go hat erkannt, um welchen Container es sich tatsächlich handelt. Es gibt drei verbreitete Kodierungen: PKCS#8 (`-----BEGIN PRIVATE KEY-----`, jeder Algorithmus), PKCS#1 (`-----BEGIN RSA PRIVATE KEY-----`, nur RSA) und SEC 1 (`-----BEGIN EC PRIVATE KEY-----`, nur EC). Der Hinweis in Klammern nennt die Funktion, die deine Bytes parsen kann. Der Schlüssel selbst ist in Ordnung.
Warum der Fehler auftritt
RSA-Schlüssel in PKCS#1, der Code erwartet PKCS#8
häufig`openssl genrsa` (OpenSSL 1.x) und viele ältere Tools schreiben `RSA PRIVATE KEY`; Code, der für die Ausgabe von `openssl genpkey` geschrieben wurde, ruft `ParsePKCS8PrivateKey` auf. Mit neueren Tools passiert auch das Umgekehrte.
EC-Schlüssel im Format SEC 1
häufig`openssl ecparam -genkey` schreibt `EC PRIVATE KEY` (SEC 1, RFC 5915). Der Schlüssel muss an `ParseECPrivateKey` gehen oder nach PKCS#8 konvertiert werden.
Öffentlicher RSA-Schlüssel in PKCS#1 an ParsePKIXPublicKey übergeben
gelegentlich`-----BEGIN RSA PUBLIC KEY-----` ist die nackte PKCS#1-Struktur ohne die Algorithmuskennung, die `PUBLIC KEY` (SPKI) mitführt.
So behebst du den Fehler
- 1.
Parser anhand des PEM-Typs wählen
Das PEM-Label verrät dir den Container. Verzweige anhand von `block.Type`, statt ein einziges Format anzunehmen.
go func parsePrivateKeyPEM(data []byte) (crypto.Signer, error) { block, _ := pem.Decode(data) if block == nil { return nil, errors.New("no PEM block found") } switch block.Type { case "PRIVATE KEY": // PKCS#8: RSA, ECDSA, Ed25519, X25519 key, err := x509.ParsePKCS8PrivateKey(block.Bytes) if err != nil { return nil, err } signer, ok := key.(crypto.Signer) if !ok { return nil, fmt.Errorf("%T cannot sign", key) } return signer, nil case "RSA PRIVATE KEY": // PKCS#1 return x509.ParsePKCS1PrivateKey(block.Bytes) case "EC PRIVATE KEY": // SEC 1 return x509.ParseECPrivateKey(block.Bytes) default: return nil, fmt.Errorf("unsupported PEM type %q", block.Type) } } - 2.
Schlüssel auf PKCS#8 und SPKI vereinheitlichen
PKCS#8 für private Schlüssel und SPKI für öffentliche Schlüssel funktionieren mit jedem Algorithmus und jeder modernen Bibliothek. Konvertiere einmal bei der Bereitstellung.
bash # Normalise any private key to PKCS#8 ("-----BEGIN PRIVATE KEY-----") openssl pkcs8 -topk8 -nocrypt -in legacy.pem -out key.pk8.pem # Public keys: PKCS#1 "RSA PUBLIC KEY" -> SPKI "PUBLIC KEY" openssl rsa -RSAPublicKey_in -in rsa-pub.pem -pubout -out spki.pem
Verwandte Fehler
asn1: structure error: tags don't matchGo encoding/asn1algid parse error, not a sequenceJava (JDK)System.Security.Cryptography.CryptographicException: ASN1 corrupted data..NET System.Security.Cryptographytoken signature is invalid: key is of invalid type: ECDSA verify expects *ecdsa…golang-jwt/jwt (Go)