您好,我正在尝试创建对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();
}
预先感谢
答案 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);
}
}