[英]Issue regarding Hmac SHA256 in different programming languages
嘗試在不同的編程語言中集成HMACSHA256(哈希)時遇到問題。 我嘗試使用Java和C#中的標准預定義方法來實現標准算法,並且使用不同的語言會得到不同的結果。 請在下面查看我在Java和C#中的實現:
Java的:
public static String convertSHAWithSalt(String value, String salt)
throws NoSuchAlgorithmException, InvalidKeyException {
String data = "";
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(salt.getBytes(StandardCharsets.UTF_8));
byte[] bytes = md.digest(value.getBytes(StandardCharsets.UTF_8));
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1));
}
data = sb.toString();
System.out.println(data);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
字符串值'abcd'和空鹽值的結果: 88d4266fd4e6338d13b845fcf289579d209c897823b9217da3e161936f031589
C#:
public static string createHash(string message, string secret)
{
byte[] keyByte = System.Text.Encoding.UTF8.GetBytes(secret);
byte[] messageBytes = System.Text.Encoding.UTF8.GetBytes(message);
HMACSHA256 hmacsha256 = new HMACSHA256(keyByte);
byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
return BitConverter.ToString(hashmessage).Replace("-", "").ToLower();
}
字符串值'abcd'和空鹽值的結果: 527ff4c28c22a090fe39908139363e81b8fb10d0695a135518006abfa21cf5a2
請說明為什么兩個結果都不同。 我也在Java中嘗試了以下實現,但不適用於空鹽值:
public static String convertSHAWithSalt(String value, String salt)
throws NoSuchAlgorithmException, InvalidKeyException {
String data = "";
Mac sha256Hmac = Mac.getInstance("HmacSHA256");
SecretKeySpec secretkey = new SecretKeySpec(salt.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
sha256Hmac.init(secretkey);
data = bytesToHex(sha256Hmac.doFinal(data.getBytes(StandardCharsets.UTF_8)));
System.out.println(data);
}
SHA-256
和HMAC-SHA-256
之間有區別 。 HMAC-SHA-256
(另請參見HMAC
)是一種使用SHA-256
-hash算法生成MAC
的算法。
第一個Java代碼和C#代碼的結果不同,因為Java代碼使用SHA-256
和C#代碼HMAC-SHA-256
。
由於您要使用HMAC-SHA-256
我將重點放在此方面,而忽略第一個Java代碼。
文本的C#代碼結果
This is an arbitrary text!
用鑰匙
1234567890
是
25583e6e0b6c2c3a5c50ebd9ea48138a960a7ca2a215fae2b4b82ee99734deb4
第二個Java代碼也使用HMAC-SHA-256
。 如果您更換線
data = bytesToHex(sha256Hmac.doFinal(data.getBytes(StandardCharsets.UTF_8)));
System.out.println(data);
同
data = bytesToHex(sha256Hmac.doFinal(value.getBytes(StandardCharsets.UTF_8)));
return data;
然后,輸出是相同的(前提是您的(未發布的) bytesToHex
方法以正確的方式工作,請參見例如, 如何在Java中將字節數組轉換為十六進制字符串? )。
順便說一句,在第二個Java代碼中,您應該將標簽的salt
更改為類似於key
因為這是MAC
上下文中的常用措辭。 鹽通常與第一個Java代碼中的密碼哈希結合使用。
注意:在Java代碼中,不允許將空字節數組用作SecretKeySpec
-input。 這將引發IllegalArgumentException (Empty key)
。 但是,C#代碼中的HMACSHA256
-ctor接受一個空字節數組,並在內部用0值填充。 因此,關於您的測試用例(文本: abcd
,空鍵),您可以用包含單個0值的字節數組在Java代碼中模擬空字節數組。 然后,Java代碼的輸出等於C#代碼的輸出。 當然,空鍵只能用於該測試用例。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.