I'm trying to get the SHA256 of a string in Android.
Here is the PHP code that I want to match:
echo bin2hex(mhash(MHASH_SHA256,"asdf")); //outputs "f0e4c2f76c58916ec258f246851bea091d14d4247a2fc3e18694461b1816e13b"
Now, in Java, I'm trying to do the following:
String password="asdf" MessageDigest digest=null; try { digest = MessageDigest.getInstance("SHA-256"); } catch (NoSuchAlgorithmException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } digest.reset(); try { Log.i("Eamorr",digest.digest(password.getBytes("UTF-8")).toString()); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); }
But this prints out: "a42yzk3axdv3k4yh98g8"
What did I do wrong here?
Solution thanks to erickson:
Log.i("Eamorr",bin2hex(getHash("asdf"))); public byte[] getHash(String password) { MessageDigest digest=null; try { digest = MessageDigest.getInstance("SHA-256"); } catch (NoSuchAlgorithmException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } digest.reset(); return digest.digest(password.getBytes()); } static String bin2hex(byte[] data) { return String.format("%0" + (data.length*2) + "X", new BigInteger(1, data)); }
For SHA-256 these are calculated from the first 8 primes. These always remain the same for any message. The primes are firstly square rooted and then taken to the modulus 1. The result is then multiplied by 16⁸ and rounded down to the nearest integer.
The only way to check if a hash is a valid SHA-256 hash is to check 256 bits in it- if it does, then yes some input CAN possibly generate that output. Hashes are one way meaning I can give you a hash and you can never decrypt it (this is the difference between hashing and an encryption).
It's always 64 characters, which can be determined by running anything into one of the online SHA-256 calculators.
Yes, a SHA256 is always 256 bits long, equivalent to 32 bytes, or 64 bytes in an hexadecimal string format. You can even use char(64) instead of varchar(64) since the size won't change. Show activity on this post. Yes, it will always have 64 characters.
The PHP function bin2hex
means that it takes a string of bytes and encodes it as a hexadecimal number.
In the Java code, you are trying to take a bunch of random bytes and decode them as a string using your platform's default character encoding. That isn't going to work, and if it did, it wouldn't produce the same results.
Here's a quick-and-dirty binary-to-hex conversion for Java:
static String bin2hex(byte[] data) { StringBuilder hex = new StringBuilder(data.length * 2); for (byte b : data) hex.append(String.format("%02x", b & 0xFF)); return hex.toString(); }
This is quick to write, not necessarily quick to execute. If you are doing a lot of these, you should rewrite the function with a faster implementation.
You are along the right lines, but converting the bytes is a little more complicated. This works on my device:
// utility function private static String bytesToHexString(byte[] bytes) { // http://stackoverflow.com/questions/332079 StringBuffer sb = new StringBuffer(); for (int i = 0; i < bytes.length; i++) { String hex = Integer.toHexString(0xFF & bytes[i]); if (hex.length() == 1) { sb.append('0'); } sb.append(hex); } return sb.toString(); } // generate a hash String password="asdf"; MessageDigest digest=null; String hash; try { digest = MessageDigest.getInstance("SHA-256"); digest.update(password.getBytes()); hash = bytesToHexString(digest.digest()); Log.i("Eamorr", "result is " + hash); } catch (NoSuchAlgorithmException e1) { // TODO Auto-generated catch block e1.printStackTrace(); }
Source: bytesToHexString function is from the IOSched project.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With