spring-projects/spring-security · error · IllegalArgumentException
Invalid RSA Private Key ASN1 sequence.
Error message
Invalid RSA Private Key ASN1 sequence.
What it means
After base64-decoding PEM content, parseKeyPair() parses the DER bytes as an ASN1Sequence and requires exactly 9 elements for a PKCS#1 RSAPrivateKey structure. This error means the decoded ASN.1 sequence has the wrong number of fields, so the data is not a valid RSA PRIVATE KEY (PKCS#1) structure.
Source
Thrown at crypto/src/main/java/org/springframework/security/crypto/encrypt/RsaKeyHelper.java:98
catch (Exception ex) {
// Ignore
}
throw new IllegalArgumentException("String is not PEM encoded data, nor a public key encoded for ssh");
}
String type = m.group(1);
final byte[] content = base64Decode(m.group(2));
PublicKey publicKey;
PrivateKey privateKey = null;
try {
KeyFactory fact = KeyFactory.getInstance("RSA");
switch (type) {
case "RSA PRIVATE KEY" -> {
ASN1Sequence seq = ASN1Sequence.getInstance(content);
if (seq.size() != 9) {
throw new IllegalArgumentException("Invalid RSA Private Key ASN1 sequence.");
}
org.bouncycastle.asn1.pkcs.RSAPrivateKey key = org.bouncycastle.asn1.pkcs.RSAPrivateKey
.getInstance(seq);
RSAPublicKeySpec pubSpec = new RSAPublicKeySpec(key.getModulus(), key.getPublicExponent());
RSAPrivateCrtKeySpec privSpec = new RSAPrivateCrtKeySpec(key.getModulus(), key.getPublicExponent(),
key.getPrivateExponent(), key.getPrime1(), key.getPrime2(), key.getExponent1(),
key.getExponent2(), key.getCoefficient());
publicKey = fact.generatePublic(pubSpec);
privateKey = fact.generatePrivate(privSpec);
}
case "PUBLIC KEY" -> {
KeySpec keySpec = new X509EncodedKeySpec(content);
publicKey = fact.generatePublic(keySpec);
}
case "RSA PUBLIC KEY" -> {
ASN1Sequence seq = ASN1Sequence.getInstance(content);
org.bouncycastle.asn1.pkcs.RSAPublicKey key = org.bouncycastle.asn1.pkcs.RSAPublicKey
.getInstance(seq);View on GitHub (pinned to 96852e8860)
Solutions
- Convert the key to PKCS#1: openssl rsa -in key.pem -traditional -out rsakey.pem
- Verify the base64 body is complete and unmodified between BEGIN/END lines
- Match the PEM header to the actual format (BEGIN PRIVATE KEY = PKCS#8, BEGIN RSA PRIVATE KEY = PKCS#1)
- Re-extract the key: openssl rsa -in bad.pem -check
Example fix
// before openssl pkcs8 -topk8 -in rsa.pem // produces PKCS#8, seq size != 9 // after openssl rsa -in key.pem -traditional -out rsa_pkcs1.pem
Defensive patterns
Strategy: validation
Validate before calling
// Confirm PKCS#1 format before parsing
String body = pem.replaceAll("-----(BEGIN|END) RSA PRIVATE KEY-----", "").replaceAll("\\s", "");
byte[] der = Base64.getMimeDecoder().decode(body);
if (der[4] != 0x30) throw new IllegalArgumentException("Not DER sequence"); Try / catch
try { return RsaKeyHelper.parseKeyPair(pem); } catch (IllegalArgumentException ex) { if (ex.getMessage().contains("ASN1")) { /* convert key with openssl and retry once */ } throw ex; } Prevention
- Generate keys in PKCS#1 (openssl genrsa / openssl rsa -traditional)
- Never hand-edit PEM bodies
- Match PEM header to actual DER structure
- Validate keys with openssl rsa -check before use
When it happens
Trigger: Passing a 'PRIVATE KEY' (PKCS#8) PEM but labeled or routed into the 'RSA PRIVATE KEY' branch; truncated or corrupted base64 body; passing a public key or certificate body under an RSA PRIVATE KEY header.
Common situations: Key generated by OpenSSL in PKCS#8 format (openssl genpkey) instead of traditional PKCS#1 (openssl genrsa); manual header edits; copy-paste truncation of the long base64 block.
Related errors
- String is not PEM encoded data, nor a public key encoded for
- is not a supported format
- Cannot load keys from store:
- Only RSA is currently supported, but algorithm was
- Key data does not contain a public key
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/f6ebafc5f19081cb.
Report an issue: GitHub.