Generate SHA1 Hash in Portable Class Library

前端 未结 9 1966
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-01-07 23:56

I\'m trying to build a portable class library that generates OAuth urls for other classes/applications to use. This class library using OAuth has to be a portable class libr

相关标签:
9条回答
  • 2021-01-08 00:32

    You might want to check out the new .NET Standard library:

    https://docs.microsoft.com/en-us/dotnet/articles/standard/library

    It is portable, and System.Security.Cryptography is included.

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

    You might also get some help (for creating a PCL project with .NET Standard Library) here:

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

    0 讨论(0)
  • Here is an example using 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());
        }
    
    0 讨论(0)
  • 2021-01-08 00:42

    I think the easiest way is to use the PCLCrypto nuget package. Then you can do:

    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();
    }
    
    0 讨论(0)
  • 2021-01-08 00:47

    I have used this BouncyCastle Nuget package: https://www.nuget.org/packages/BouncyCastle-PCL/ and it works just fine for me (cross platforms Windows Store App, .Net Framework 4.5, Silverlight 5, Windows Phone 8, Xamarin.Android, Xamarin.iOS)

    Use HMACSHA1 to generate signature like this:

    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);
    }
    
    0 讨论(0)
  • 2021-01-08 00:53

    Mono provides a managed implementation of SHA1 for it's own mscorlib.dll (but it's not located in Mono.Security.dll like @CodeInChaos suggested).

    It's open source, very well tested and meant to behave exactly like Microsoft implementation (e.g. it derives from SHA1, HashAlgorith... implements ICryptoTransform...) so it should be an easy drop-in replacement.

    0 讨论(0)
  • 2021-01-08 00:53

    I wanted sign OAuth also, and am looking at PCL Crypto - this test shows creation of a HmacSha1 hash, and compares the result to the standard .NET Framework way.

        [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]);
            }
        }
    
    0 讨论(0)
提交回复
热议问题