How do I generate a hash code with hash sha256 in java? - java

I would like to know the code to do this in java please?
This is what i have so far but it does not work?
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import static jdk.nashorn.tools.ShellFunctions.input;
public class Sha256hash
{
public static String main(String[] args) throws NoSuchAlgorithmException
{
MessageDigest md = MessageDigest.getInstance("SHA1");
md.reset();
byte[] buffer = input.getBytes("UTF-8");
md.update(buffer);
byte[] digest = md.digest();
String hexStr = "";
for (int i = 0; i < digest.length; i++) {
hexStr += Integer.toString( ( digest[i] & 0xff ) + 0x100, 16).substring( 1 );
}
return hexStr;
}
}

I'm still unclear whether you want SHA-1 or SHA-256, so let's abstract the problem; firstly, an encode method to take a byte[] and return the hex (don't worry, you already wrote it; but I would prefer a StringBuilder over String concatenation. Java String is immutable, so you're creating garbage for later garbage collection with +) -
private static String encodeHex(byte[] digest) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < digest.length; i++) {
sb.append(Integer.toString((digest[i] & 0xff) + 0x100, 16).substring(1));
}
return sb.toString();
}
Next, we can create a method that takes the algorithm name and the String to digest and returns that digest. Like
public static String digest(String alg, String input) {
try {
MessageDigest md = MessageDigest.getInstance(alg);
byte[] buffer = input.getBytes("UTF-8");
md.update(buffer);
byte[] digest = md.digest();
return encodeHex(digest);
} catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
e.printStackTrace();
return e.getMessage();
}
}
Then we can get a SHA-1 or a SHA-256 hash like
public static void main(String[] args) {
System.out.println(digest("SHA1", ""));
System.out.println(digest("SHA-256", ""));
}
Which outputs (as expected)
da39a3ee5e6b4b0d3255bfef95601890afd80709
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

The main entry point can not return String. Furthermore, input is not declared. You maybe want to change the name of your function to generate with input as a parameter.
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import static jdk.nashorn.tools.ShellFunctions.input;
public class Sha256hash
{
public static String generate(String input) throws NoSuchAlgorithmException
{
MessageDigest md = MessageDigest.getInstance("SHA1");
md.reset();
byte[] buffer = input.getBytes("UTF-8");
md.update(buffer);
byte[] digest = md.digest();
String hexStr = "";
for (int i = 0; i < digest.length; i++) {
hexStr += Integer.toString( ( digest[i] & 0xff ) + 0x100, 16).substring( 1 );
}
return hexStr;
}
}
This example works for me returning c3499c2729730a7f807efb8676a92dcb6f8a3f8f as result of processing the string example:
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class Sha256hash
{
public static String generate(String input) throws NoSuchAlgorithmException, UnsupportedEncodingException
{
MessageDigest md = MessageDigest.getInstance("SHA1");
md.reset();
byte[] buffer = input.getBytes("UTF-8");
md.update(buffer);
byte[] digest = md.digest();
String hexStr = "";
for (int i = 0; i < digest.length; i++) {
hexStr += Integer.toString( ( digest[i] & 0xff ) + 0x100, 16).substring( 1 );
}
return hexStr;
}
}
Main:
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
public class Tester {
public static void main(String[] args) throws NoSuchAlgorithmException, UnsupportedEncodingException {
String someText = "example";
System.out.println(Sha256hash.generate(someText));
}
}
Finally, as Elliott has pointed out If you want to use SHA-256 you should change MessageDigest.getInstance("SHA1"); to MessageDigest.getInstance("SHA256"); Right now you are using SHA-1. Also pointed by Elliot you should use StringBuilder in the loop for improved efficiency.

Related

AES/CBC/PKCS5Padding Encryption result different in PHP and Java

