1

This is the have code which i am currently looking into

package com.security;
import java.util.Map;
import javax.xml.bind.DatatypeConverter;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Iterator;

public class Signature {
    private static final String HMAC_SHA256 = "HmacSHA256";
    private static final String SECRET_KEY = "LF8np6Lk0PvQ8yQvOnsqvC5WOnRbLOEadpZOAYd22QNdXnSKI08VXfo6Kl0yV5wx";

    public static String sign(Map<String,String> params) throws InvalidKeyException, NoSuchAlgorithmException, UnsupportedEncodingException {
        return sign(buildDataToSign(params), SECRET_KEY).trim();
    }

    private static String sign(String data, String secretKey) throws InvalidKeyException, NoSuchAlgorithmException, UnsupportedEncodingException {
        SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), HMAC_SHA256);
        Mac mac = Mac.getInstance(HMAC_SHA256);
        mac.init(secretKeySpec);
        byte[] rawHmac = mac.doFinal(data.getBytes("UTF-8"));
        return DatatypeConverter.printBase64Binary(rawHmac).replace("\n", "").trim();
    }

    private static String buildDataToSign(Map<String,String> params) {
        String[] signedFieldNames = String.valueOf(params.get("signed_fields")).split(",");
        ArrayList<String> dataToSign = new ArrayList<String>();
        for (String signedFieldName : signedFieldNames) {
            dataToSign.add(signedFieldName + "=" + String.valueOf(params.get(signedFieldName)).trim());
        }
        return commaSeparate(dataToSign);
    }

    private static String commaSeparate(ArrayList<String> dataToSign) {
        StringBuilder csv = new StringBuilder();
        for (Iterator<String> it = dataToSign.iterator(); it.hasNext(); ) {
            csv.append(it.next());
            if (it.hasNext()) {
                csv.append(",");
            }
        }
        return csv.toString();
    }
}

Here i understand that hmac ashing mechanism is being used and it generates base64 like string in the end.

I am planning to recreate the code in php which suppose to deliver the same output, can someone please explain what's actually happening here.

Thanks in advance.

At the end the above code generates a random string like:

gPRbQMzGGu4ShTwS1NzhzObRWLuGuxvKJuVpSpOaFZk=

Ry Van
  • 311
  • 2
  • 9
  • 1
    check this: [why PHP's hash_hmac(sha256) gives different result than java sha256_HMAC](https://stackoverflow.com/questions/24429734/why-phps-hash-hmacsha256-gives-different-result-than-java-sha256-hmac) – Mert Öksüz Aug 23 '17 at 07:29
  • @MertÖksüz this will be helpful thanks. – Ry Van Aug 23 '17 at 07:38
  • Follow that question: [why-phps-hash-hmacsha256-gives-different-result-than-java-sha256-hmac](https://stackoverflow.com/questions/24429734/why-phps-hash-hmacsha256-gives-different-result-than-java-sha256-hmac) – Mert Öksüz Aug 23 '17 at 07:39
  • 1
    @MertÖksüz, apparently this one line "base64_encode(hash_hmac('sha256', $data, $secret, false));" can accomplish what java does? – Ry Van Aug 23 '17 at 07:44
  • @RyVan It's possible you need to set the last parameter to `true` but the key point to take away here is `hash_hmac` is the equivalent PHP function to do this. – apokryfos Aug 23 '17 at 08:05

0 Answers0