C#和Java - hmacsha256哈希的区别 [英] c# and java - difference between hmacsha256 hash
问题描述
我在Java中的以下代码:
I have the following code in Java:
byte[] secretKey = secretAccessKey.getBytes("UTF-8");
SecretKeySpec signingKey = new SecretKeySpec(secretKey, "HmacSHA256");
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(signingKey);
byte[] bytes = data.getBytes("UTF-8");
byte[] rawHmac = mac.doFinal(bytes);
String result = javax.xml.bind.DatatypeConverter.printBase64Binary(rawHmac);
和C#中的以下代码:
UTF8Encoding enc = new UTF8Encoding();
byte[] secretKey = enc.GetBytes(secretAccessKey);
HMACSHA256 hmac = new HMACSHA256(secretKey);
hmac.Initialize();
byte[] bytes = enc.GetBytes(data);
byte[] rawHmac = hmac.ComputeHash(bytes);
string result = Convert.ToBase64String(rawHmac);
字节数组SecretKey的和字节是等价的,但该字节数组rawHmac不同以及字符串结果是不同的。 ?任何人都可以看到,为什么
The byte arrays "secretKey" and "bytes" are equivalent but the byte array "rawHmac" is different, and the string "result" is different. Can anyone see why?
推荐答案
不这样做:
byte[] bytes = data.getBytes();
这将使用平台默认的编码字符串转换为字节数组。能而你想要的东西可重复的平台之间变化。我建议UTF-8:
That will use the platform default encoding to convert a string to a byte array. That can vary between platform, whereas you want something repeatable. I would suggest UTF-8:
byte[] bytes = data.getBytes("UTF-8");
(做的关键是相同的,当然。)
(Do the same for the key, of course.)
您应该然后使用相同的编码在C# - 的不的ASCII,除非你真的想不处理非ASCII字符
You should then use the same encoding in your C# - not ASCII, unless you really want to not handle non-ASCII characters.
byte[] bytes = Encoding.UTF8.GetBytes(data);
这也不清楚怎么你算账对比结果 - 不要忘记,字节
在Java的签名,但在C#中的无符号。它可能是最简单的哈希转换为十六进制或Base64出于比较的目的
It's also not clear how you're comparing the results afterwards - don't forget that byte
is signed in Java, but unsigned in C#. It's probably simplest to convert the hash to hex or base64 for comparison purposes.
编辑:我强烈怀疑的最后一部分是问题 - 对比结果
I strongly suspect the last part was the problem - comparing the results.
下面是两个短,但完整的程序(使用Java中的base64 iharder.net转换器)以下生产同类的base64输出:
Here are two short but complete programs (using the iharder.net base64 converter in Java) which produce the same base64 output:
Java的:
import java.util.*;
import javax.crypto.*;
import javax.crypto.spec.*;
public class Test {
public static void main (String[] args) throws Exception {
String secretAccessKey = "mykey";
String data = "my data";
byte[] secretKey = secretAccessKey.getBytes();
SecretKeySpec signingKey = new SecretKeySpec(secretKey, "HmacSHA256");
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(signingKey);
byte[] bytes = data.getBytes();
byte[] rawHmac = mac.doFinal(bytes);
System.out.println(Base64.encodeBytes(rawHmac));
}
}
C#:
C#:
using System;
using System.Security.Cryptography;
using System.Text;
class Test
{
static void Main()
{
String secretAccessKey = "mykey";
String data = "my data";
byte[] secretKey = Encoding.UTF8.GetBytes(secretAccessKey);
HMACSHA256 hmac = new HMACSHA256(secretKey);
hmac.Initialize();
byte[] bytes = Encoding.UTF8.GetBytes(data);
byte[] rawHmac = hmac.ComputeHash(bytes);
Console.WriteLine(Convert.ToBase64String(rawHmac));
}
}
这两个输出:
ivEyFpkagEoghGnTw/LmfhDOsiNbcnEON50mFGzW9/w=
这篇关于C#和Java - hmacsha256哈希的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!