不要这样做:
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输出:
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.enpreBytes(rawHmac)); }}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=



