Java Android HMAC SHA512负字节
您好,我正在尝试创建Http请求到Api,它需要加密数据。我在C#中也做了同样的例子,效果很好。在androidjava中,我无法复制hash并对WebApi进行身份验证。我认为问题在于Java Android HMAC SHA512负字节,java,android,byte,hmac,sha,Java,Android,Byte,Hmac,Sha,您好,我正在尝试创建Http请求到Api,它需要加密数据。我在C#中也做了同样的例子,效果很好。在androidjava中,我无法复制hash并对WebApi进行身份验证。我认为问题在于 mac.doFinal(byteData); 正在创建具有负值的字节数组。C#中没有否定词。 这是我的密码。请告诉我我做错了什么: public static String calculateHMAC(String secret, String data) { byte[] byteSecret =
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中没有无符号类型,因此无法避免二进制数据中出现负值。这不是问题所在
您遇到的一个问题是
byteArrayToString()
toHexString()
不会将pad保留为零,因此值0..15不会输出两个字符,而只输出一个字符。我会使用类似于String.format(“%02x”,b)
的格式。另请参见:可能我的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);
}
}
public void postInfo(){
字符串mApiKey=“$2y$10$6qyl9aYyT.3EV9uue5yup.EM6K1A9O98ZUZYD0JBL5DBKRYNAF16”;
字符串mApiPin=“377eac53887e1cff2c7ff999”;
String params=“method=info&time=“+String.valueOf(System.currentTimeMillis()/1000);
最终HttpClient HttpClient=新的DefaultHttpClient();
最终HttpPost HttpPost=新HttpPost(apidentpoint.ENDPOINT);
试一试{
List nameValuePairs=新的ArrayList(2);
添加(新的BasicNameValuePair(“方法”、“信息”));
添加(新的BasicNameValuePair(“time”,String.valueOf(System.currentTimeMillis()/1000));
setEntity(新的UrlEncodedFormEntity(nameValuePairs));
字符串hmac=hmac.hash(mApiKey,params);
addHeader(“key”,mApiKey);
httppost.addHeader(“哈希”,hmac);
AsyncTask.execute(新的Runnable(){
@凌驾
公开募捐{
试一试{
HttpResponse response=httpclient.execute(httppost);
HttpEntity=response.getEntity();
String content=EntityUtils.toString(entity);//这里它输出符号不正确
返回;
}捕获(IOE异常){
e、 printStackTrace();
}
}
});
返回;
}捕获(IOE异常){
//TODO自动生成的捕捉块
}
}
公共静态字符串哈希(字符串键、字符串消息){
字节[]returnVal=null;
试一试{
SecretKeySpec signingKey=newsecretkeyspec(key.getBytes(StandardCharsets.UTF_8),“HmacSHA512”);
Mac Mac=Mac.getInstance(“HmacSHA512”);
mac.init(签名密钥);
returnVal=mac.doFinal(msg.getBytes(StandardCharsets.UTF_8));
}
捕获(例外情况除外){
掷骰子;
}
最后{
返回convertToHex(returnVal);
}
}
谢谢您的回答。我也试过这个,但没用。我在谷歌上尝试了各种解决方案。这些都不管用。C#创建的hmac Sha512是正确的,java则不是。我不知道现在该怎么办