{"record":{"id":"f2c74c8edb63d77b","repo":"skylot/jadx","slug":"failed-to-build-hash","errorCode":null,"errorMessage":"Failed to build hash","messagePattern":"Failed to build hash","errorType":"exception","errorClass":"JadxRuntimeException","httpStatus":null,"severity":"critical","filePath":"jadx-core/src/main/java/jadx/core/utils/files/FileUtils.java","lineNumber":501,"sourceCode":"\tpublic static List<Path> fileNamesToPaths(List<String> fileNames) {\n\t\treturn fileNames.stream().map(Paths::get).collect(Collectors.toList());\n\t}\n\n\tpublic static List<File> toFiles(List<Path> paths) {\n\t\treturn paths.stream().map(Path::toFile).collect(Collectors.toList());\n\t}\n\n\tpublic static String md5Sum(String str) {\n\t\treturn md5Sum(str.getBytes(StandardCharsets.UTF_8));\n\t}\n\n\tpublic static String md5Sum(byte[] data) {\n\t\ttry {\n\t\t\tMessageDigest md = MessageDigest.getInstance(\"MD5\");\n\t\t\tmd.update(data);\n\t\t\treturn bytesToHex(md.digest());\n\t\t} catch (Exception e) {\n\t\t\tthrow new JadxRuntimeException(\"Failed to build hash\", e);\n\t\t}\n\t}\n\n\t/**\n\t * Hash timestamps of input files\n\t */\n\tpublic static String buildInputsHash(List<Path> inputPaths) {\n\t\ttry (ByteArrayOutputStream bout = new ByteArrayOutputStream();\n\t\t\t\tDataOutputStream data = new DataOutputStream(bout)) {\n\t\t\tList<Path> inputFiles = FileUtils.expandDirs(inputPaths);\n\t\t\tCollections.sort(inputFiles);\n\t\t\tdata.write(inputPaths.size());\n\t\t\tdata.write(inputFiles.size());\n\t\t\tfor (Path inputFile : inputFiles) {\n\t\t\t\tFileTime modifiedTime = Files.getLastModifiedTime(inputFile);\n\t\t\t\tdata.writeLong(modifiedTime.toMillis());\n\t\t\t}\n\t\t\treturn FileUtils.md5Sum(bout.toByteArray());","sourceCodeStart":483,"sourceCodeEnd":519,"githubUrl":"https://github.com/skylot/jadx/blob/e738a26571d02919f01df40de93bc9a44dee4e18/jadx-core/src/main/java/jadx/core/utils/files/FileUtils.java#L483-L519","documentation":"Thrown by md5Sum(byte[]) when MessageDigest.getInstance(\"MD5\") fails. MD5 is a mandatory algorithm in every standard Java JDK (mandated by JCA specification), so NoSuchAlgorithmException should never occur in a compliant JVM. The only realistic trigger is a non-compliant or severely stripped/custom JVM (e.g., a minimal embedded JVM, or a security provider configuration that removed MD5). The catch is defensive.","triggerScenarios":"Running jadx on a non-standard JVM that does not include the MD5 algorithm. A custom security.provider configuration that explicitly deregisters MD5. An extremely minimal/embedded JVM that omits MessageDigest support.","commonSituations":"Embedded device JVMs with reduced crypto. A security policy (Java Security Manager or custom provider) that removed MD5. Extremely rare in practice — standard Oracle/OpenJDK, GraalVM, and Android all include MD5.","solutions":["Use a standard JDK (Oracle, OpenJDK, or a JCA-compliant JVM) that includes MD5.","Check installed security providers: java.security.Security.getProviders() and verify MessageDigest hash algorithms.","If MD5 was intentionally removed, patch md5Sum to use an alternative like SHA-256."],"exampleFix":"// before\nMessageDigest md = MessageDigest.getInstance(\"MD5\"); // can throw\n\n// after — verify provider support at startup\nif (MessageDigest.isAvailable(\"MD5\")) { // Java 17+; otherwise try/catch\n    md = MessageDigest.getInstance(\"MD5\");\n} else {\n    md = MessageDigest.getInstance(\"SHA-256\");\n}","handlingStrategy":"try-catch","validationCode":"// Check MD5 availability before use\npublic static boolean isMd5Available() {\n    try {\n        MessageDigest.getInstance(\"MD5\");\n        return true;\n    } catch (Exception e) {\n        return false;\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    String hash = FileUtils.md5Sum(data);\n} catch (JadxRuntimeException e) {\n    if (e.getCause() instanceof NoSuchAlgorithmException) {\n        // MD5 not available — use alternative or report environment issue\n        LOG.error(\"MD5 not available on this JVM: {}\", e.getCause().getMessage());\n    }\n}","preventionTips":["Use a standard JCA-compliant JDK that includes MD5.","Verify security providers at startup if running in a non-standard environment.","If MD5 is intentionally unavailable, patch md5Sum to use SHA-256."],"tags":["crypto","hash","jvm","jadx"],"backgroundTag":null,"analyzedSha":"e738a26571d02919f01df40de93bc9a44dee4e18","analyzedAt":"2026-08-14T00:10:24.238Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}