Android HMAC SHA512负字节

时间:2018-07-29 12:43:22

标签: java android byte hmac sha

您好,我正在尝试创建对Api的Http请求,该请求需要对数据SHA512进行加密。我在C#中制作了相同的示例,但仍然有效。在Android Java中,我无法复制哈希并向WebApi进行身份验证。我认为问题是

mac.doFinal(byteData);

正在创建带有负值的字节数组。在C#中,没有负数。 这是我的代码。请告诉我我在做什么错:

public static String calculateHMAC(String secret, String data) {
    byte[] byteSecret = secret.getBytes(StandardCharsets.UTF_8);
    byte[] byteData = data.getBytes(StandardCharsets.UTF_8);

    try {
        SecretKeySpec signingKey = new SecretKeySpec(byteSecret,    "HmacSHA512");
        Mac mac = Mac.getInstance("HmacSHA512");

        mac.init(signingKey);
        byte[] rawHmac = mac.doFinal(byteData); // -> Here Java makes rawMac with negative bytes
        return byteArrayToString(rawHmac);
    } catch (GeneralSecurityException e) {
        throw new IllegalArgumentException();
    }

}

private static String byteArrayToString(byte[] bytes) {

    StringBuilder sb = new StringBuilder();

    for(byte b : bytes){
        sb.append(Integer.toHexString(0xff & b));
    }
    return sb.toString();

}

预先感谢

2 个答案:

答案 0 :(得分:0)

在Java中没有无符号类型,因此您不能避免二进制数据中的负值。没问题。

您遇到的一个问题是byteArrayToString()toHexString()不会用零左键填充,因此值0..15不会输出两个字符,而只会输出一个字符。我会改用String.format("%02x", b)之类的东西。另请参阅:How to convert a byte array to a hex string in Java?

答案 1 :(得分:0)

也许我的Http Post请求做错了。它需要HMAC SHA512加密。这是我的测试代码:

public void postInfo() {
    String mApiKey = "$2y$10$6qyl9aYyT.3EV9uue5yup.eM6k1A9O98ZuZMYd0JBl5dbKRYNAF16";
    String mApiPin = "377eac53887e1cff2c7ff999";

    String params = "method=info&time=" + String.valueOf(System.currentTimeMillis() / 1000);

    final HttpClient httpclient = new DefaultHttpClient();
    final HttpPost httppost = new HttpPost(ApiEndPoint.ENDPOINT);

    try {
        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);

        nameValuePairs.add(new BasicNameValuePair("method", "info"));
        nameValuePairs.add(new BasicNameValuePair("time", String.valueOf(System.currentTimeMillis() / 1000)));

        httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

        String hmac = HMAC.hash(mApiKey, params);

        httppost.addHeader("key", mApiKey);
        httppost.addHeader("hash", hmac);

        AsyncTask.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    HttpResponse response = httpclient.execute(httppost);

                    HttpEntity entity = response.getEntity();

                    String content = EntityUtils.toString(entity); // Here it outputs that sign is incorrect

                    return;
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        });

        return;

    } catch (IOException e) {
        // TODO Auto-generated catch block
    }
}

public static String hash(String key, String msg) {
    byte[] returnVal = null;
    try {
        SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "HmacSHA512");
        Mac mac = Mac.getInstance("HmacSHA512");
        mac.init(signingKey);
        returnVal = mac.doFinal(msg.getBytes(StandardCharsets.UTF_8));
    }
    catch (Exception ex) {
        throw ex;
    }
    finally {
        return convertToHex(returnVal);
    }
}