How can I hash some String
with SHA-256
in Java?
-
2possible duplicate of [Hash String via SHA-256 in Java](http://stackoverflow.com/questions/3103652/hash-string-via-sha-256-in-java) – mmmmmm Aug 11 '14 at 12:25
-
1https://www.baeldung.com/sha-256-hashing-java – Barett Mar 31 '20 at 21:47
18 Answers
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));

- 3,837
- 1
- 36
- 46

- 1,421,763
- 867
- 9,128
- 9,194
-
24*"SHA-256 isn't an encoding"* absolutely right, but I must say I prefer the current question's title to "how to encrypt with sha" (many seem to think it's encryption). Perhaps we should treat it as encoding instead of something to do with cryptography because in practice that's closer to how it's used. – Luc Jun 10 '14 at 12:32
-
10@Luc: Well it's a cryptographic hash, so I don't think it's unreasonable to say it *does* have something to do with cryptography... encryption and cryptography aren't interchangable... – Jon Skeet Jun 10 '14 at 12:34
-
12Note: it's a good idea to use [StandardCharsets.UTF_8](http://docs.oracle.com/javase/7/docs/api/java/nio/charset/StandardCharsets.html#UTF_8) instead of the `"UTF-8"` literal in Java 7+: one checked exception less to worry about. – kryger Dec 01 '15 at 21:59
-
2@kryger: Agreed, and edited. Oh the joys of answers from before Java 7's release... – Jon Skeet Dec 01 '15 at 22:04
-
3Why should you avoid the String(byte[], String) constructor when dealing with the hash result? – Isaac van Bakel Apr 18 '16 at 13:03
-
7@IsaacvanBakel: Because a hash *isn't* encoded text. It's arbitrary binary data. – Jon Skeet Apr 18 '16 at 13:04
-
3The right way to call it should be "how do i hash a text using SHA 256" because at last what you have is the result of the aplication of a hashing algorithm, you are NOT encrypting the text since you can't decrypt it – Carlos de Luna Saenz Feb 27 '18 at 17:44
-
1@IsaacvanBakel: a hash is generally a result of conversion from the original string - and this conversion is one-way, fitting the result into specified amount of bits, and reproducible (same input gives same output). Imagine a sine waveform - you pick a point on X axis and get its height on Y axis. Y is the hash, this X always gives this Y. But many X'es do, so no Y=>X. Encoding (and/or lossless compression) is a conversion which is reversible - there you can get the input string by processing the output, and may be or not be reproducible (there are many ways to spell even base64 correctly). – Jim Klimov Dec 08 '20 at 14:58
-
raise error in vscode : Unhandled exception type NoSuchAlgorithmExceptionJava(16777384) – DachuanZhao Aug 19 '21 at 02:30
-
1@DachuanZhao: See https://stackoverflow.com/questions/16133881 - this is just normal checked exception behavior, and nothing to do with SHA-256 in particular. – Jon Skeet Aug 19 '21 at 05:25
I think that the easiest solution is to use Apache Common Codec:
String sha256hex = org.apache.commons.codec.digest.DigestUtils.sha256Hex(stringText);

- 2,454
- 1
- 13
- 7
Full example hash to string as another string.
public static String sha256(final String base) {
try{
final MessageDigest digest = MessageDigest.getInstance("SHA-256");
final byte[] hash = digest.digest(base.getBytes("UTF-8"));
final StringBuilder hexString = new StringBuilder();
for (int i = 0; i < hash.length; i++) {
final 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);
}
}

- 114,585
- 152
- 739
- 1,270

- 1,149
- 1
- 7
- 2
-
7To encode Jon's results as hex, consider using an existing library like [apache commons](http://commons.apache.org/codec/apidocs/org/apache/commons/codec/binary/Hex.html#encodeHexString%28byte[]%29) rather than rolling your own. – Leigh Jun 13 '12 at 20:18
-
1Why StringBuffer? (not a stringBuilder)? and maybe it would be better to set default size of stringbuilder? – Bogdan Oct 09 '13 at 12:28
-
46@Leigh: some people dont want to add a whole lib dependency just because they need a single function of it so rolling your own is sometimes a good idea. – Chris Sep 04 '14 at 09:23
-
5@Chris - True. That is why I said "consider" using it ;-) Existing libs can add bulk. On the flip side they are usually more highly tested than home spun code and of course save time. But there is no one-size-fits-all answer for everyone. – Leigh Sep 13 '14 at 19:52
-
2You could also read the source code from the library and copy its code! – Olav Grønås Gjerde May 10 '16 at 10:11
-
you save my life.. I want to convert php hash function $key = hash('sha256', '1234567890'); in android it gives me exact result.. Thank you so much – shubomb Feb 12 '20 at 11:01
-
Is there any reason that it could fail, though, and throw an exception (or have digest to be null) ? – android developer Mar 14 '21 at 13:35
-
Its not quite a full example... could you add `import java.security.MessageDigest;` to the top? It threw me off for a minute. – justin.m.chase Sep 10 '21 at 12:37
Another alternative is Guava which has an easy-to-use suite of Hashing utilities. For example, to hash a string using SHA256 as a hex-string you would simply do:
final String hashed = Hashing.sha256()
.hashString("your input", StandardCharsets.UTF_8)
.toString();