I am developing a REST API in which the data to be passed to the server need to be encrypted with 'AES/CBC/PKCS5Padding'. The REST API client side is using Java to encrypt and decrypt the data, while on my side I am using PHP.
The secret key used here is hash with sha1. I have the same secret key value with the client side and also the IV value is the same, but when I try to encrypt and compare it to the client, it's different.
JAVA Code:
import java.util.Arrays;
import java.security.*;
import java.io.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import java.lang.Object;
class Main {
public static String stringToHex(String base)
{
StringBuffer buffer = new StringBuffer();
int intValue;
for(int x = 0; x < base.length(); x++)
{
int cursor = 0;
intValue = base.charAt(x);
String binaryChar = new String(Integer.toBinaryString(base.charAt(x)));
for(int i = 0; i < binaryChar.length(); i++)
{
if(binaryChar.charAt(i) == '1')
{
cursor += 1;
}
}
if((cursor % 2) > 0)
{
intValue += 128;
}
buffer.append(Integer.toHexString(intValue) + " ");
}
return buffer.toString();
}
public static String bytesToHex(byte[] a) {
StringBuilder sb = new StringBuilder(a.length * 2);
for(byte b: a)
sb.append(String.format("%02x", b));
return sb.toString();
}
public static void main(String[] args) throws NoSuchAlgorithmException, UnsupportedEncodingException,
InvalidAlgorithmParameterException,
NoSuchProviderException,
NoSuchPaddingException,
InvalidKeyException,
IllegalBlockSizeException,
BadPaddingException
{
MessageDigest sha = MessageDigest.getInstance("SHA-1");
String secretKey = "mysecretkey102018";
String message = "00155001C"
byte[] key = sha.digest(secretKey.getBytes("UTF-8"));
byte[] value = message.getBytes();
key = Arrays.copyOf(key, 16);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
IvParameterSpec iv = new IvParameterSpec("AAAAAAAAAAAAAAAA".getBytes("UTF-8"));
cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
System.out.println(bytesToHex(cipher.doFinal(value)));
}
PHP Code:
class IDebit
{
private $iv = "AAAAAAAAAAAAAAAA";
private $secret_key = "mysecretkey102018";
private $message = "00155001C";
public function generateEncrytedKeyId()
{
$hashPassword = substr(hash("SHA1", $secret_key), 0, 32);
$blocksize = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$str = $this->pkcs5_pad($message, $blocksize);
$encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $hashPassword, $str, MCRYPT_MODE_CBC, self::IV);
return bin2hex($encrypted);
}
protected function pkcs5_pad($text, $blocksize)
{
$pad = $blocksize - (strlen($text) % $blocksize);
return $text . str_repeat(chr($pad), $pad);
}
}
The encryption result on Java is c1e7af770d9d0af59cc75d1c76aa78f6, while on PHP is d67a15a027be7e7ab68ea6ab88ea4f2f
I'm wondering what is wrong with my code. I have googled and check on this forum about the question dozens of times but I am unable to get the same result. I have rechecked my code with the answers posted by people on this forum and it's identical.

wrong calculatin of sha256 hash in android

I have a problem generating a correct hash for a given string by android studio. I have read a lot of solutions without understanding how to convert it the right way.
I need the correct hash since i am making an HTTP request with it.
Here is my code in JAVA:
public String getHash(final String appSecret , final String sessionToken)throws NoSuchAlgorithmException ,UnsupportedEncodingException{
String input = sessionToken + appSecret;
MessageDigest digest = MessageDigest.getInstance("SHA-256");
digest.reset();
byte[] byteData = digest.digest(input.getBytes("UTF-8"));
StringBuffer sb = new StringBuffer();
for (int i = 0; i < byteData.length; i++){
sb.append(String.format("%02x", 0xFF & byteData[i]));
}
return sb.toString();
}
For an input like:
1130_11825_253402300799_1_1bcb4a27d42524de11325ec627b63878770a8651c0a0d8ddfc8fc06b92aea281634ff11f7d874c03851932304601439e
I need the exact output:
01a9d698f0587a25ad8ef56b0994ec0022364aff91d668a4b3a4b97c40167672
but i got a wrong output:
a60f61b5e9f832b153a91e8d2b1ffa28b9611b2d60c3669663cfe050ac8e28cc
I think my problem is how to read/print the string but i can't figure out how to correct it.
I know that an online hash calculator return a correct hash.
Thanks.
import static org.junit.Assert.assertEquals;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import org.junit.Test;
public class Sha256Test {
#Test
public void sha256Test() throws NoSuchAlgorithmException {
String out = hash256("1130_11825_253402300799_1_1bcb4a27d42524de11325ec627b63878770a8651c0a0d8ddfc8fc06b92aea281634ff11f7d874c03851932304601439e");
String in = "01a9d698f0587a25ad8ef56b0994ec0022364aff91d668a4b3a4b97c40167672";
assertEquals(in, out);
}
private String hash256(String data) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(data.getBytes());
return bytesToHex(md.digest());
}
private String bytesToHex(byte[] bytes) {
StringBuffer result = new StringBuffer();
for (byte byt : bytes) {
result.append(Integer.toString((byt & 0xff) + 0x100, 16).substring(1));
}
return result.toString();
}
}
See: https://gist.github.com/avilches/750151
I modified getHash to take a a single String, I removed the call to reset() and you to finish digest(). I also prefer the for each loop. Like,
public static String getHash(final String msg) {
StringBuilder sb = new StringBuilder();
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
digest.update(msg.getBytes());
byte[] byteData = digest.digest();
for (byte x : byteData) {
String str = Integer.toHexString(Byte.toUnsignedInt(x));
if (str.length() < 2) {
sb.append('0');
}
sb.append(str);
}
} catch (Exception e) {
e.printStackTrace();
}
return sb.toString();
}
And call it like
public static void main(String[] args) {
String out = getHash("1130_11825_253402300799_1_1bcb4a27d42524de11325ec627b63878770a8651c0a0d8ddfc8fc06b92aea281634ff11f7d874c03851932304601439e");
String expected = "01a9d698f0587a25ad8ef56b0994ec0022364aff91d668a4b3a4b97c40167672";
System.out.println(out.equals(expected));
}
I get
true

