c#和java—hmacsha256哈希之间的差异
我有以下Java代码:c#和java—hmacsha256哈希之间的差异,c#,java,encryption,hmac,sha256,C#,Java,Encryption,Hmac,Sha256,我有以下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[] rawH
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#中的以下代码:
字节数组“secretKey”和“bytes”是等效的,但字节数组“rawHmac”不同,字符串“result”也不同。有人知道为什么吗?不要这样做:
byte[] bytes = data.getBytes();
这将使用平台默认编码将字符串转换为字节数组。这可能因平台而异,而您需要的是可重复的内容。我建议UTF-8:
byte[] bytes = data.getBytes("UTF-8");
(当然,对钥匙也要这样做。)
然后,您应该在C#-而不是ASCII中使用相同的编码,除非您确实不想处理非ASCII字符
byte[] bytes = Encoding.UTF8.GetBytes(data);
还不清楚以后如何比较结果-不要忘记,byte
在Java中是有符号的,但在C中是无符号的。为了便于比较,将哈希转换为十六进制或base64可能是最简单的方法
编辑:我强烈怀疑最后一部分是问题所在——比较结果
下面是两个简短但完整的程序(使用Java中的iharder.net base64转换器),它们生成相同的base64输出:
爪哇:
C#:
来自以下两方面的输出:
ivEyFpkagEoghGnTw/LmfhDOsiNbcnEON50mFGzW9/w=
这不是一个问题,正如所演示的,哈希值总是相同的 我的例子中的问题是不相关的,事实上Java大写字母在UrlEncoder上进行百分比编码,而.NET没有
这说明了单独测试是多么重要 还应该说“data”和“secretKey”是等效的stringsThanks,但正如我所说的,bytes[]在两种语言中包含相同的数字。因此,尽管您的评论很有帮助,但它们并不能解决问题issue@GregT字体他们至少解决了一个问题。也请看我的最后一段-您没有给我们任何关于如何比较这些的指示。如果您可以编辑您的问题,提供两个简短但完整的程序来演示问题,这将使生活更轻松。谢谢,现在就这样做。我不知道字节之间的差异。@GregT:我编辑了答案,以显示简短但完整的程序,这些程序给出了相同的答案。您能否以显示不同答案的方式编辑您的问题?(你给出的代码仍然不完整。)@GregT:现在,你应该可以使用我创建的两个独立程序,并提供一个密钥/数据对来显示差异。
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));
}
}
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=