elastic/elasticsearch · error · GeneralSecurityException
PKCS#8 Private Key is encrypted with unsupported PBES2 algor
Error message
PKCS#8 Private Key is encrypted with unsupported PBES2 algorithm [{}] What it means
Thrown by getEncryptedPrivateKeyInfo as a fallback when the JCE cannot construct an EncryptedPrivateKeyInfo and manual ASN.1 parsing reveals the key is PBES2-encrypted with a cipher whose OID does not start with the AES OID prefix (2.16.840.1.101.3.4.1). Only AES variants are supported under PBES2; anything else (e.g. RC2, DES, Camellia under PBES2) is rejected with a descriptive OID and optional algorithm name.
Source
Thrown at libs/ssl-config/src/main/java/org/elasticsearch/common/ssl/PemUtils.java:429
} catch (IOException e) {
// The Sun JCE provider can't handle non-AES PBES2 data (but it can handle PBES1 DES data - go figure)
// It's not worth our effort to try and decrypt it ourselves, but we can detect it and give a good error message
DerParser parser = new DerParser(keyBytes);
final DerParser.Asn1Object rootSeq = parser.readAsn1Object(DerParser.Type.SEQUENCE);
parser = rootSeq.getParser();
final DerParser.Asn1Object algSeq = parser.readAsn1Object(DerParser.Type.SEQUENCE);
parser = algSeq.getParser();
final String algId = parser.readAsn1Object(DerParser.Type.OBJECT_OID).getOid();
if (PBES2_OID.equals(algId)) {
final DerParser.Asn1Object algData = parser.readAsn1Object(DerParser.Type.SEQUENCE);
parser = algData.getParser();
final DerParser.Asn1Object ignoreKdf = parser.readAsn1Object(DerParser.Type.SEQUENCE);
final DerParser.Asn1Object cryptSeq = parser.readAsn1Object(DerParser.Type.SEQUENCE);
parser = cryptSeq.getParser();
final String encryptionId = parser.readAsn1Object(DerParser.Type.OBJECT_OID).getOid();
if (encryptionId.startsWith(AES_OID) == false) {
final String name = getAlgorithmNameFromOid(encryptionId);
throw new GeneralSecurityException(
"PKCS#8 Private Key is encrypted with unsupported PBES2 algorithm ["
+ encryptionId
+ "]"
+ (name == null ? "" : " (" + name + ")"),
e
);
}
}
throw e;
}
}
/**
* This is horrible, but it's the only option other than to parse the encoded ASN.1 value ourselves
* @see AlgorithmParameters#toString() and com.sun.crypto.provider.PBES2Parameters#toString()
*/
private static String getPBES2Algorithm(EncryptedPrivateKeyInfo encryptedPrivateKeyInfo) {
final AlgorithmParameters algParameters = encryptedPrivateKeyInfo.getAlgParameters();View on GitHub (pinned to db6a809a66)
Solutions
- Re-encrypt the key with an AES cipher: 'openssl pkcs8 -topk8 -in current.key -out new.key -v2 aes-256-cbc'.
- If the key was produced by an older OpenSSL, regenerate it with a modern default (modern OpenSSL defaults to AES-256-CBC under PBES2).
- If a third-party tool generated the key, export it from that tool in plaintext or PKCS#8 AES and re-import.
Example fix
// before: encrypt with 3DES under PBES2 (unsupported) // openssl pkcs8 -topk8 -inkey raw.key -out enc.key -v2 des3 // after: encrypt with AES-256-CBC under PBES2 openssl pkcs8 -topk8 -inkey raw.key -out enc.key -v2 aes-256-cbc
Defensive patterns
Strategy: try-catch
Validate before calling
// Inspect the PBES2 cipher OID before passing the key to Elasticsearch // openssl asn1parse -in enc.key -strparse 4 gives the encryption algorithm; confirm it starts with 2.16.840.1.101.3.4.1 (AES). // Alternatively: openssl pkcs8 -topk8 -in current.key -out new.key -v2 aes-256-cbc (re-encrypt to a supported cipher).
Try / catch
try {
PemUtils.readPrivateKey(path, passwordSupplier);
} catch (GeneralSecurityException e) {
if (e.getMessage().contains("unsupported PBES2 algorithm")) {
// re-encrypt with AES-256-CBC and retry
} else throw e;
} Prevention
- Standardise on AES-256-CBC for encrypted PKCS#8 keys across your PKI tooling.
- Document the supported PBES2 ciphers (AES only) in your key-generation runbook.
- Audit keys generated by third-party tools with 'openssl asn1parse' before importing.
When it happens
Trigger: Loading an encrypted PKCS#8 key produced by 'openssl pkcs8 -topk8 -v2 <cipher>' where <cipher> is a non-AES cipher such as 'des3', 'rc2', or 'camellia'; a key produced by a third-party tool (e.g. old Java BouncyCastle defaults, NSS, or Windows certmgr) that selected a non-AES PBES2 cipher.
Common situations: Operators migrating from older OpenSSL defaults; keys generated by enterprise PKI tooling that mandates non-AES ciphers; interoperability with legacy HSMs; keys produced with 'openssl pkcs8 -v1 des3' (which is PBES1, handled separately) versus '-v2 des3' (PBES2 with 3DES, which is NOT supported here).
Related errors
- Error parsing key algorithm identifier. Algorithm with OID [
- failed to load a KeyManager for certificate/key pair [{}], [
- could not load ssl private key file [{}]
- cannot create trust using PEM certificates [{}]
- could not load ssl private key file [{}]
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/5b6603190f282e8c.
Report an issue: GitHub.