{"record":{"id":"c7353f4abe2bea11","repo":"spring-projects/spring-security","slug":"no-sha-implementation-available","errorCode":null,"errorMessage":"No SHA implementation available!","messagePattern":"No SHA implementation available!","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"crypto/src/main/java/org/springframework/security/crypto/password/LdapShaPasswordEncoder.java","lineNumber":118,"sourceCode":"\n\tprivate String encode(CharSequence rawPassword, byte @Nullable [] salt) {\n\t\tMessageDigest sha = getSha(rawPassword);\n\t\tif (salt != null) {\n\t\t\tsha.update(salt);\n\t\t}\n\t\tbyte[] hash = combineHashAndSalt(sha.digest(), salt);\n\t\tString prefix = getPrefix(salt);\n\t\treturn prefix + Utf8.decode(Base64.getEncoder().encode(hash));\n\t}\n\n\tprivate MessageDigest getSha(CharSequence rawPassword) {\n\t\ttry {\n\t\t\tMessageDigest sha = MessageDigest.getInstance(\"SHA\");\n\t\t\tsha.update(Utf8.encode(rawPassword));\n\t\t\treturn sha;\n\t\t}\n\t\tcatch (java.security.NoSuchAlgorithmException ex) {\n\t\t\tthrow new IllegalStateException(\"No SHA implementation available!\");\n\t\t}\n\t}\n\n\tprivate String getPrefix(byte @Nullable [] salt) {\n\t\tif (salt == null || salt.length == 0) {\n\t\t\treturn this.forceLowerCasePrefix ? SHA_PREFIX_LC : SHA_PREFIX;\n\t\t}\n\t\treturn this.forceLowerCasePrefix ? SSHA_PREFIX_LC : SSHA_PREFIX;\n\t}\n\n\tprivate byte[] extractSalt(String encPass) {\n\t\tString encPassNoLabel = encPass.substring(6);\n\t\tbyte[] hashAndSalt = Base64.getDecoder().decode(encPassNoLabel.getBytes());\n\t\tint saltLength = hashAndSalt.length - SHA_LENGTH;\n\t\tbyte[] salt = new byte[saltLength];\n\t\tSystem.arraycopy(hashAndSalt, SHA_LENGTH, salt, 0, saltLength);\n\t\treturn salt;\n\t}","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/crypto/src/main/java/org/springframework/security/crypto/password/LdapShaPasswordEncoder.java#L100-L136","documentation":"getSha requests the plain \"SHA\" (SHA-1) MessageDigest and rethrows NoSuchAlgorithmException as IllegalStateException(\"No SHA implementation available!\"). Every compliant JDK must provide SHA-1, so this indicates a fundamentally broken or non-standard Java runtime with no SHA-capable security provider installed. The exception deliberately loses the original cause, which makes diagnosing provider problems harder.","triggerScenarios":"Calling encode or matches on LdapShaPasswordEncoder in a JVM where MessageDigest.getInstance(\"SHA\") fails because security providers are stripped, misconfigured, or replaced (e.g. restricted FIPS-only runtime without \"SHA\" alias).","commonSituations":"Custom java.security configuration removing the SUN provider; embedding the library in a heavily hardened or minimal runtime image; provider registration failures at JVM startup.","solutions":["Restore the default SUN security provider or add \"security.provider.1=sun.security.provider.Sun\" back in the java.security file.","Verify with MessageDigest.getInstance(\"SHA\") in a plain main() to confirm the runtime itself is the problem.","Run on a standard JDK/JRE distribution that includes SHA-1 support instead of a custom minimal image."],"exampleFix":"// before (custom java.security)\n#security.provider.1=sun.security.provider.Sun\n// after\nsecurity.provider.1=sun.security.provider.Sun","handlingStrategy":"try-catch","validationCode":"try { MessageDigest.getInstance(\"SHA\"); } catch (java.security.NoSuchAlgorithmException e) {\n    throw new IllegalStateException(\"JVM lacks SHA provider; fix java.security config\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    encoder.encode(rawPassword);\n} catch (IllegalStateException e) {\n    if (e.getMessage().contains(\"No SHA implementation\")) {\n        // alert: JVM provider configuration is broken; fail fast / restore providers\n    }\n}","preventionTips":["Do not strip the SUN provider from java.security in production images.","Run a startup smoke test that hashes a probe string with every encoder in use."],"tags":["java","spring-security","crypto","jvm"],"backgroundTag":"unsupported-platform","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}