HMC SHA1哈希- c#产生与Ruby不同的哈希输出
本文关键字:哈希 Ruby 输出 SHA1 HMC | 更新日期: 2023-09-27 18:06:43
我正试图快速获得一个有bug的。net客户端库为第三方服务,我正在使用的工作。原始库(可以工作)是用Ruby编写的,但是它们的DotNet等效库会向Ruby库产生不同的哈希输出。
Ruby加密代码如下:
def self.encrypt_string(input_string)
raise Recurly::ConfigurationError.new("Recurly gem not configured") unless Recurly.private_key.present?
digest_key = ::Digest::SHA1.digest(Recurly.private_key)
sha1_hash = ::OpenSSL::Digest::Digest.new("sha1")
::OpenSSL::HMAC.hexdigest(sha1_hash, digest_key, input_string.to_s)
end
(假定)等效的c#代码是:
private static string ComputePrivateHash(string dataToProtect)
{
if(String.IsNullOrEmpty(Configuration.RecurlySection.Current.PrivateKey))
throw new RecurlyException("A Private Key must be configured to use the Recurly Transparent Post API.");
byte[] salt_binary = SHA1.Create().ComputeHash(Encoding.ASCII.GetBytes(dataToProtect));
string salt_hex = BitConverter.ToString(salt_binary).Replace("-", "").ToLower();
string salt = salt_hex.Substring(0, 20);
HMACSHA1 hmac_sha1 = new HMACSHA1(Encoding.ASCII.GetBytes(Configuration.RecurlySection.Current.PrivateKey));
hmac_sha1.Initialize();
byte[] private_key_binary = Encoding.ASCII.GetBytes(salt);
byte[] passkey_binary = hmac_sha1.ComputeHash(private_key_binary, 0, private_key_binary.Length);
return BitConverter.ToString(passkey_binary).Replace("-", "").ToLower();
}
给定相同的输入和私钥,实际的哈希输出会有所不同。c#方法有什么问题导致它产生错误的哈希输出?
编辑
这就是I编写代码的方式,尽管它仍然产生错误的输出:
private static string ComputePrivateHash(string dataToProtect)
{
if(String.IsNullOrEmpty(Configuration.RecurlySection.Current.PrivateKey))
throw new RecurlyException("A Private Key must be configured to use the Recurly Transparent Post API.");
var privateKey = Configuration.RecurlySection.Current.PrivateKey;
var hashedData = SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(dataToProtect));
var hmac = new HMACSHA1(Encoding.UTF8.GetBytes(privateKey));
var hash = hmac.ComputeHash(hashedData);
return BitConverter.ToString(hash).Replace("-", "").ToLower();
}
正确答案
感谢下面Henning的回答,我能够确定正确的代码是:
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();
如果我理解这段代码,似乎Ruby代码在将密钥提供给HMAC之前分别对其进行了散列(这在密码学上不应该是必要的,因为HMAC在必要时自己会散列一个长密钥),并将散列密钥与原始消息一起提供给HMAC。
另一方面,你的c#代码用消息的原始键和散列来计算HMAC。(令人费解的是,存储哈希消息的变量被称为salt
和private_key_binary
,尽管内容既不是盐也不是键…)
我无法想象Ruby和c#库对HMAC的处理会如此不同,所以这是正确的事情。