沒時間扯淡類,趕緊上車吧。 在現代社會中,信息安全對於每一個人都是至關重要的,例如我們的銀行賬戶安全、支付寶和微信賬戶安全、以及郵箱等等,說到信息安全,那就必須得提到加密技術,至於加密的一些相關概念,在這裡就不說了。 這一次將會主要講解.NET的加密方式,接下來將會分別介紹散列加密,對稱加密,非對稱 ...
沒時間扯淡類,趕緊上車吧。
在現代社會中,信息安全對於每一個人都是至關重要的,例如我們的銀行賬戶安全、支付寶和微信賬戶安全、以及郵箱等等,說到信息安全,那就必須得提到加密技術,至於加密的一些相關概念,在這裡就不說了。
這一次將會主要講解.NET的加密方式,接下來將會分別介紹散列加密,對稱加密,非對稱加密等等加密方式在.NET中的應用,本文主要講解散列加密在.NET中的應用實例。
一.DotNet散列演算法概述:
說到散列應該都不會陌生,並且首先都會想到MD5加密,但是對於散列更加深入的瞭解,恐怕知道的人就不會那麼多了。散列演算法創建了一個散列碼,也叫做“消息摘要”或“消息指紋”,看到“消息指紋”這個詞,我首先想到的是可以唯一識別一個消息或者說可以唯一的標識一個人。
1.散列演算法原理概述:
散列演算法的核心是一個數學函數,在兩個固定大小的數據塊中運行它可以創建一個散列碼。在散列演算法中需要指定一個“種子值”,該值和第一塊消息數據一同載入散列函數這就生成了第一個散列碼,按照上一步的方式,散列碼依次進入下一個散列函數運算,最後獲得散列碼,如下圖所示:
散列碼是採用重覆調用散列函數的鏈創建的,散列碼依賴於消息的單個位的值。散列函數是通過操作兩塊固定長度的二進位數據來生成散列碼,散列演算法則描述類使用散列函數為消息創建散列碼的過程,散列演算法是使用散列函數的協議,指定類如何分解消息及如何鏈接之前消息快產生的結果。散列碼的長度也有所限制,散列碼長度較長時,需要的破解時間就會較長,這就是暴力破解的方式,但是散列碼較長,生成散列碼的時間就是比較長,任何策略都是需要付出代價的。
2.DotNet的散列演算法種類:
在.NET中,常用的散列演算法種類有如下幾種:
在以上列舉的幾種散列演算法中,MD5是.NET含有的最快的散列演算法。如果基礎演算法有缺陷,越長的散列碼並不一定能夠提供越好的安全。
二.DotNet散列演算法應用解析:
以上對散列演算法,以及散列演算法在.NET中分類做了一個簡單的介紹,接下來我們具體看一下再.NET中實現這幾種散列演算法的類。
在.NET中System.Security.Cryptography命名空間下的HashAlgorithm類,表示所有加密哈希演算法實現均必須從中派生的基類。有如下類結構:
在.NET中有兩種類型的實現類,一個是以“Managed”結尾,這些類都被寫入托管.NET語言,一種是以“CryptoServiceProvider”結尾,這些類是基於Windows CryptoAPI的。接下來我們具體的瞭解一下HashAlgorithm類的一些方法:
1.HashAlgorithm類方法和屬性解析:
(1).Hash屬性:獲取計算所得的哈希代碼的值。
public virtual byte[] Hash { get { if (this.m_bDisposed) throw new ObjectDisposedException((string) null); if (this.State != 0) throw new CryptographicUnexpectedOperationException(Environment.GetResourceString("Cryptography_HashNotYetFinalized")); return (byte[]) this.HashValue.Clone(); } }
該屬性返回類電腦的散列碼值,該屬性是一個位元組數組,由代碼可以看出該屬性是只讀的,返回計算所得的哈希代碼的當前值。
(2).Create()方法:創建哈希演算法的指定實現的實例。
public static HashAlgorithm Create(string hashName) { return (HashAlgorithm) CryptoConfig.CreateFromName(hashName); }
由代碼可知,指定哈希演算法的新實例,如果hashName不是有效哈希演算法,則為 null,該方法使用名稱創建一個HashAlgorithm對象的新實例。
(3).ComputeHash()方法:從位元組數組和數據流中創建散列碼。
public byte[] ComputeHash(byte[] buffer) { if (this.m_bDisposed) throw new ObjectDisposedException((string) null); if (buffer == null) throw new ArgumentNullException("buffer"); this.HashCore(buffer, 0, buffer.Length); this.HashValue = this.HashFinal(); byte[] numArray = (byte[]) this.HashValue.Clone(); this.Initialize(); return numArray; }
以上是ComputeHash()方法的一個重載版本,使用位元組數組來創建一個散列碼,該方法返回一個位元組數組,該數組含有消息數據的散列碼。HashCore()將寫入對象的數據路由到哈希演算法以計算哈希值,HashFinal()在加密流對象處理完最後的數據後完成哈希計算。
2.HMAC類: 表示基於哈希的消息驗證代碼 (HMAC) 的所有實現必須從中派生的抽象類。
創建加密散列碼(消息驗證碼MACs)有兩種方式:
第一種:先合併類密鑰和消息數據,再使用通常的加密散列演算法來為該並集創建散列碼。常用的是HMAC標準。
第二種:使用對稱演算法來加密消息數據,除了最後幾位之外,所有的加密數據位都將被捨棄。
HMAC標準制定瞭如何合併消息數據和密鑰,但是沒有指定應該使用那種散列演算法來創建散列碼,這也就意味著該標準可以應用於任何演算法。
(1).Key屬性:獲取或設置用於哈希演算法的密鑰。
public override byte[] Key { get { return (byte[]) this.KeyValue.Clone(); } set { if (this.m_hashing) throw new CryptographicException(Environment.GetResourceString("Cryptography_HashKeySet")); this.InitializeKey(value); } }
該屬性在這裡進行類重寫,該屬性是一個位元組數組,屬性可讀寫。
(2).Create()方法:創建基於哈希的消息驗證代碼 (HMAC) 指定實現的實例。
public static HMAC Create(string algorithmName) { return (HMAC) CryptoConfig.CreateFromName(algorithmName); }
該方法指定的 HMAC 實現的新實例,該方法跟HashAlgorithm類的Create方法類似,這裡就不做深入的解析。
(3).HashCore()方法:將寫入對象的數據路由給預設 HMAC 哈希演算法以計算哈希值。
protected override void HashCore(byte[] rgb, int ib, int cb) { if (!this.m_hashing) { this.m_hash1.TransformBlock(this.m_inner, 0, this.m_inner.Length, this.m_inner, 0); this.m_hashing = true; } this.m_hash1.TransformBlock(rgb, ib, cb, rgb, ib); }
該方法在這裡被重寫,將寫入對象的數據路由給預設 HMAC 哈希演算法以計算哈希值。TransformBlock()計算輸入位元組數組的指定區域的哈希值,將輸入位元組數組的指定區域複製到指定的區域,輸出位元組數組。
三.DotNet散列演算法實現實例:
以上介紹在.NET下的散列加密的主要類,接下來看一下MD5的具體實現代碼:
/// <summary> /// 表示 MD5哈希演算法的所有實現均從中繼承的抽象類。 /// </summary> [ComVisible(true)] public abstract class MD5 : HashAlgorithm { /// <summary> /// 初始化 MD5 的新實例。 /// </summary> protected MD5() { this.HashSizeValue = 128; } /// <summary> /// 創建MD5 哈希演算法的預設實現的實例。 /// </summary> /// <returns> /// <see cref="T:System.Security.Cryptography.MD5"/> 哈希演算法的新實例。 /// </returns> public static MD5 Create() { return MD5.Create("System.Security.Cryptography.MD5"); } /// <summary> /// 創建MD5 哈希演算法的指定實現的實例。 /// </summary> /// <returns> public static MD5 Create(string algName) { return (MD5) CryptoConfig.CreateFromName(algName); } }
由以上的代碼可以看住,在MD5類中,具體的實現方法都是由HashAlgorithm類的Create方法實現,在這裡就不再做介紹。
1.SHA1演算法實例:
public static string GetSha1(string str) { if (string.IsNullOrEmpty(str)) { throw new ArgumentNullException(str); } try { //建立SHA1對象 SHA1 sha = new SHA1CryptoServiceProvider(); //將mystr轉換成byte[] var enc = new ASCIIEncoding(); var dataToHash = enc.GetBytes(str); //Hash運算 var dataHashed = sha.ComputeHash(dataToHash); //將運算結果轉換成string var hash = BitConverter.ToString(dataHashed).Replace("-", ""); return hash; } catch (ArgumentNullException ex) { throw ex; } catch (ArgumentException arex) { throw arex; } catch (ObjectDisposedException obex) { throw obex; }
2.MD5加密實例:
/// <summary> /// 32位大寫 /// </summary> /// <returns></returns> public static string Upper32(string s) { var hashPasswordForStoringInConfigFile = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(s, "md5"); if (hashPasswordForStoringInConfigFile != null) s = hashPasswordForStoringInConfigFile; return s.ToUpper(); } /// <summary> /// 32位小寫 /// </summary> /// <returns></returns> public static string Lower32(string s) { var hashPasswordForStoringInConfigFile = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(s, "md5"); if (hashPasswordForStoringInConfigFile != null) s = hashPasswordForStoringInConfigFile; return s.ToLower(); } /// <summary> /// 16位大寫 /// </summary> /// <returns></returns> public static string Upper16(string s) { var hashPasswordForStoringInConfigFile = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(s, "md5"); if (hashPasswordForStoringInConfigFile != null) s = hashPasswordForStoringInConfigFile.ToString(); return s.ToUpper().Substring(8, 16); } /// <summary> /// 16位小寫 /// </summary> /// <returns></returns> public static string Lower16(string s) { var hashPasswordForStoringInConfigFile = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(s, "md5"); if (hashPasswordForStoringInConfigFile != null) s = hashPasswordForStoringInConfigFile.ToString(); return s.ToLower().Substring(8, 16); }
四.總結:
以上介紹了散列演算法在.NET的應用和原理,希望可以幫到一些人,如果文章中有寫的錯誤和不到位的地方,還望大家多多批評指正。
友情添加一個加密的helper方法:http://www.cnblogs.com/liqingwen/p/6155694.html