Message d’erreur
algid parse error, not a sequence
Également affiché sous la forme
- 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
Sur les JDK 8 à 11, le texte de l’exception lui-même est « InvalidKeyException: IOException : algid parse error, not a sequence ». Les JDK plus récents (vérifié sur 21 et 25) indiquent « Unable to decode key » et conservent « algid parse error, not a sequence » dans la ligne `Caused by:` de la pile d’appels.
Java (JDK) — KeyFactory.generatePrivate / generatePublic with PKCS8EncodedKeySpec or X509EncodedKeySpec
Ce que cela signifie
Les octets que vous avez placés dans un `PKCS8EncodedKeySpec` ou un `X509EncodedKeySpec` ne commencent pas par la structure promise par cette spec : les deux formats commencent par une SEQUENCE contenant un AlgorithmIdentifier (« algid »), et le JDK a trouvé autre chose à cet endroit. Le cas classique est une clé RSA PKCS#1 (`-----BEGIN RSA PRIVATE KEY-----`), dont le premier élément est un INTEGER. Le JDK ne lit que PKCS#8 pour les clés privées et X.509 SubjectPublicKeyInfo pour les clés publiques.
Pourquoi cela se produit
Une clé PKCS#1 (« BEGIN RSA PRIVATE KEY »)
fréquente`genrsa` d’OpenSSL 1.x, de nombreux panneaux d’hébergement et des outils plus anciens écrivent du PKCS#1. Son DER est la séquence RSAPrivateKey sans l’identifiant d’algorithme qu’ajoute PKCS#8 : le JDK ne trouve donc pas l’algid.
Specs publique et privée interverties
fréquenteUne clé privée passée à `X509EncodedKeySpec`, ou une clé publique passée à `PKCS8EncodedKeySpec`. Les structures diffèrent juste après la SEQUENCE externe.
Pas les octets DER de la clé
occasionnelleTexte PEM passé sous forme d’octets, base64 décodé deux fois, ou clé d’un magasin de clés exportée dans un autre format. Ces cas échouent généralement avec un autre `Caused by` (« extra data at the end », « DerInputStream.getLength() »), mais le message algid apparaît quand les premiers octets se trouvent être analysables.
Un certificat au lieu d’une clé
occasionnelleLe contenu d’un bloc `-----BEGIN CERTIFICATE-----` est un certificat X.509, pas un SubjectPublicKeyInfo. Chargez-le avec `CertificateFactory` et appelez `getPublicKey()`.
Comment corriger l’erreur
- 1.
Convertir la clé en PKCS#8 / SPKI une fois pour toutes
Une seule commande OpenSSL convertit les clés PKCS#1 aux formats que le JDK lit nativement.
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.
Retirer l’armure et vérifier l’étiquette
Ne décodez que le corps base64, et rejetez les étiquettes PEM que le JDK ne sait pas lire avec un message clair plutôt qu’avec une erreur d’analyse.
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.
Ou lire toutes les variantes de PEM avec Bouncy Castle
`PEMParser` comprend PKCS#1, PKCS#8, SEC 1 et le PEM chiffré, et `JcaPEMKeyConverter` transforme le résultat en clés JCA.
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); }
Erreurs associées
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