Android Java 和 PHP HASH HMAC SHA256 不同的结果
Android Java and PHP HASH HMAC SHA256 different result
我在 stack-overflow 中看到了一些相同的问题,但没有找到答案。
Android Java:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Base64;
import android.util.Log;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
private String hash_hmac(String str, String secret) throws Exception{
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
byte[] string = str.getBytes();
String stringInBase64 = Base64.encodeToString(string, Base64.DEFAULT);
SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
sha256_HMAC.init(secretKey);
String hash = Base64.encodeToString(sha256_HMAC.doFinal(stringInBase64.getBytes()), Base64.DEFAULT);
return hash;
}
String str = "1234";
String key = "1234";
try {
Log.d("HMAC:", hash_hmac(str,key));
} catch (Exception e) {
Log.d("HMAC:","stop");
e.printStackTrace();
}
结果:
UHWlHiPrOxxncJTagnlvVcln3xKZ1PKaojFeTMDLXws=
并且在PHP代码中:
$str=base64_encode('1234');
$key='1234';
print(base64_encode(hash_hmac('sha256', $str, $key,true)));
结果:
FBp7PnSG4MQNgcFWAjjlkxNdiqivrmNfnRZur1Dko2Q=
如您所见,我得到了不同的结果。我做错了什么?
PS。正如我们所说,我编辑代码,但这对我没有帮助。请解释,为什么我有不同的结果?
你有2种方法可以解决:
删除第 1 行中的 base_encode
$str='eyJoYXNoIjoic29tZVJlcUhhc2hTdHIiLCJhbnN3ZXIiOnRydWV9';
删除打印中的base_encode
print(hash_hmac('sha256', $str, $key,true));
Difference is in PHP $str
initialized with base64_encode
but in JAVA you didn't encode during hash_mac
所有你需要在 hash_mac 之前在 JAVA 中用 base64 编码 str
private String hash_hmac(String str, String secret) {
String ss = Base64.encodeToString(str.getBytes("UTF-8"));
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256");
sha256_HMAC.init(secretKey);
String hash1 = Base64.encodeToString(sha256_HMAC.doFinal(ss.getBytes("UTF-8")));
return hash1;
}
Or just change in PHP code to remove base64
in str
initialization
$str='eyJoYXNoIjoic29tZVJlcUhhc2hTdHIiLCJhbnN3ZXIiOnRydWV9';
我解决了!小参数:Base64.NO_WRAP 当我将 base64 字节编码为 base64 到 hmac 时。
Tha Android Java 代码是:
private String hash_hmac_test(String base_string, String key) throws Exception {
try {
Mac mac = Mac.getInstance("HmacSHA256");
SecretKeySpec secret = new SecretKeySpec(key.getBytes("UTF-8"), mac.getAlgorithm());
mac.init(secret);
String base_string_base64 = Base64.encodeToString(base_string.getBytes(), Base64.NO_WRAP);
byte[] digest = mac.doFinal(base_string_base64.getBytes());
//android.util.Base64.encodeT
String retVal = Base64.encodeToString(digest,Base64.DEFAULT);
Log.v(TAG, "String: " + base_string);
Log.v(TAG, "String in Base64: " + base_string_base64);
Log.v(TAG, "key: " + key);
Log.v(TAG, "result: " + retVal);
} catch (Exception e) {
System.out.println(e.getMessage());
}
return "ok";
}
而在 PHP 中的代码是:
base64_encode(hash_hmac('sha256', base64_encode($str), $key,true))
两个结果都很好!
谢谢大家!
我在 stack-overflow 中看到了一些相同的问题,但没有找到答案。
Android Java:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Base64;
import android.util.Log;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
private String hash_hmac(String str, String secret) throws Exception{
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
byte[] string = str.getBytes();
String stringInBase64 = Base64.encodeToString(string, Base64.DEFAULT);
SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
sha256_HMAC.init(secretKey);
String hash = Base64.encodeToString(sha256_HMAC.doFinal(stringInBase64.getBytes()), Base64.DEFAULT);
return hash;
}
String str = "1234";
String key = "1234";
try {
Log.d("HMAC:", hash_hmac(str,key));
} catch (Exception e) {
Log.d("HMAC:","stop");
e.printStackTrace();
}
结果:
UHWlHiPrOxxncJTagnlvVcln3xKZ1PKaojFeTMDLXws=
并且在PHP代码中:
$str=base64_encode('1234');
$key='1234';
print(base64_encode(hash_hmac('sha256', $str, $key,true)));
结果:
FBp7PnSG4MQNgcFWAjjlkxNdiqivrmNfnRZur1Dko2Q=
如您所见,我得到了不同的结果。我做错了什么?
PS。正如我们所说,我编辑代码,但这对我没有帮助。请解释,为什么我有不同的结果?
你有2种方法可以解决:
删除第 1 行中的 base_encode
$str='eyJoYXNoIjoic29tZVJlcUhhc2hTdHIiLCJhbnN3ZXIiOnRydWV9';
删除打印中的base_encode
print(hash_hmac('sha256', $str, $key,true));
Difference is in PHP
$str
initialized withbase64_encode
but in JAVA you didn't encode duringhash_mac
所有你需要在 hash_mac 之前在 JAVA 中用 base64 编码 str
private String hash_hmac(String str, String secret) {
String ss = Base64.encodeToString(str.getBytes("UTF-8"));
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256");
sha256_HMAC.init(secretKey);
String hash1 = Base64.encodeToString(sha256_HMAC.doFinal(ss.getBytes("UTF-8")));
return hash1;
}
Or just change in PHP code to remove
base64
instr
initialization
$str='eyJoYXNoIjoic29tZVJlcUhhc2hTdHIiLCJhbnN3ZXIiOnRydWV9';
我解决了!小参数:Base64.NO_WRAP 当我将 base64 字节编码为 base64 到 hmac 时。 Tha Android Java 代码是:
private String hash_hmac_test(String base_string, String key) throws Exception {
try {
Mac mac = Mac.getInstance("HmacSHA256");
SecretKeySpec secret = new SecretKeySpec(key.getBytes("UTF-8"), mac.getAlgorithm());
mac.init(secret);
String base_string_base64 = Base64.encodeToString(base_string.getBytes(), Base64.NO_WRAP);
byte[] digest = mac.doFinal(base_string_base64.getBytes());
//android.util.Base64.encodeT
String retVal = Base64.encodeToString(digest,Base64.DEFAULT);
Log.v(TAG, "String: " + base_string);
Log.v(TAG, "String in Base64: " + base_string_base64);
Log.v(TAG, "key: " + key);
Log.v(TAG, "result: " + retVal);
} catch (Exception e) {
System.out.println(e.getMessage());
}
return "ok";
}
而在 PHP 中的代码是:
base64_encode(hash_hmac('sha256', base64_encode($str), $key,true))
两个结果都很好! 谢谢大家!