加盐密码破解遇阻求助:字典与哈希算法相关问题排查
Hey there! It’s frustrating when unsalted hashes crack smoothly but salted ones won’t cooperate—let’s walk through the most likely issues and fixes for your scenario.
1. You’re Treating the Hex Salt as a Plain String (Biggest Culprit!)
You mentioned the salt is a hexadecimal string, but your current code is concatenating it directly with the word as a regular string before hashing. That’s almost certainly the problem.
For example:
- If your salt hex string is
a1b2, it represents the bytes0xA1and0xB2(not the ASCII/UTF-8 bytes for the characters 'a', '1', 'b', '2'). - Your code is hashing
word + "a1b2"(the string), but the target system is probably hashingword_bytes + 0xA10xB2(the raw salt bytes).
Fix: Convert the Hex Salt to Bytes First
Add a helper method to parse the hex string into a byte array, then combine those bytes with your word’s bytes before hashing:
import java.nio.charset.StandardCharsets; import java.security.MessageDigest; public class HashHelper { // Convert hex string to byte array public static byte[] hexToBytes(String hexSalt) { int length = hexSalt.length(); byte[] saltBytes = new byte[length / 2]; for (int i = 0; i < length; i += 2) { saltBytes[i / 2] = (byte) ((Character.digit(hexSalt.charAt(i), 16) << 4) + Character.digit(hexSalt.charAt(i+1), 16)); } return saltBytes; } public static String hashWithSalt(String word, String hexSalt) throws Exception { MessageDigest md = MessageDigest.getInstance("MD5"); // Get word bytes with explicit encoding (match target system!) byte[] wordBytes = word.getBytes(StandardCharsets.UTF_8); byte[] saltBytes = hexToBytes(hexSalt); // Combine word and salt bytes (adjust order if needed!) byte[] combined = new byte[wordBytes.length + saltBytes.length]; System.arraycopy(wordBytes, 0, combined, 0, wordBytes.length); System.arraycopy(saltBytes, 0, combined, wordBytes.length, saltBytes.length); md.update(combined); byte[] digest = md.digest(); // Convert digest to hex string (lowercase, match target format) StringBuilder sb = new StringBuilder(); for (byte b : digest) { sb.append(String.format("%02x", b)); } return sb.toString(); } }
2. Salt-Password Order Might Be Reversed
You mentioned trying to append the salt before and after, but double-check the target system’s actual logic. Some systems use salt + password instead of password + salt. Test both orders with the fixed hex-to-byte logic above.
3. Character Encoding Mismatch
Your original code uses getBytes() without specifying an encoding, which uses your system’s default (could be UTF-8, ISO-8859-1, etc.). If the target system used a different encoding to convert the password string to bytes, your hash will never match. Always specify the encoding explicitly (like StandardCharsets.UTF_8 or StandardCharsets.US_ASCII) to match the target system’s setup.
4. Hex String Case Sensitivity
Some systems output hash values in uppercase, while your code generates lowercase. If the target hash is A1B2C3... and your code returns a1b2c3..., the comparison will fail. Normalize both to lowercase or uppercase before checking for matches.
Quick Validation Step
To confirm your fix works, pick a known password and salt, compute the hash manually (using an offline tool that supports hex salts), then run it through your updated code. If the outputs match, you’re on the right track!
内容的提问来源于stack exchange,提问作者Polyphase29

