Fehlermeldung
algid parse error, not a sequence
Auch ausgegeben als
- java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : algid parse error, not a sequence
- java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: Unable to decode key
Unter JDK 8–11 lautet der Text der Exception selbst „InvalidKeyException: IOException : algid parse error, not a sequence“. Neuere JDKs (geprüft mit 21 und 25) melden „Unable to decode key“ und behalten „algid parse error, not a sequence“ in der Zeile `Caused by:` des Stacktraces.
Java (JDK) — KeyFactory.generatePrivate / generatePublic with PKCS8EncodedKeySpec or X509EncodedKeySpec
Was der Fehler bedeutet
Die Bytes, die du in eine `PKCS8EncodedKeySpec` oder `X509EncodedKeySpec` verpackt hast, beginnen nicht mit der Struktur, die diese Spec verspricht: Beide Formate beginnen mit einer SEQUENCE, die einen AlgorithmIdentifier („algid“) enthält, und das JDK hat dort etwas anderes gefunden. Der klassische Fall ist ein PKCS#1-RSA-Schlüssel (`-----BEGIN RSA PRIVATE KEY-----`), dessen erstes Element ein INTEGER ist. Das JDK liest private Schlüssel nur als PKCS#8 und öffentliche Schlüssel nur als X.509-SubjectPublicKeyInfo.
Warum der Fehler auftritt
Ein PKCS#1-Schlüssel („BEGIN RSA PRIVATE KEY“)
häufig`genrsa` aus OpenSSL 1.x, viele Hosting-Panels und ältere Tools schreiben PKCS#1. Die DER-Kodierung eines solchen Schlüssels ist die Sequenz RSAPrivateKey ohne den Algorithmusbezeichner, den PKCS#8 ergänzt, deshalb findet das JDK den algid nicht.
Öffentliche und private Spec vertauscht
häufigEin privater Schlüssel wurde an `X509EncodedKeySpec` übergeben oder ein öffentlicher Schlüssel an `PKCS8EncodedKeySpec`. Die Strukturen unterscheiden sich direkt nach der äußeren SEQUENCE.
Nicht die DER-Bytes des Schlüssels
gelegentlichPEM-Text, der als Bytes übergeben wurde, doppelt base64-dekodierte Daten oder ein Schlüssel aus einem Keystore, der in einem anderen Format exportiert wurde. Diese Fälle scheitern meist mit einem anderen `Caused by` („extra data at the end“, „DerInputStream.getLength()“), aber die algid-Meldung erscheint, wenn sich die ersten Bytes zufällig parsen lassen.
Ein Zertifikat statt eines Schlüssels
gelegentlichDer Inhalt von `-----BEGIN CERTIFICATE-----` ist ein X.509-Zertifikat, keine SubjectPublicKeyInfo. Lade das Zertifikat mit `CertificateFactory` und rufe `getPublicKey()` auf.
So behebst du den Fehler
- 1.
Schlüssel einmalig nach PKCS#8 / SPKI konvertieren
Ein einziger OpenSSL-Befehl wandelt PKCS#1-Schlüssel in die Formate um, die das JDK nativ liest.
bash # "-----BEGIN RSA PRIVATE KEY-----" (PKCS#1) -> "-----BEGIN PRIVATE KEY-----" (PKCS#8) openssl pkcs8 -topk8 -nocrypt -in rsa-pkcs1.pem -out private-pkcs8.pem # "-----BEGIN RSA PUBLIC KEY-----" -> "-----BEGIN PUBLIC KEY-----" (X.509 SubjectPublicKeyInfo) openssl rsa -RSAPublicKey_in -in rsa-public-pkcs1.pem -pubout -out public.pem - 2.
Rahmenzeilen entfernen und Label prüfen
Dekodiere nur den base64-Inhalt und lehne PEM-Labels, die das JDK nicht lesen kann, mit einer klaren Meldung ab statt mit einem Parse-Fehler.
java import java.nio.file.*; import java.security.*; import java.security.spec.*; import java.util.Base64; static PrivateKey loadPkcs8(Path path, String algorithm) throws Exception { String pem = Files.readString(path); if (!pem.contains("-----BEGIN PRIVATE KEY-----")) { throw new IllegalArgumentException("expected a PKCS#8 'BEGIN PRIVATE KEY' file"); } String body = pem.replaceAll("-----[A-Z ]+-----", "").replaceAll("\\s", ""); return KeyFactory.getInstance(algorithm).generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode(body))); } static PublicKey loadSpki(Path path, String algorithm) throws Exception { String body = Files.readString(path).replaceAll("-----[A-Z ]+-----", "").replaceAll("\\s", ""); return KeyFactory.getInstance(algorithm).generatePublic(new X509EncodedKeySpec(Base64.getDecoder().decode(body))); } - 3.
Oder jede PEM-Variante mit Bouncy Castle lesen
`PEMParser` versteht PKCS#1, PKCS#8, SEC 1 und verschlüsseltes PEM, und `JcaPEMKeyConverter` macht aus dem Ergebnis JCA-Schlüssel.
java // With Bouncy Castle (bcpkix): reads PKCS#1, PKCS#8, SEC 1 and encrypted keys try (var parser = new org.bouncycastle.openssl.PEMParser(Files.newBufferedReader(path))) { Object object = parser.readObject(); var converter = new org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter(); PrivateKey key = object instanceof org.bouncycastle.openssl.PEMKeyPair pair ? converter.getKeyPair(pair).getPrivate() : converter.getPrivateKey((org.bouncycastle.asn1.pkcs.PrivateKeyInfo) object); }
Verwandte Fehler
x509: failed to parse private key (use ParsePKCS1PrivateKey instead for this ke…Go crypto/x509java.lang.IllegalArgumentException: Illegal base64 character 2dJava (JDK)System.Security.Cryptography.CryptographicException: ASN1 corrupted data..NET System.Security.CryptographyCould not deserialize key data. The data may be in an incorrect format, it may…Python cryptography