Создание хэша 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/