Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/284.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 Base64和HmacSHA256加密_Java_C#_Android_Base64_Sha256 - Fatal编程技术网

C#到Java Base64和HmacSHA256加密

C#到Java Base64和HmacSHA256加密,java,c#,android,base64,sha256,Java,C#,Android,Base64,Sha256,我在C#中有以下代码,它从Base64编码的字符串生成哈希值 var hmacSha256 = new System.Security.Cryptography.HMACSHA256 { Key = Convert.FromBase64String(key) }; string verb = "post"; string resourceType = "docs"; string resourceId = "dbs/ToDoList/colls/Items"; string date = Da

我在C#中有以下代码,它从Base64编码的字符串生成哈希值

var hmacSha256 = new System.Security.Cryptography.HMACSHA256 { Key = Convert.FromBase64String(key) };

string verb = "post";
string resourceType = "docs";
string resourceId = "dbs/ToDoList/colls/Items";
string date = DateTime.UtcNow.ToString("R");

string payLoad = string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}\n{1}\n{2}\n{3}\n{4}\n",
        verb.ToLowerInvariant(),
        resourceType.ToLowerInvariant(),
        resourceId,
        date.ToLowerInvariant(),
        ""
);

byte[] hashPayLoad = hmacSha256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(payLoad));
string signature = Convert.ToBase64String(hashPayLoad);

string authToken = System.Web.HttpUtility.UrlEncode(String.Format(System.Globalization.CultureInfo.InvariantCulture, "type={0}&ver={1}&sig={2}",
    keyType,
    tokenVersion,
    signature));
这工作得非常好,我想将其转换为Android应用程序的Java代码。我查了这些来源的参考资料-

并用Java编写了以下代码-

String restServiceVersion = "2017-02-22";

String verb = "post";
String resourceType = "docs";
String resourceId = "dbs/ToDoList/colls/Items";

String dateString = org.apache.http.impl.cookie.DateUtils.formatDate(new Date(System.currentTimeMillis()));

String gmtIndex = "GMT";
int index = dateString.indexOf(gmtIndex);

String dateStringFinal = dateString.substring(0, index + 3).toLowerCase();

String payLoad = verb +"\n" + resourceType + "\n" + resourceId + "\n" + dateStringFinal + "\n\n";

System.out.println(payLoad);

String secretAccessKey = MASTER_KEY;
String data = payLoad;
byte[] secretKey = Base64.decode(secretAccessKey, Base64.DEFAULT);
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 authToken = "type=master&ver=1.0&sig=" + Base64.encodeToString(rawHmac, Base64.DEFAULT);
Java中生成的
authToken
值与C#不匹配。此外,Base64解码生成的字节数组也不同


我不确定这是不是正确的方法。有人能看一下吗?我所需要的只是将上面的工作C#代码转换为我的Android应用程序的Java。

最可能的解释是:BASE64字符串中嵌入了不可见的unicode字符(例如“零宽度非joiner”)。当base-64解码时,一个平台正在剥离这些数据,而另一个平台则没有,这会导致不同的密钥。

因此这些值不匹配。信息量真大。。。。。如果base64解码后密钥的字节不同,那么sha256哈希肯定也会不同。您是否绝对100%确定源base64编码密钥在这两种情况下是相同的?你能告诉我们,对于给定的输入,你在每个平台下得到的输出是什么吗?(如果您使用的确切密钥仅用于本地测试目的,则可以使用该密钥)。@DylanNicholson是源密钥和其他参数相同。我只是担心我是否正确地构建了它们。我会说,不管密钥是否不同,如果您的输入文本包含基于当前时间的日期,即使在同一平台上,哈希值也总是不同的!您确定
org.apache.http.impl.cookie.DateUtils.formatDate
生成的格式与
.ToString(“R”)
相同吗?但如果你不打算发布更多关于你所看到的东西的信息,我怀疑有人会帮你解决它。@DylanNicholson True。但实际上为了调试,我已经替换并硬编码了相同的日期值。甚至字节数组的初始值-byte[]secretKey=Base64.decode(secretAccessKey,Base64.DEFAULT);与C#-Convert不同。从Base64String(键)考虑到他提供的所有信息(请阅读评论线程上方的内容),这几乎肯定是解释他观察到的行为的唯一答案(注意,从技术上讲,除了“有人能看一下吗?”),没有其他问题)。