Я пытаюсь быстро получить некорректную клиентскую библиотеку .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 #, из-за которого он выдает неправильный хэш-результат?
РЕДАКТИРОВАТЬ
Это способ Я написал бы код, хотя он все равно дает неправильный результат:
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();
}
ПРАВИЛЬНЫЙ ОТВЕТ
Благодаря приведенному ниже ответу Хеннинга я смог определить, что правильный код:
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();