DotNet加密方式解析--散列加密

来源:http://www.cnblogs.com/pengze0902/archive/2017/01/10/6268700.html
-Advertisement-
Play Games

沒時間扯淡類,趕緊上車吧。 在現代社會中,信息安全對於每一個人都是至關重要的,例如我們的銀行賬戶安全、支付寶和微信賬戶安全、以及郵箱等等,說到信息安全,那就必須得提到加密技術,至於加密的一些相關概念,在這裡就不說了。 這一次將會主要講解.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


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在點擊運行項目時,生成成功。但是頁面沒有彈出來,彈出個提示框,無法連接到 ASP.NET Development Server. 網上我看到說關閉掉防火牆,可是再關掉防火牆後還是不行。但是其他的項目又能跑起來,所以估計是埠號被占用了。 最後的解決方案是: 項目右鍵屬性,在屬性視窗,將使用動態埠號 ...
  • 我個人比較懶,能自動做的事絕不手動做,最近在用ASP.NET Core寫一個項目,過程中會積累一些方便的工具類或框架,分享出來歡迎大家點評。 如果以後有時間的話,我打算寫一個系列的【實現BUG自動檢測】,本文將是第一篇。 如果你使用過ASP.NET Core那麼對依賴註入一定不陌生。 使用流程... ...
  • 在C#.NET的開發中,事件是經常接觸到的概念,比如為按鈕添加點擊事件,並寫入點擊按鈕觸發事件要運行的代碼。不管是ASP.NET還是WinForm等各種形式的應用程式,最經常是為系統生成的事件寫具體代碼。如果要自定義事件呢?有的朋友對於自定義事件感覺比較難理解。最近在開發HoverTreeTop項目 ...
  • C#簡單程式練習 說明:學習之餘溫習幾道經典基礎知識題,將其記錄下來,以供初學者參考。 1,題目:求出0-1000中能被7整除的數,並計算輸出每五個數的和: 運行截圖: 題目2:編寫一個類,其中包含一個排序的方法 Sort(), 當傳入的是一串整數,就按照從小到大的順序輸出,如果傳入的是一個字元串, ...
  • 堆、棧、引用類型、值類型 記憶體分為堆和棧(PS:還有一種是靜態存儲區域 [記憶體分為這三種]),值類型的數據存儲在棧中,引用類型的數據存儲在堆中。 堆、棧: 堆和棧的區別: 棧是編譯期間就分配好的記憶體空間,因此你的代碼中必須就棧的大小有明確的定義;局部值類型變數、值類型參數等都在棧記憶體中。 堆是程式運 ...
  • 本篇和大家分享的是學習Vuejs的總結和調用webapi的一個小示例;快到年底了爭取和大家多分享點東西,希望能對各位有所幫助;本章內容希望大家喜歡,也希望各位多多掃碼支持和推薦謝謝: » Vuejs - 學習大雜燴 » WebApi + Vue.js 示例 下麵一步一個腳印的來分享: » Vuejs ...
  • WEB後臺開發,如果用的是Bootstrap框架,那這個表格神器你一定不要錯過。 官方地址:https://datatables.net/ What?英文不好,沒關係咱有中文的 http://datatables.club/ 不過我還是建議看英文的,因為比較全面雖然訪問的速度慢點,終歸能進的去。閑話 ...
  • 恢復內容開始 http://ironpython.net/documentation/dotnet/這是原文地址 以下筆記僅記錄閱讀過程中我認為有必要記錄的內容,大多數都是依賴翻譯軟體的機翻,配合個人對代碼的理解寫出的筆記,個別不是很確定的,會在句首標註 猜測: 在ironPython 中想使用.N ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...