spring-projects/spring-boot · error · IllegalArgumentException
Error decrypting private key
Error message
Error decrypting private key
What it means
Pkcs8PrivateKeyDecryptor.decrypt handles BEGIN ENCRYPTED PRIVATE KEY blocks. It builds EncryptedPrivateKeyInfo from the bytes, derives a PBE SecretKey from the supplied password, obtains a Cipher, and returns keyInfo.getKeySpec(cipher). The catch (IOException | GeneralSecurityException) wraps any failure as IllegalArgumentException. The most common cause is a wrong password; it can also be an unsupported encryption algorithm.
Solutions
- Supply the correct password (the parse(text, password) overload).
- Verify the password decrypts the key out of band: `openssl pkey -in key.enc -passin pass:<pw>`.
- Re-encrypt with a standard algorithm: `openssl pkcs8 -topk8 -in key.pem -out key.enc`.
- On JDK 8u160 or older, install the JCE Unlimited Strength policy files; current JDKs ship with it by default.
Defensive patterns
Strategy: try-catch
Validate before calling
// Confirm the password decrypts the key out of band
Process p = new ProcessBuilder("openssl", "pkey", "-in", keyPath.toString(),
"-passin", "pass:" + password, "-noout").redirectErrorStream(true).start();
if (p.waitFor() != 0) {
throw new IllegalArgumentException("Wrong password or unsupported encryption for " + keyPath);
} Try / catch
try {
PemPrivateKeyParser.parse(text, password);
} catch (IllegalStateException ex) {
Throwable c = ex.getCause();
if (c instanceof IllegalArgumentException
&& "Error decrypting private key".equals(c.getMessage())) {
// prompt the user for the correct password and retry once
}
throw ex;
} Prevention
- Verify the private key password in CI with `openssl pkey -in key.enc -passin pass:...`.
- Prefer unencrypted keys when the secrets are already managed by a vault.
- Re-encrypt with a standard PBES2 algorithm (`openssl pkcs8 -topk8`) for broad JVM compatibility.
When it happens
Trigger: createKeySpecForPkcs8Encrypted calls Pkcs8PrivateKeyDecryptor.decrypt(bytes, password). Failure occurs when: the password is wrong (Cipher.init or getKeySpec fails); the PBES2 algorithm in the key is not offered by the configured JCE provider; the encrypted key bytes are malformed; or password is null on an encrypted key (Assert.state at line 452 throws IllegalArgumentException before the try, with a different message).
Common situations: Wrong passphrase supplied at build time; key encrypted with an algorithm (e.g. PBES2 with AES-256-GCM) the JVM cannot service on a very old JDK without unlimited-crypto policy; corrupted encrypted key; password not propagated through the buildpack configuration.
Related errors
- Error loading private key file
- Missing private key or unrecognized format
- Error adding certificates to KeyStore
- Error creating KeyStore
- Error reading certificate
AI-assisted analysis of spring-projects/spring-boot@270dfe353f (2026-08-11).
Data as JSON: /api/errors/9cf446862fbde168.
Report an issue: GitHub.
Appendix: source
Thrown at buildpack/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/ssl/PemPrivateKeyParser.java:464
*/
static class Pkcs8PrivateKeyDecryptor {
public static final String PBES2_ALGORITHM = "PBES2";
static PKCS8EncodedKeySpec decrypt(byte[] bytes, @Nullable String password) {
Assert.state(password != null, "Password is required for an encrypted private key");
try {
EncryptedPrivateKeyInfo keyInfo = new EncryptedPrivateKeyInfo(bytes);
AlgorithmParameters algorithmParameters = keyInfo.getAlgParameters();
String encryptionAlgorithm = getEncryptionAlgorithm(algorithmParameters, keyInfo.getAlgName());
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(encryptionAlgorithm);
SecretKey key = keyFactory.generateSecret(new PBEKeySpec(password.toCharArray()));
Cipher cipher = Cipher.getInstance(encryptionAlgorithm);
cipher.init(Cipher.DECRYPT_MODE, key, algorithmParameters);
return keyInfo.getKeySpec(cipher);
}
catch (IOException | GeneralSecurityException ex) {
throw new IllegalArgumentException("Error decrypting private key", ex);
}
}
private static String getEncryptionAlgorithm(@Nullable AlgorithmParameters algParameters, String algName) {
if (algParameters != null && PBES2_ALGORITHM.equals(algName)) {
return algParameters.toString();
}
return algName;
}
}
/**
* ANS.1 encoded object identifier.
*/
static final class EncodedOid {
static final EncodedOid OID_1_2_840_10040_4_1 = EncodedOid.of("2a8648ce380401");View on GitHub (pinned to 270dfe353f)