HMC SHA1哈希 - Java的生产比C#不同的Hash输出 [英] HMC SHA1 hash - Java producing different hash output than C#

查看:901
本文介绍了HMC SHA1哈希 - Java的生产比C#不同的Hash输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个跟进的问题,但我想端口C#代码到Java而不是Ruby代码为C#,就像在相关的问题的情况下。我试图验证加密签名从Recurly.js API返回是有效的。不幸的是,Recurly没有一个Java库,以协助验证,所以我必须实现签名验证自己。

This is a follow up to this question, but I'm trying to port C# code to Java instead of Ruby code to C#, as was the case in the related question. I am trying to verify the encrypted signature returned from the Recurly.js api is valid. Unfortunately, Recurly does not have a Java library to assist with the validation, so I must implement the signature validation myself.

根据以上的相关问题(的this ),下面的C#代码可以生成散列验证来自Recurly返回签名所需:

Per the related question above (this), the following C# code can produce the hash needed to validate the signature returned from Recurly:

var privateKey = Configuration.RecurlySection.Current.PrivateKey;
var hashedKey = SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(privateKey));
var hmac = new HMACSHA1(hashedKey);
var hash = hmac.ComputeHash(Encoding.ASCII.GetBytes(dataToProtect));
return BitConverter.ToString(hash).Replace("-", "").ToLower();



Recurly提供其签名文档页面:

未加密的验证消息
[1312701386,transactioncreate,[ACCOUNT_CODE:ABC,amount_in_cents:5000,货币:美元]

unencrypted verification message: [1312701386,transactioncreate,[account_code:ABC,amount_in_cents:5000,currency:USD]]

私钥
0123456789ABCDEF0123456789ABCDEF

private key: 0123456789ABCDEF0123456789ABCDEF

得到的签名
0f5630424b32402ec03800e977cd7a8b13dbd153-1312701386

resulting signature: 0f5630424b32402ec03800e977cd7a8b13dbd153-1312701386

下面是我的Java实现:

Here is my Java implementation:

String unencryptedMessage = "[1312701386,transactioncreate,[account_code:ABC,amount_in_cents:5000,currency:USD]]";
String privateKey = "0123456789ABCDEF0123456789ABCDEF";
String encryptedMessage = getHMACSHA1(unencryptedMessage, getSHA1(privateKey));

private static byte[] getSHA1(String source) throws NoSuchAlgorithmException, UnsupportedEncodingException{
    MessageDigest md = MessageDigest.getInstance("SHA-1");
    byte[] bytes = md.digest(source.getBytes("UTF-8"));
    return bytes;
}

private static String getHMACSHA1(String baseString, byte[] keyBytes) throws GeneralSecurityException, UnsupportedEncodingException {
    SecretKey secretKey = new SecretKeySpec(keyBytes, "HmacSHA1");
    Mac mac = Mac.getInstance("HmacSHA1");
    mac.init(secretKey);
    byte[] bytes = baseString.getBytes("ASCII");
    return Hex.encodeHexString(mac.doFinal(bytes));
}



然而,当我打印出来的encryptedMessage变量,它不匹配的消息示例性签名的一部分。具体来说,我得到的c8a9188dcf85d1378976729e50f1de5093fabb78而不是0f5630424b32402ec03800e977cd7a8b13dbd153值。

However, when I print out the encryptedMessage variable, it does not match the message portion of the example signature. Specifically, I get a value of "c8a9188dcf85d1378976729e50f1de5093fabb78" instead of "0f5630424b32402ec03800e977cd7a8b13dbd153".

更新

每@ M.Babcock,我重新与示例数据的C#代码,并将其返回的输出作为Java代码相同。因此,它出现在我的散列的做法是正确的,但我传递了错误的数据(unencryptedMessage)。叹。我会更新这个职位,如果/当我能确定正确的数据是 - 作为Recurly文档中提供似乎失去了一些东西在加密验证消息进行加密。

Per @M.Babcock, I reran the C# code with the example data, and it returned the same output as the Java code. So it appears my hashing approach is correct, but I am passing in the wrong data (unencryptedMessage). Sigh. I will update this post if/when I can determine what the correct data to encrypt is- as the "unencrypted verification message" provided in the Recurly documentation appears to be missing something.

更新2

错误竟然是未加密的验证消息数据/格式。在这个例子中数据的消息实际上并没有加密的例子签名设置─所以也许过时的文档?无论如何,我已经确认了Java实现将真实世界的数据。感谢所有。

The error turned out to be the "unencrypted verification message" data/format. The message in the example data does not actually encrypt to the example signature provided- so perhaps outdated documentation? At any rate, I have confirmed the Java implementation will work for real-world data. Thanks to all.

推荐答案

我认为这个问题是在你的.NET代码。是否 Configuration.RecurlySection.Current.PrivateKey 返回一个字符串?是该值你所期望的钥匙吗?

I think the problem is in your .NET code. Does Configuration.RecurlySection.Current.PrivateKey return a string? Is that value the key you expect?

使用下面的代码,.NET和Java返回相同的结果。

Using the following code, .NET and Java return identical results.

.NET代码

string message = "[1312701386,transactioncreate,[account_code:ABC,amount_in_cents:5000,currency:USD]]";
string privateKey = "0123456789ABCDEF0123456789ABCDEF";

var hashedKey = SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(privateKey));
var hmac = new HMACSHA1(hashedKey);
var hash = hmac.ComputeHash(Encoding.ASCII.GetBytes(message));

Console.WriteLine("  Message: {0}", message);
Console.WriteLine("      Key: {0}\n", privateKey);
Console.WriteLine("Key bytes: {0}", BitConverter.ToString(hashedKey).Replace("-", "").ToLower());
Console.WriteLine("   Result: {0}", BitConverter.ToString(hash).Replace("-", "").ToLower());



结果:


  Message: [1312701386,transactioncreate,[account_code:ABC,amount_in_cents:5000,currency:USD]]
      Key: 0123456789ABCDEF0123456789ABCDEF

Key bytes: 4d857d2408b00c3dd17f0c4ffcf15b97f1049867
   Result: c8a9188dcf85d1378976729e50f1de5093fabb78

的Java

String message = "[1312701386,transactioncreate,[account_code:ABC,amount_in_cents:5000,currency:USD]]";
String privateKey = "0123456789ABCDEF0123456789ABCDEF";

MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] keyBytes = md.digest(privateKey.getBytes("UTF-8"));

SecretKey sk = new SecretKeySpec(keyBytes, "HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(sk);
byte[] result = mac.doFinal(message.getBytes("ASCII"));

System.out.println("  Message: " + message);
System.out.println("      Key: " + privateKey + "\n");
System.out.println("Key Bytes: " + toHex(keyBytes));
System.out.println("  Results: " + toHex(result));



结果:


  Message: [1312701386,transactioncreate,[account_code:ABC,amount_in_cents:5000,currency:USD]]
      Key: 0123456789ABCDEF0123456789ABCDEF

Key Bytes: 4d857d2408b00c3dd17f0c4ffcf15b97f1049867
  Results: c8a9188dcf85d1378976729e50f1de5093fabb78

这篇关于HMC SHA1哈希 - Java的生产比C#不同的Hash输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