在可移植类库中生成SHA1哈希

时间:2012-04-20 22:28:57

标签: c# sha1 portable-class-library

我正在尝试构建一个可移植的类库,为其他类/应用程序生成OAuth URL。这个使用OAuth的类库必须是一个可移植的类库,因此它可以使用我正在构建的不同版本的DropBox API。

此类的一部分需要生成SHA1哈希以使用。

生成oauth_signature

我知道可移植类库不支持System.Security.Cryptography,所以无论如何这个类可以生成没有该类的SHA1哈希吗?

9 个答案:

答案 0 :(得分:16)

我认为最简单的方法是使用 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();
}

答案 1 :(得分:8)

我最近也需要这个,我发现更容易从HashLib中获取SHA1实现:http://hashlib.codeplex.com/

Mono实现有一些远程依赖(例外的本地化等),而从HashLib你只需要复制几个文件而不做任何改动:

Converters.cs
Hash.cs
HashBuffer.cs
HashCryptoNotBuildIn.cs
HashResult.cs
IHash.cs
SHA0.cs
SHA1.cs

总共55 KB的代码,所以没什么太重的。

答案 2 :(得分:6)

Mono为其自己的mscorlib.dll提供了managed implementation of SHA1(但它不像@CodeInChaos建议的那样位于Mono.Security.dll中)。

它是开源的,经过严格测试,其意图与Microsoft实现完全相同(例如,它源自SHA1HashAlgorith ... implements ICryptoTransform ...)所以应该是一个简单的替代品。

答案 3 :(得分:6)

我使用过这个BouncyCastle Nuget软件包:https://www.nuget.org/packages/BouncyCastle-PCL/它对我来说很好用(跨平台 Windows应用商店应用,.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);
}

答案 4 :(得分:2)

SHA-1 Wikipedia article包含伪代码,您可以将其用作自己实现的指南。但是,与加密函数一样,我强烈建议使用经过实践检验的实现。

假设您需要SHA-256实现,您可以在BouncyCastle中找到一个,它以源代码形式提供。那里的相关课叫做Org.BouncyCastle.Crypto.Digests.Sha256Digest(这里是它的source)。

答案 5 :(得分:1)

您可能想要查看新的 .NET标准库:

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();
        }
    }

您可能还会获得一些帮助(用于使用.NET标准库创建PCL项目):

https://xamarinhelp.com/dot-net-standard-pcl-xamarin-forms/

答案 6 :(得分:0)

我也希望签署OAuth,并且正在查看PCL加密 - 此测试显示了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]);
        }
    }

答案 7 :(得分:0)

当我必须达到同样的结果时,这对我有用。您也可以使用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)));
    }
}

引自代码:Github Issue #554 link

答案 8 :(得分:0)

以下是使用BouncyCastle

的示例
    public static string ComputeSha1(string data)
    {
        var sha1Digest = new Org.BouncyCastle.Crypto.Digests.Sha1Digest();
        var hash = new byte[sha1Digest.GetDigestSize()];

        var dataBytes = Encoding.UTF8.GetBytes(data);
        foreach (var b in dataBytes)
        {
            sha1Digest.Update(b);
        }
        sha1Digest.DoFinal(hash, 0);

        return string.Join("", hash.Select(b => b.ToString("x2")).ToArray());
    }