- 20,053
- 6
- 63
- 70
-
2Just to note – since introduction in version 11 it still marked as @Beta in version 30. – m1ld Aug 06 '21 at 11:23
If you are using Java 8 you can encode the byte[]
by doing
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(text.getBytes(StandardCharsets.UTF_8));
String encoded = Base64.getEncoder().encodeToString(hash);

- 13,582
- 13
- 81
- 106
-
1This way is convenient for me. However, you should use the following Base64.encodeToString(hash, Base64.DEFAULT); – Motassem Jalal Jun 27 '17 at 10:53
-
@MotassemJalal Base64.DEFAULT is not available in latest version of Java8, I am currently using jdk1.8.0_144, Can you please tell me how you have created it? – rajadilipkolli Dec 01 '17 at 07:30
-
2@rajadilipkolli I think it's the Android implementation: https://developer.android.com/reference/android/util/Base64 – dbm Jun 11 '18 at 19:33
-
1For some reason I get the wrong result from this. Example: for the input of "test", I got `n4bQgYhMfWWaL+qgxVrQFaO/TxsrC4Is0V1sFbDwCgg=` instead of `9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08` . How come? – android developer Mar 14 '21 at 13:39
-
It is one way of doing it, but not the common standard. @android developer, that is why you are seeing a different value here than what you'd see in other implementations. – Durga Swaroop Aug 30 '21 at 11:10
import java.security.MessageDigest;
public class CodeSnippets {
public static String getSha256(String value) {
try{
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(value.getBytes());
return bytesToHex(md.digest());
} catch(Exception ex){
throw new RuntimeException(ex);
}
}
private static String bytesToHex(byte[] bytes) {
StringBuffer result = new StringBuffer();
for (byte b : bytes) result.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1));
return result.toString();
}
}

- 3,310
- 3
- 25
- 41
-
What's the point of bitwise &-ing a byte value with `0xff`? It yields nothing, does it? – yktoo Jan 27 '17 at 14:20
-
3@yktoo : It converts it to a positive integer (bytes are signed in Java, unfortunately) http://stackoverflow.com/questions/11380062/what-does-value-0xff-do-in-java – leonbloy Mar 15 '17 at 18:18
-
String hashWith256(String textToHash) {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] byteOfTextToHash = textToHash.getBytes(StandardCharsets.UTF_8);
byte[] hashedByetArray = digest.digest(byteOfTextToHash);
String encoded = Base64.getEncoder().encodeToString(hashedByetArray);
return encoded;
}

- 455
- 5
- 14

- 331
- 3
- 10
I traced the Apache code through DigestUtils
and sha256
seems to default back to java.security.MessageDigest
for calculation. Apache does not implement an independent sha256
solution. I was looking for an independent implementation to compare against the java.security
library. FYI only.

- 6,511
- 13
- 49
- 53

- 99
- 1
- 3
Here is a slightly more performant way to turn the digest into a hex string:
private static final char[] hexArray = "0123456789abcdef".toCharArray();
public static String getSHA256(String data) {
StringBuilder sb = new StringBuilder();
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(data.getBytes());
byte[] byteData = md.digest();
sb.append(bytesToHex(byteData);
} catch(Exception e) {
e.printStackTrace();
}
return sb.toString();
}
private static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for ( int j = 0; j < bytes.length; j++ ) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return String.valueOf(hexChars);
}
Does anyone know of a faster way in Java?

