How to hash some String with SHA-256 in Java?
SHA-256 isn't an "encoding" - it's a one-way hash.
You'd basically convert the string into bytes (e.g. using text.getBytes(StandardCharsets.UTF_8)
) and then hash the bytes. Note that the result of the hash would also be arbitrary binary data, and if you want to represent that in a string, you should use base64 or hex... don't try to use the String(byte[], String)
constructor.
e.g.
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(text.getBytes(StandardCharsets.UTF_8));
Hash String via SHA-256 in Java
To hash a string, use the built-in MessageDigest class:
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.nio.charset.StandardCharsets;
import java.math.BigInteger;
public class CryptoHash {
public static void main(String[] args) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("SHA-256");
String text = "Text to hash, cryptographically.";
// Change this to UTF-16 if needed
md.update(text.getBytes(StandardCharsets.UTF_8));
byte[] digest = md.digest();
String hex = String.format("%064x", new BigInteger(1, digest));
System.out.println(hex);
}
}
In the snippet above, digest
contains the hashed string and hex
contains a hexadecimal ASCII string with left zero padding.
Hashing password by SHA256 then write to file
Code
You can test/run this code on ▶▶▶▶▶ https://replit.com/@JomaCorpFX/JavaHashes
HashAlgorithm.java
public enum HashAlgorithm {
SHA512("SHA-512"),
SHA256("SHA-256"),
SHA384("SHA-384"),
SHA1("SHA-1"),
MD5("MD5");
private String Value = "";
HashAlgorithm(String Value) {
this.Value = Value;
}
@Override
public String toString() {
return Value;
}
}
HexEncoder.java
import java.util.Formatter;
public class HexEncoder{
public static String toHex(byte[] data) {
StringBuilder sb = new StringBuilder(data.length * 2);
try (Formatter formatter = new Formatter(sb))
{
for (byte b : data)
{
formatter.format("%02x", b);
}
}
return sb.toString();
}
}
HashManager.java
import java.security.MessageDigest;
import java.nio.charset.StandardCharsets;
public class HashManager {
public static byte[] toRawHash(byte[] data, HashAlgorithm algorithm) throws Exception
{
byte[] buffer = data;
MessageDigest messageDigest = MessageDigest.getInstance(algorithm.toString());
messageDigest.reset();
messageDigest.update(buffer);
return messageDigest.digest();
}
public static String toHexHash(byte[] data, HashAlgorithm algorithm) throws Exception
{
return HexEncoder.toHex(toRawHash(data, algorithm));
}
public static String toHexHash(String data, HashAlgorithm algorithm) throws Exception
{
return toHexHash(data.getBytes(StandardCharsets.UTF_8), algorithm);
}
}
Main.java
public class Main {
public static void main(String[] args) throws Exception {
String data = "grape";
System.out.println(HashManager.toHexHash(data, HashAlgorithm.SHA256));
System.out.println(HashManager.toHexHash(data, HashAlgorithm.SHA256));
System.out.println(HashManager.toHexHash(data, HashAlgorithm.SHA256));
System.out.println(HashManager.toHexHash(data, HashAlgorithm.SHA256));
}
}
Output
Verify Hashing.sha256() generated hash
SHA-256 and, in general, the family of SHA 2 algorithms is wonderfully described in Wikipedia and different RFCs, RFC 6234 and the superseded RFC 4634.
All these sources dictate that the output provided by the SHA 256 hash function is 256 bits length, 32 bytes (the number that accompanies the SHA word is the mentioned value for every algorithm in the family, roughly speaking).
These sequence of bytes is typically encoded in hex. This is the implementation provided by Guava as well.
Then, the problem can be reduced to identify if a string in Java is a valid hex encoding.
That problem has been already answered here, in SO, for example in this question.
For its simplicity, consider the solution proposed by @laycat:
boolean isHex = mac_addr.matches("^[0-9a-fA-F]+$");
As every byte is encoded with two hex characters and, as mentioned, the SHA-256 algorithm produces and output of 32 bytes you can safely check for a string of 64 characters length, as suggested in the answer of @D.O. as well. Your validation code could be similar to this:
boolean canBeSha256Output = sha256Hex.matches("^[0-9a-fA-F]{64}$");
Please, be aware that there is no possibility for saying if a character hex string of a certain length on its own is or not the result of a hash function, whichever hash function you consider.
You only can be sure that a hash output is a hash output if and only if it matches the result of applying the corresponding hash function over the original input.
How to hash a string using SHA-256
this will pring hex representation of hash
String s = DatatypeConverter.printHexBinary(hash)
you cannot get original string from hash
Java SHA-256 Program provides wrong Hash
A 32-byte hash means a string of 64 characters. Each byte contains 2 hex digits, so you need 2 characters per byte:
while (hexString.length() < 64)
{
hexString.insert(0, '0');
}
Related Topics
What Does Statement.Setfetchsize(Nsize) Method Really Do in SQL Server Jdbc Driver
Generate All Combinations from Multiple Lists
Parsing an Arithmetic Expression and Building a Tree from It in Java
Java Count Occurrence of Each Item in an Array
Cannot Issue Data Manipulation Statements with Executequery()
Java Method to Swap Primitives
Jersey /* Servlet Mapping Causes 404 Error for Static Resources
How to Terminate Scanner When Input Is Complete
Comparing Two Integer Arrays in Java
How to Store More Than One String in a Map
Creating a Variable Name Using a String Value
How to Parse Output of New Date().Tostring()
Java Datetimeformatterbuilder Fails on Testtime
How to Activate Jmx on My Jvm for Access with Jconsole
How to Decompile a Whole Jar File
Why Double Width = 50/110000; the Output Is 0.000000000000000
Updating Java Priorityqueue When Its Elements Change Priority