{"record":{"id":"75a911053507a866","repo":"elastic/elasticsearch","slug":"private-key-encrypted-with-unsupported-algorithm","errorCode":null,"errorMessage":"Private Key encrypted with unsupported algorithm [{}]","messagePattern":"Private Key encrypted with unsupported algorithm \\[(.+?)\\]","errorType":"exception","errorClass":"GeneralSecurityException","httpStatus":null,"severity":"error","filePath":"libs/ssl-config/src/main/java/org/elasticsearch/common/ssl/PemUtils.java","lineNumber":532,"sourceCode":"            throw new IOException(\"Malformed PEM file, DEK-Info IV is invalid\", e);\n        }\n        if (\"DES-CBC\".equals(algorithm)) {\n            byte[] key = generateOpenSslKey(password, iv, 8);\n            encryptionKey = new SecretKeySpec(key, DEPRECATED_DES_ALGORITHM);\n        } else if (\"DES-EDE3-CBC\".equals(algorithm)) {\n            byte[] key = generateOpenSslKey(password, iv, 24);\n            encryptionKey = new SecretKeySpec(key, DEPRECATED_DES_EDE_ALGORITHM);\n        } else if (\"AES-128-CBC\".equals(algorithm)) {\n            byte[] key = generateOpenSslKey(password, iv, 16);\n            encryptionKey = new SecretKeySpec(key, \"AES\");\n        } else if (\"AES-192-CBC\".equals(algorithm)) {\n            byte[] key = generateOpenSslKey(password, iv, 24);\n            encryptionKey = new SecretKeySpec(key, \"AES\");\n        } else if (\"AES-256-CBC\".equals(algorithm)) {\n            byte[] key = generateOpenSslKey(password, iv, 32);\n            encryptionKey = new SecretKeySpec(key, \"AES\");\n        } else {\n            throw new GeneralSecurityException(\"Private Key encrypted with unsupported algorithm [\" + algorithm + \"]\");\n        }\n        String transformation = encryptionKey.getAlgorithm() + \"/\" + \"CBC\" + \"/\" + padding;\n        Cipher cipher = Cipher.getInstance(transformation);\n        cipher.init(Cipher.DECRYPT_MODE, encryptionKey, new IvParameterSpec(iv));\n        return cipher;\n    }\n\n    /**\n     * Performs key stretching in the same manner that OpenSSL does. This is basically a KDF\n     * that uses n rounds of salted MD5 (as many times as needed to get the necessary number of key bytes)\n     * <p>\n     * https://www.openssl.org/docs/man1.1.0/crypto/PEM_write_bio_PrivateKey_traditional.html\n     */\n    private static byte[] generateOpenSslKey(char[] password, byte[] salt, int keyLength) {\n        byte[] passwordBytes = CharArrays.toUtf8Bytes(password);\n        MessageDigest md5 = SslUtil.messageDigest(\"md5\");\n        byte[] key = new byte[keyLength];\n        int copied = 0;","sourceCodeStart":514,"sourceCodeEnd":550,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/libs/ssl-config/src/main/java/org/elasticsearch/common/ssl/PemUtils.java#L514-L550","documentation":"Thrown by getCipherFromParameters when the DEK-Info algorithm token does not match any of the supported ciphers: DES-CBC, DES-EDE3-CBC, AES-128-CBC, AES-192-CBC, AES-256-CBC. Any other algorithm name (e.g. 'BF-CBC' for Blowfish, 'RC2-CBC', 'CAMELLIA-256-CBC', or a misspelled AES variant) is rejected as a GeneralSecurityException.","triggerScenarios":"Loading an OpenSSL-format encrypted key produced by 'openssl rsa -<cipher>' or 'openssl ec -<cipher>' with an unsupported cipher such as '-bf' (Blowfish), '-camellia-*', or '-rc2'; a key produced by an older OpenSSL defaulting to an unsupported algorithm; a hand-edited DEK-Info header with a misspelled algorithm.","commonSituations":"Operators using legacy OpenSSL invocations; keys produced by non-conformant tooling; migration from environments that allowed Blowfish/Camellia; misspelled algorithm names from manual editing.","solutions":["Re-encrypt the key with a supported cipher: 'openssl rsa -aes256 -in plain.key -out enc.key' (RSA) or 'openssl ec -aes256 -in plain.key -out enc.key' (EC).","Confirm the DEK-Info algorithm token is exactly one of: DES-CBC, DES-EDE3-CBC, AES-128-CBC, AES-192-CBC, AES-256-CBC.","If you cannot re-encrypt, decrypt the key with a tool that supports the original cipher and re-encrypt with OpenSSL using AES-256-CBC."],"exampleFix":"// before: encrypt with Blowfish (unsupported)\n//   openssl rsa -bf -in plain.key -out enc.key\n// after: encrypt with AES-256-CBC (supported)\nopenssl rsa -aes256 -in plain.key -out enc.key","handlingStrategy":"validation","validationCode":"// Validate the DEK-Info cipher is one of the supported algorithms\nSet<String> SUPPORTED = Set.of(\"DES-CBC\", \"DES-EDE3-CBC\", \"AES-128-CBC\", \"AES-192-CBC\", \"AES-256-CBC\");\nString algo = /* algorithm token from DEK-Info */;\nif (!SUPPORTED.contains(algo)) {\n    throw new IllegalArgumentException(\"Unsupported PEM cipher: \" + algo + \"; re-encrypt with AES-256-CBC\");\n}","typeGuard":null,"tryCatchPattern":"try { PemUtils.readPrivateKey(path, passwordSupplier); }\ncatch (GeneralSecurityException e) { if (e.getMessage().contains(\"unsupported algorithm\")) { /* re-encrypt with AES */ } else throw e; }","preventionTips":["Standardise on AES-256-CBC for OpenSSL-format encrypted keys.","Regenerate keys with 'openssl <algo> -aes256' rather than legacy ciphers.","Document supported ciphers in your key-generation runbook."],"tags":["ssl","pem","cipher","encrypted","dek-info","config"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}