2012-04-20 46 views
15

我正在嘗試構建一個可移植類庫,以生成其他類/應用程序使用的OAuth url。這個使用OAuth的類庫必須是一個可移植的類庫,因此它可以與我正在構建的不同版本的DropBox API一起工作。在便攜式類庫中生成SHA1哈希

該類的一部分需要生成SHA1哈希以生成oauth_signature。

我知道,可移植類庫不支持System.Security.Cryptography,所以無論如何,這個類可以生成一個沒有這個類的SHA1哈希?

+2

你可以複製在從Mono.Security一些代碼的例子。 – CodesInChaos 2012-04-20 22:30:15

+2

我在SHA1Managed類中看不到任何麻煩的依賴關係。便攜式打擊我只是未完成,每當我看一看。 – 2012-04-20 23:20:50

+0

這將是一個問題,但它是一個非常簡單的字符串構建類與幾個方法,所以只要他們的工作未完成不是一個問題。 – 2012-04-20 23:22:34

回答

6

Mono提供了它自己的mscorlib.dll一個managed implementation of SHA1(但它不是位於Mono.Security.dll像@CodeInChaos建議)。

它是開源的,很好的測試,旨在表現得完全像微軟實現(例如,它派生從SHA1HashAlgorith ...實現ICryptoTransform ...),所以它應該是一個簡單的簡易替換。

+0

你可以給我一些幫助,用它來簡單地散列一個字符串?代碼幾乎沒有評論它,所以我覺得很難理解。 – 2012-04-23 19:24:36

+1

您需要將字符串轉換爲字節,例如'System.Text.XXXEncoding.GetBytes()'。請特別注意編碼(例如UTF8比ASCII好得多),因爲不同的字節會導致不同的散列值。 – poupou 2012-04-23 19:36:31

+0

我不知道如何使用它。有人可以幫助我從一些字符串生成SHA1哈希? – alvaropaco 2016-03-15 14:54:24

2

SHA-1 Wikipedia article包含可用作自己實現的指導的僞代碼。但是,與密碼功能一樣,我強烈建議使用久經考驗的實現。

假設你想要一個SHA-256實現,你可以在源代碼格式的BouncyCastle中找到一個。這裏的相關類叫做Org.BouncyCastle.Crypto.Digests.Sha256Digest(這裏是它的source)。

8

嗯,我需要這也最近,我發現更容易採取SHA1實現從HashLib:http://hashlib.codeplex.com/

單執行有一定範圍廣泛的依賴(例外的定位,等等),而來自HashLib你只需要要複製幾個文件而不做任何更改:

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

55 KB的代碼總數,所以沒有太重。

+0

爲我工作。我確實需要添加一些額外的文件到你的列表中。 IHashInfo.cs(並非所有東西都需要)。在上面引用的類中使用的.SubArray()擴展方法也需要ArrayExtentions.cs。我將HashFactory類縮小到與移植類匹配 - 但它確實完成了工作。感謝提示。原來我的頭在旋轉着看着所有的課程。你的清單真的有幫助。 – TravisWhidden 2014-12-03 20:48:04

+0

這工作很好,謝謝! 像rouen提到的,你的列表中缺少IHashInfo.cs。 因爲我只需要一個字符串進行SHA1轉換,所以我能夠將代碼大小縮小到〜26 KB。 – 2016-01-25 13:28:11

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

我同意 - 但您可能想要更改示例以顯示正在使用的密鑰: byte [] keyMaterial; byte [] data; var algorithm = WinRTCrypto.MacAlgorithmProvider.OpenAlgorithm(MacAlgorithm.HmacSha1); CryptographicHash hasher = algorithm.CreateHash(keyMaterial); hasher.Append(data); byte [] mac = hasher.GetValueAndReset(); string macBase64 = Convert.ToBase64String(mac); – 2016-01-25 00:58:13

+0

很好的例子!我有一個小的補充。在一行中創建十六進制字符串,而不是5:return string.Join(「」,hash.Select(b => b.ToString(「x2」))。ToArray()); – 2016-06-28 06:55:07

6

我已經使用這個BouncyCastle的NuGet包:https://www.nuget.org/packages/BouncyCastle-PCL/,它爲我工作得很好(跨平臺的Windows Store應用.NET框架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); 
} 
0

我想籤的OAuth也和我在看PCL加密 - 此測試顯示HMACSHA1哈希的創建,並比較日e結果轉換爲標準的.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]); 
     } 
    } 
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/

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

代碼引述:https://xamarinhelp.com/cryptography-in-xamarin-forms/

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