Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c#和java—hmacsha256哈希之间的差异_C#_Java_Encryption_Hmac_Sha256 - Fatal编程技术网

c#和java—hmacsha256哈希之间的差异

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

我有以下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#中的以下代码:

字节数组“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=