Hash String via SHA-256 in Java

JavaBouncycastleSha256Jce

Java Problem Overview


By looking around here as well as the internet in general, I have found Bouncy Castle. I want to use Bouncy Castle (or some other freely available utility) to generate a SHA-256 Hash of a String in Java. Looking at their documentation I can't seem to find any good examples of what I want to do. Can anybody here help me out?

Java Solutions


Solution 1 - 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.

Solution 2 - Java

This is already implemented in the runtime libs.

public static String calc(InputStream is) {
	String output;
	int read;
	byte[] buffer = new byte[8192];

	try {
		MessageDigest digest = MessageDigest.getInstance("SHA-256");
		while ((read = is.read(buffer)) > 0) {
			digest.update(buffer, 0, read);
		}
		byte[] hash = digest.digest();
		BigInteger bigInt = new BigInteger(1, hash);
		output = bigInt.toString(16);
        while ( output.length() < 32 ) {
            output = "0"+output;
        }
	} 
	catch (Exception e) {
		e.printStackTrace(System.err);
		return null;
	}

	return output;
}

In a JEE6+ environment one could also use JAXB DataTypeConverter:

import javax.xml.bind.DatatypeConverter;

String hash = DatatypeConverter.printHexBinary( 
           MessageDigest.getInstance("MD5").digest("SOMESTRING".getBytes("UTF-8")));

Solution 3 - Java

You don't necessarily need the BouncyCastle library. The following code shows how to do so using the Integer.toHexString function

public static String sha256(String base) {
    try{
        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        byte[] hash = digest.digest(base.getBytes("UTF-8"));
        StringBuffer hexString = new StringBuffer();
    
        for (int i = 0; i < hash.length; i++) {
            String hex = Integer.toHexString(0xff & hash[i]);
            if(hex.length() == 1) hexString.append('0');
            hexString.append(hex);
        }

        return hexString.toString();
    } catch(Exception ex){
       throw new RuntimeException(ex);
    }
}

Special thanks to user1452273 from this post: https://stackoverflow.com/questions/5531455/how-to-encode-some-string-with-sha256-in-java/11009612#11009612

Keep up the good work !

Solution 4 - Java

When using hashcodes with any jce provider you first try to get an instance of the algorithm, then update it with the data you want to be hashed and when you are finished you call digest to get the hash value.

MessageDigest sha = MessageDigest.getInstance("SHA-256");
sha.update(in.getBytes());
byte[] digest = sha.digest();

you can use the digest to get a base64 or hex encoded version according to your needs

Solution 5 - Java

Java 8: Base64 available:

	MessageDigest md = MessageDigest.getInstance( "SHA-512" );
	md.update( inbytes );
	byte[] aMessageDigest = md.digest();

	String outEncoded = Base64.getEncoder().encodeToString( aMessageDigest );
	return( outEncoded );

Solution 6 - Java

I suppose you are using a relatively old Java Version without SHA-256. So you must add the BouncyCastle Provider to the already provided 'Security Providers' in your java version.

    // NEEDED if you are using a Java version without SHA-256    
    Security.addProvider(new BouncyCastleProvider());
    
    // then go as usual 
    MessageDigest md = MessageDigest.getInstance("SHA-256");
    String text = "my string...";
    md.update(text.getBytes("UTF-8")); // or UTF-16 if needed
    byte[] digest = md.digest();

Solution 7 - Java

return new String(Hex.encode(digest));

Solution 8 - Java

Using Java 8

MessageDigest digest = null;
try {
	digest = MessageDigest.getInstance("SHA-256");
} catch (NoSuchAlgorithmException e) {
	e.printStackTrace();
}
byte[] hash = digest.digest(text.getBytes(StandardCharsets.UTF_8));
String encoded = DatatypeConverter.printHexBinary(hash);        
System.out.println(encoded.toLowerCase());

Solution 9 - Java

This will work with "org.bouncycastle.util.encoders.Hex" following package

return new String(Hex.encode(digest));

Its in bouncycastle jar.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionknpwrsView Question on Stackoverflow
Solution 1 - JavaBrendan LongView Answer on Stackoverflow
Solution 2 - JavastackerView Answer on Stackoverflow
Solution 3 - JavaWhiplashView Answer on Stackoverflow
Solution 4 - JavaNikolaus GradwohlView Answer on Stackoverflow
Solution 5 - JavaMike DeverView Answer on Stackoverflow
Solution 6 - Javaobe6View Answer on Stackoverflow
Solution 7 - JavaKayView Answer on Stackoverflow
Solution 8 - JavaMimu Saha TishanView Answer on Stackoverflow
Solution 9 - JavaShrikant KarvadeView Answer on Stackoverflow