wrong calculatin of sha256 hash in android

1.8k views Asked by At

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.

2

There are 2 answers

1
Elliott Frisch On BEST ANSWER

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
0
Hey StackExchange On
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