【问题标题】:Android HMAC SHA512 Negative ByteAndroid HMAC SHA512 负字节
【发布时间】:2019-01-05 21:44:17
【问题描述】:

您好,我正在尝试创建对 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();

}

提前致谢

【问题讨论】:

    标签: java android byte hmac sha


    【解决方案1】:

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

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

    【讨论】:

    • 感谢您的回答。我也试过这个,但没有帮助。我已经尝试了 Google 上的所有解决方案。它都不起作用。 C# 创建正确的 hmac Sha512 而 java 不创建。我现在不知道该怎么办
    【解决方案2】:

    也许我的 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);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-16
      • 2014-12-04
      • 1970-01-01
      • 1970-01-01
      • 2017-01-11
      • 1970-01-01
      相关资源
      最近更新 更多