converting string to md5 gives add number of digits

I am trying to convert a String to its MD5 representation with this code:
public static void main(String[] args) throws NoSuchAlgorithmException {
String s = "oshai";
MessageDigest m = MessageDigest.getInstance("MD5");
m.update(s.getBytes(),0,s.length());
String md5 = new BigInteger(1,m.digest()).toString(16);
System.out.println(md5.length());
}
The returned String has add number of digits (31, so it can be an Hex number). What am I doing wrong?
You don't want to use BigInteger. Try a more traditional toHexString method..
public static void main(String[] args) throws NoSuchAlgorithmException {
String s = "oshai";
MessageDigest m = MessageDigest.getInstance("MD5");
m.update(s.getBytes(),0,s.length());
String string = toHexString(m.digest());
System.out.println(string);
}
public static String toHexString(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for(byte b : bytes) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
This method works for sure:
private String hashWithMD5(String text) throws UnsupportedEncodingException, NoSuchAlgorithmException {
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
byte[] digest = messageDigest.digest(text.getBytes("UTF-8"));
StringBuilder sb = new StringBuilder();
for (int i = 0; i < digest.length; i++) {
sb.append(Integer.toString((digest[i] & 0xff) + 0x100, 16).substring(1));
}
return sb.toString();
}
I have faced an error with missing "00" at the left side, while converting string to the encrypted format.
Normally you won't find the bug in your app by using the common md5 method.
So, please test your app with the string "sandeep" (I have used it because it has a "00" at left side).
This issue messed my hours and finally i found the following solution from a link.
"I had an error with md5 string with 00 at leftside, ie, a string “sandeep” converted to “DCF16D903E5890AABA465B0B1BA51F ” than the actual “00DCF16D903E5890AABA465B0B1BA51F
I ended up with this method, that work cool in my app."
public static String md5(String inputString) {
try {
// Create MD5 Hash
MessageDigest msgDigest = java.security.MessageDigest.getInstance("MD5");
msgDigest.update(inputString.getBytes());
byte msgDigestBytes[] = msgDigest.digest();
// Create Hex String
StringBuffer hexString = new StringBuffer();
for (int i = 0; i < msgDigestBytes.length; i++) {
String h = Integer.toHexString(0xFF & msgDigestBytes[i]);
while (h.length() < 2)
h = "0" + h;
hexString.append(h);
}
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
Ref:http://www.coderexception.com/CbHuB1uHPWxXUQXi/converting-string-to-md5-gives-add-number-of-digits
use this method :
public static String md5(String input) {
String md5 = null;
if (null == input)
return null;
try {
// Create MessageDigest object for MD5
MessageDigest digest = MessageDigest.getInstance("MD5");
// Update input string in message digest
digest.update(input.getBytes(), 0, input.length());
// Converts message digest value in base 16 (hex)
md5 = new BigInteger(1, digest.digest()).toString(16);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return md5;
}

rc4 encryption and decryption in java

I have tried working on the RC4 encryption and decryption procedure. I keep getting an error with the code line s2=key.charAt(j++).
The debugger tells me that it cannot be resolved from char to int.
The output runs untill entering the keystream. The XOR operation is not working out.
Can anyone point out a possible solution?
import java.util.Scanner;
public class Rc4
{
//global
public static int SIZE=256;
public static int[] s1 = new int[SIZE+1]; //filled with random numbers
public static int[] s2 = new int[SIZE+1]; //filled with keytext
public static int i,j;
public static String key, input;
public static void main(String[] args)
{
Scanner keyboard= new Scanner(System.in);
System.out.print("En/Decrypt:");
input = keyboard.nextLine();
System.out.print("Enter key :");
key = keyboard.nextLine();
INIT();
KSA();
}
static void INIT()
{
j=0;
for(i=0; i<SIZE; i++)
{
if(j==key.length())
j=0;
s2= key.charAt(j++);
}
}
static void KSA()
{
for( i=0; i<SIZE; i++)
s1[i]=i;
j=0;
for(int i=0; i<SIZE; i++)
{
j = (j + s1[i] + s2[i]) % SIZE;
swap(i, j);
}
}
static void PRGA()
{
int Rand=0;
//print();
j=i=0;
for(int x = 0; x< input.length(); x++)
{
i = (i + 1) % SIZE;
j = (j + s1[i]) % SIZE;
swap(i, j);
Rand = (char)s1[ ((s1[i] + s1[j]) % SIZE)];
System.out.print((char)(input.charAt(x) ^ Rand) );
}
}
static void print()
{
System.out.print("\n");
for(int y=0; y<input.length(); y++)
{
System.out.print(input.charAt(y));
}
System.out.print("\n");
}
static void swap(int i, int j)
{
int temp = s1[i];
s1[i]= s1[j];
s1[j] = temp;
}
}
You can use Hex and binary conversion of org.bouncycastle api for achieving the conversions without encoding issues. Built in crypto api can do the encryption/decryption for you.
Something like this:
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import org.apache.commons.codec.DecoderException;
import org.bouncycastle.util.encoders.Hex;
public class RC4Algo {
public static void main(String args[])throws IOException, NoSuchAlgorithmException, DecoderException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException
{
decryptRC4();
}
static String decryptRC4() throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException{
byte[] plainBytes = "testString".getBytes();
String hashedKey = hashedData("thisismysecretkey");
//Generate a new key using KeyGenerator
/*KeyGenerator rc4KeyGenerator = KeyGenerator.getInstance("RC4");
SecretKey key = rc4KeyGenerator.generateKey();*/
Key key = new SecretKeySpec(Hex.decode(hashedKey), "RC4"); //String to key conversion using Hex.decode to convert to byte []
// Create Cipher instance and initialize it to encrytion mode
Cipher cipher = Cipher.getInstance("RC4"); // Transformation of the algorithm
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] cipherBytes = cipher.doFinal(plainBytes);
String encoded = encodeBase64(cipherBytes);
String decoded = decodeBase64(encoded);
// Reinitialize the Cipher to decryption mode
cipher.init(Cipher.DECRYPT_MODE,key, cipher.getParameters());
byte[] plainBytesDecrypted = cipher.doFinal(Hex.decode(decoded));
System.out.println("Decrypted Data : "+new String(plainBytesDecrypted));
return new String(plainBytesDecrypted);
}
static String decodeBase64(String encodedData){
byte[] b = Base64.getDecoder().decode(encodedData);
String decodedData = DatatypeConverter.printHexBinary(b);
return decodedData;
}
static String encodeBase64(byte[] data){
byte[] b = Base64.getEncoder().encode(data);
String encodedData = new String(b);
/*String encodedData = DatatypeConverter.printHexBinary(b);*/
return encodedData;
}
static String hashedData(String key) throws NoSuchAlgorithmException{
String password = key;
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(password.getBytes());
byte byteData[] = md.digest();
//convert the byte to hex format method 1
StringBuffer sb = new StringBuffer();
for (int i = 0; i < byteData.length; i++) {
sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
}
//convert the byte to hex format method 2
StringBuffer hexString = new StringBuffer();
for (int i=0;i<byteData.length;i++) {
String hex=Integer.toHexString(0xff & byteData[i]);
if(hex.length()==1) hexString.append('0');
hexString.append(hex);
}
return hexString.toString();
}
}
Tip: Use Hex to binary and vice versa conversions to get rid of encoding issues.
Output:
Hope this helps!
RC4 is a byte-oriented algorithm. Java characters are not bytes. But you can convert strings to and from byte arrays as needed. You're welcome to check out my implementation here.
For the conversion to a string with UTF-8 encoding:
new String(bytes, "UTF-8");
and to a byte array:
str.getBytes("UTF-8");
or use a CharsetEncoder if you're not using a simple encoding like UTF-8.

How to hash some String with SHA-256 in Java?

How can I 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));
I think that the easiest solution is to use Apache Common Codec:
String sha256hex = org.apache.commons.codec.digest.DigestUtils.sha256Hex(stringText);
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();
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);
}
}
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);
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();
}
}
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;
}
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.
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());
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)})
}
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
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?
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 -
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();
}
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;
}
}
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;
}
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);
}
}
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.

Categories

Resources