Verify hash signature against secret java

2.5k views Asked by At

I'm trying to convert the php code below to java. I'm having difficulties comparing the hash. Could someone offer some help. Thanks

Example comes from here https://developers.facebook.com/docs/facebook-login/using-login-with-games/#parsingsr

$secret = "appsecret"; // Use your app secret here

// decode the data
$sig = base64_url_decode($encoded_sig);
$data = json_decode(base64_url_decode($payload), true);

// confirm the signature
$expected_sig = hash_hmac('sha256', $payload, $secret, $raw = true);
if ($sig !== $expected_sig) {

What I've got thus far.

String secret = "somesecret";
String signedRequest = "some.signedrequest";

String[] encoded = signedRequest.split("\\.");

System.out.println(encoded[0]);
System.out.println(encoded[1]);

String signature = base64UrlDecode(encoded[0]);
String payload = base64UrlDecode(encoded[1]);


public static String base64UrlDecode(String input) {
    String result = null;
    Base64 decoder = new Base64(true);
    byte[] decodedBytes = decoder.decode(input);
    result = new String(decodedBytes);
    return result;
}

From here I'm at a loss.

I do not know how to set-up the hash to be compared against my signature.

1

There are 1 answers

3
Honey Goyal On BEST ANSWER

Get some idea from this, this worked for me.

import org.apache.commons.codec.binary.Base64;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

private JSONObject parseFBSignedRequest(String signedRequest, String secret) throws UnsupportedEncodingException, Exception {


    //split request into signature and data
    String[] signedRequests = signedRequest.split("\\.", 2);
    //parse signature
    String sig = signedRequests[0];

    //parse data and convert to json object
    String data = signedRequests[1];

    //I assumed it is UTF8
    JSONObject jsonData = new JSONObject(new String(Base64.decodeBase64(data), "UTF-8"));
    //check signature algorithm
    if(!jsonData.getString("algorithm").equals("HMAC-SHA256")) {
        //unknown algorithm is used
        return null;
    }

    //check if data is signed correctly
    if(!hmacSHA256(signedRequests[1], secret).equals(sig)) {
        //signature is not correct, possibly the data was tampered with
        return null;
    }
    return jsonData;

}

//HmacSHA256 implementation 
private String hmacSHA256(String data, String key) throws Exception {
    SecretKeySpec secretKey = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
    Mac mac = Mac.getInstance("HmacSHA256");
    mac.init(secretKey);
    byte[] hmacData = mac.doFinal(data.getBytes("UTF-8"));
    return new String(Base64.encodeBase64URLSafe(hmacData), "UTF-8");
}