Создание хэша SHA1 в библиотеке портативных классов
Я пытаюсь создать портативную библиотеку классов, которая генерирует URL-адреса OAuth для других классов/приложений. Эта библиотека классов, использующая OAuth, должна быть переносимой библиотекой классов, поэтому она может работать с различными версиями API DropBox, которые я создаю.
Часть этого класса должна генерировать хэш SHA1 для генерации oauth_signature с.
Я знаю, что переносимая библиотека классов не поддерживает System.Security.Cryptography, так или иначе, что этот класс может генерировать хэш SHA1 без этого класса?
Ответы
Ответ 1
Mono предоставляет управляемую реализацию SHA1 для своего собственного mscorlib.dll
(но он не находится в Mono.Security.dll
, как предлагается @CodeInChaos).
Он с открытым исходным кодом, очень хорошо протестирован и должен вести себя точно так же, как реализация Microsoft (например, он происходит от SHA1
, HashAlgorith
... реализует ICryptoTransform
...), поэтому он должен быть простым вложением замена.
Ответ 2
Я думаю, что самый простой способ - использовать пакет PCLCrypto nuget. Затем вы можете сделать:
private static string CalculateSha1Hash(string input)
{
// step 1, calculate MD5 hash from input
var hasher = WinRTCrypto.HashAlgorithmProvider.OpenAlgorithm(HashAlgorithm.Sha1);
byte[] inputBytes = Encoding.UTF8.GetBytes(input);
byte[] hash = hasher.HashData(inputBytes);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hash.Length; i++)
{
sb.Append(hash[i].ToString("X2"));
}
return sb.ToString();
}
Ответ 3
Ну, мне тоже было нужно это слишком недавно, и мне было намного легче взять реализацию SHA1 из HashLib: http://hashlib.codeplex.com/
Монореализация имеет некоторые далеко идущие зависимости (локализация исключений и т.д.), а из HashLib вам нужно только скопировать несколько файлов без каких-либо изменений в них:
Converters.cs
Hash.cs
HashBuffer.cs
HashCryptoNotBuildIn.cs
HashResult.cs
IHash.cs
SHA0.cs
SHA1.cs
55 Кбайт кода, поэтому ничего слишком тяжелого.
Ответ 4
Я использовал этот пакет BouncyCastle Nuget: https://www.nuget.org/packages/BouncyCastle-PCL/, и он отлично подходит для меня (кросс-платформы приложение для Windows Store,.Net Framework 4.5, Silverlight 5, Windows Phone 8, Xamarin.Android, Xamarin.iOS)
Используйте HMACSHA1 для создания такой подписи:
public string GenerateSignature(string key, string signatureBase)
{
var keyBytes = Encoding.UTF8.GetBytes(key);
HMACSHA1 hashAlgorithm = new HMACSHA1(keyBytes);
byte[] dataBuffer = Encoding.UTF8.GetBytes(signatureBase);
byte[] hashBytes = hashAlgorithm.ComputeHash(dataBuffer);
return Convert.ToBase64String(hashBytes);
}
Ответ 5
Статья в Википедии SHA-1 содержит псевдокод, который вы могли бы использовать в качестве ориентира для своей собственной реализации. Но, как всегда, с криптографическими функциями, я настоятельно рекомендую использовать проверенную и проверенную реализацию.
Предполагая, что вы хотите реализовать SHA-256, вы можете найти его в BouncyCastle, который доступен в форме исходного кода. Соответствующий класс называется Org.BouncyCastle.Crypto.Digests.Sha256Digest (здесь его источник).
Ответ 6
Возможно, вы захотите проверить новую библиотеку .NET Standard:
https://docs.microsoft.com/en-us/dotnet/articles/standard/library
Он переносимый, и System.Security.Cryptography
включен.
/// <summary>
/// Compute hash for string encoded as UTF8
/// </summary>
/// <param name="input">String to be hashed.</param>
/// <returns>40-character hex string.</returns>
public static string GetSha1(string input)
{
using (var sha1 = System.Security.Cryptography.SHA1.Create())
{
byte[] inputBytes = Encoding.UTF8.GetBytes(input);
byte[] hash = sha1.ComputeHash(inputBytes);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hash.Length; i++)
{
sb.Append(hash[i].ToString("X2"));
}
return sb.ToString();
}
}
Вы также можете получить некоторую помощь (для создания проекта PCL с .NET Standard Library):
https://xamarinhelp.com/dot-net-standard-pcl-xamarin-forms/
Ответ 7
Мне также нужен знак OAuth, и я смотрю на PCL Crypto - этот тест показывает создание хеша HmacSha1 и сравнивает результат со стандартным способом .NET Framework.
[Test]
public void CreateHash_VersusComputeHash_ReturnsEquivalent()
{
// USING TRADITIONAL .NET:
var key = new byte[32];
var contentBytes = Encoding.UTF8.GetBytes("some kind of content to hash");
new RNGCryptoServiceProvider().GetBytes(key);
var alg = new HMACSHA1(key); // Bouncy castle usage does not differ from this
var result = alg.ComputeHash(contentBytes);
// USING PCL CRYPTO:
var algorithm = WinRTCrypto.MacAlgorithmProvider.OpenAlgorithm(MacAlgorithm.HmacSha1);
byte[] mac;
using (var hasher = algorithm.CreateHash(key))
{
hasher.Append(contentBytes);
mac = hasher.GetValueAndReset();
}
// Assert results:
Assert.AreEqual(result.Length, mac.Length);
for (var i = 0; i < result.Length; i++)
{
Assert.AreEqual(result[i], mac[i]);
}
}
Ответ 8
Это работало для меня, когда мне приходилось добиваться того же результата. Вы можете сделать это с помощью SHA512
и других.
using System.Security.Cryptography;
public static string HashSHA1(this string value)
{
using (var sha = SHA1.Create())
{
return Convert.ToBase64String(sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes(value)));
}
}
Код, цитируемый: https://xamarinhelp.com/cryptography-in-xamarin-forms/