How to hash a string (SHA-256, MD5)
Short answer
MessageDigest computes a hash of bytes. HexFormat (Java 17) turns the result into a string of hex digits:
void main() throws Exception {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest("hello".getBytes(StandardCharsets.UTF_8));
IO.println(HexFormat.of().formatHex(hash));
}Output:
2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824Other algorithms
The algorithm name is passed as a string. MD5 and SHA-1 are only good for checksums, not for security:
String hash(String algorithm, String text) throws Exception {
byte[] bytes = MessageDigest.getInstance(algorithm).digest(text.getBytes(StandardCharsets.UTF_8));
return HexFormat.of().formatHex(bytes);
}
void main() throws Exception {
IO.println(hash("MD5", "hello"));
IO.println(hash("SHA-1", "hello"));
}Output:
5d41402abc4b2a76b9719d911017c592
aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434dA file hash
For a file, pass all of its bytes:
void main() throws Exception {
Path file = Path.of("data.txt");
Files.writeString(file, "hello");
byte[] hash = MessageDigest.getInstance("SHA-256").digest(Files.readAllBytes(file));
IO.println(HexFormat.of().formatHex(hash).substring(0, 16));
}Output:
2cf24dba5fb0a30eCommon mistake
Storing passwords as SHA-256 or MD5. Such hashes are very fast to compute, so brute-forcing a password is easy. For passwords use slow salted algorithms — bcrypt, scrypt or Argon2 (for example, BCryptPasswordEncoder from Spring Security).
Functions used in this recipe
- Integer.toBinaryString() — Writes a number in binary. Related methods are toHexString() and toOctalString().