Zum Inhalt springen
ecdsa.com
Go crypto/x509Go

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

So behebst du den Fehler

  1. 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. 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

Gesamte Signaturfehler-Datenbank durchsuchen