HMC SHA1哈希 - Java的生产比C#不同的Hash输出 [英] HMC SHA1 hash - Java producing different hash output than C#
问题描述
这是一个跟进这的问题,但我想端口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屋!