- 981
- 2
- 11
- 18
In Java 8
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Scanner;
import javax.xml.bind.DatatypeConverter;
Scanner scanner = new Scanner(System.in);
String password = scanner.nextLine();
scanner.close();
MessageDigest digest = null;
try {
digest = MessageDigest.getInstance("SHA-256");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
byte[] hash = digest.digest(password.getBytes(StandardCharsets.UTF_8));
String encoded = DatatypeConverter.printHexBinary(hash);
System.out.println(encoded.toLowerCase());

- 2,402
- 1
- 21
- 40
This was my approach using Kotlin:
private fun getHashFromEmailString(email : String) : String{
val charset = Charsets.UTF_8
val byteArray = email.toByteArray(charset)
val digest = MessageDigest.getInstance("SHA-256")
val hash = digest.digest(byteArray)
return hash.fold("", { str, it -> str + "%02x".format(it)})
}

- 171
- 1
- 7
-
Hi, I have just tried your code because I need to hash a password in Android Studio and your code returns something like this: ```[B@188363e```, not the encrypted password. Plus, it seems to be different each time this function is called. – Oct 31 '19 at 12:39
-
1Fixed, you forgot ```return hash.fold("", { str, it -> str + "%02x".format(it)})``` which returns the encrypted password and not the object itself. – Oct 31 '19 at 12:44
-
1yes you're right, let me update the answer with your fix. Thank you :) – Samuel Luís Oct 31 '19 at 13:32
This is what i have been used for hashing:
String pass = "password";
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
byte hashBytes[] = messageDigest.digest(pass.getBytes(StandardCharsets.UTF_8));
BigInteger noHash = new BigInteger(1, hashBytes);
String hashStr = noHash.toString(16);
Output: 5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8

- 211
- 2
- 5
This method return a left padded String
with zero:
Java 10
and after:
public static String sha256(String text) {
try {
var messageDigest = MessageDigest.getInstance("SHA-256");
var hash = messageDigest.digest(text.getBytes(StandardCharsets.UTF_8));
return String.format("%064x", new BigInteger(1, hash));
}
catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
}
}
Java 8
:
public static String sha256(String text) {
try {
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
byte[] hash = messageDigest.digest(text.getBytes(StandardCharsets.UTF_8));
return String.format("%064x", new BigInteger(1, hash));
}
catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
}
}
BTW, you can use "%064X"
for an uppercase result.
Example:
System.out.println(sha256("hello world 1"));
063dbf1d36387944a5f0ace625b4d3ee36b2daefd8bdaee5ede723637efb1cf4
Comparison to Linux cmd:
$ echo -n 'hello world 1' | sha256sum 063dbf1d36387944a5f0ace625b4d3ee36b2daefd8bdaee5ede723637efb1cf4 -

- 3,238
- 22
- 36
You can use MessageDigest in the following way:
public static String getSHA256(String data){
StringBuffer sb = new StringBuffer();
try{
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(data.getBytes());
byte byteData[] = md.digest();
for (int i = 0; i < byteData.length; i++) {
sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
}
} catch(Exception e){
e.printStackTrace();
}
return sb.toString();
}

- 333
- 3
- 14
Here's a method that shows how to hash a String
with the sha-256
algorithm and encode the result in hex
format. This is an often used format to hash and store passwords in a database:
public static String sha256(final String data) {
try {
final byte[] hash = MessageDigest.getInstance("SHA-256").digest(data.getBytes(StandardCharsets.UTF_8));
final StringBuilder hashStr = new StringBuilder(hash.length);
for (byte hashByte : hash)
hashStr.append(Integer.toHexString(255 & hashByte));
return hashStr.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
}
}

- 438
- 3
- 11
- 24
-
Some cases using this approach generates the wrong hash. Try hashing the "abcd" string. The expected is: 88d4266fd4e6338d13b845fcf289579d209c897823b9217da3e161936f031589 ; but it generates 88d4266fd4e6338d13b845fcf289579d209c897823b9217da3e161936f31589 ; missing one zero – Ráfagan May 13 '22 at 19:30
public static String sha256(String s) {
try {
return DatatypeConverter.printHexBinary(MessageDigest.getInstance("SHA-256").digest(s.getBytes(StandardCharsets.UTF_8))).toLowerCase();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}

- 11
- 4
-
1Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 15 '23 at 02:24
In Java, MessageDigest class is used to calculate cryptographic hashing value. This class provides cryptographic hash function ( MD5, SHA-1 and SHA-256) to find hash value of text.
Code example for using SHA-256 algorithm.
public void printHash(String str) throws NoSuchAlgorithmException {
MessageDigest md=MessageDigest.getInstance("SHA-256");
byte[] sha256=md.digest(str.getBytes(StandardCharsets.UTF_8));
for(byte b : sha256){
System.out.printf("%02x",b);
}
}

- 13
- 5
private static String getMessageDigest(String message, String algorithm) {
MessageDigest digest;
try {
digest = MessageDigest.getInstance(algorithm);
byte data[] = digest.digest(message.getBytes("UTF-8"));
return convertByteArrayToHexString(data);
} catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
You can call above method with different algorithms like below.
getMessageDigest(message, "MD5");
getMessageDigest(message, "SHA-256");
getMessageDigest(message, "SHA-1");
You can refer this link for complete application.

- 3,658
- 1
- 36
- 57