熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

.NET中的密碼學--對稱加密

2013-11-13 10:32:51  來源: .NET編程 

  介紹

  在net之前使用非托管的WinAPIs加密解密數據是一件非常痛苦的事情為了這個加密解密的目的NET配置了一組類(和命名空間)現在你有很多類可以使用每種不同的算法保護你的數據NET裡面Crypttography命名空間下又定義了種類型的加密方法他們是AsymmetricAlgorithmSymmetricAlgorithm和HashAlgorithm所有的這些類(和NET密碼學類型)都是抽象類我們今天將要描述SymmetricAlgorithm剩下的將在以後的文章中陸續講解

  注意雖然大多數托管代碼裡的加密類實現使用了很多CryptoAPI庫

  SymmetricAlgorithms基礎

  對稱算法使用用戶的密鑰(密碼)工作它的意思是任何時候你都可以實現它而且可以使用對稱算法加密或者解密你的數據為了加密或者解密你的數據你必須定義一個密碼或者一個密鑰下面描述了對稱加密的特性

  加密的強度依賴於你的密鑰(密碼)如果你配置一個長的密鑰它將是非常難破解的意思是他將要花費很長的時間讓黑客找到密鑰

  對稱加密的一個風險是密碼應該讓第二個人知道(這個人必須用你的密鑰來解密數據)

  這種加密算法是基於簡單的數學操作因此它工作的非常快因此當你要加密的數據量非常大的時候它是最好的選擇

  基於對稱的加密可以被黑客暴力破解但是如果你定義一個非常好的密碼(足夠長)這個破解的過程將需要很長的時間

  一旦用戶定義了密鑰黑客可以使用暴力破解或者字典來編碼或者解密你的信息但是長的密鑰可以在黑客破解你的密碼的時候保護你的數據更長的時間

  另外在使用密鑰或者密碼對稱加密過程中有一件非常重要的事情就是初始化向量(IV)IV被使用在最初的編碼中(加密或者解密)在所有的對稱算法類中我們有一個名叫Mode的屬性這是被IV使用的如果我們設置Mode屬性為CipherModeCBC(Cipher Block Chaining)則使用這個模式每個數據塊使用來自前一個塊的值來處理意思是如果系統在處理第三塊數據則它會從第二塊中取一些信息(處理第三塊數據)接著它會取第一塊數據中的信息用來處理第二塊數據但是在第一塊數據之前沒有可以用的塊因此它將使用IV來處理第一塊這個技術確保沒有兩個相同的塊產生相同的輸出並且因此使得數據更安全然而如果你使Mode=CipherModerECB(Electronic codebook mode)則他不會使用上面的方法(使用前面的處理的塊信息處理後面的塊)如果你想用很少的資源和時間處理大量的消息那麼這個方法對於你來說就很有用他也可以讓你從數據的中間開始處理

  應此上面我們包含了在對稱加密中的兩間非常重要的事情他們是密鑰和初始化向量現在讓我們看看對稱加密支持哪些算法

  對稱算法和對稱算法類

  下面是對稱算法和他們的類的關鍵信息

  算法名稱
  算法類(抽象)
  有效密鑰大小(Bit)
  默認密鑰大小(Bit)
  默認實現類

  DES
  DES
  
  
  DESCryptoServiceProvider

  TripleDES
  TripleDES
  
  
  TripleDESCryptoServiceProvider

  RC
  RC
  
  
  RCCryptoServiceProvider

  RijnDael
  RijnDael
  
  
  RijnDaelManaged

  這裡需要注意的是所有的算法類都是繼承於抽象類SymmetricAlgorithm並且你可以看到每個類都支持不同的密鑰大小相同的情況下他們也支持不同的初始化向量的大小正如我剛才所說的他們所有的類都是抽象類因此我們不能直接創建這些抽象類的任何實例但是SymmetricAlgorithm類(也是抽象類)有一個共享的方法叫Create可以不用操心它是如何實現來創建一個類的具體實例意思是你可以通過下面的方式使用它

  RC mRC = RCCreate()

  它將為您返回一個RC默認實現的一個實例而不用去關心具體如何實現RC這個類如果你想在微軟以後更新RC類的實現還能共享代碼(成為可能)這個技術是非常有用的在那種情況下你的代碼將自動適應它們的改變並且正確的工作或者可能在將來RC類用托管代碼寫你的代碼依然可以接受它在相同的情況下你同樣可以使用下面的語句

  RC mCrypto = SymmetricAlgorithmCreate(RC

  這也可以給你返回一個RC的對象(默認實現)在這種情況下你要使用重裁Create方法用算法的名字設置參數來返回算法的對象 這個Create方法來自SymmetricAlgorithm類並且向我前面說的所有的使用對稱算法的其它類都繼承於SymmetricAlgorithm因此你可以在上面所有的類裡面找到Create這個方法意思是如果你使用RCCreate(DES)則它也能工作並且將返回一個DES的對象但是不能使用RC類得到DES對象

  上面的機制看起來很有用我們可以用同樣的方法使用我們自己的算法定義自己的類但是要想這樣我們必須要對nfig文件作一些小的改動我在這裡不詳細描述你可以參考Wrox關於密碼學的書得到更多的信息

  現在讓我們看看SymmetricAlgorithm類裡面的一些方法和屬性

  BlockSize分開處理的數據塊的大小大的數據將被分成小的數據塊來處理如果數據小於塊大小則被追加(使用一些默認值填充)

  Key在處理數據的時候將要使用密鑰這個密鑰被配置成使用字節數組

  IV數據處理的時候使用初始化向量(上面已經描述)配置成字節數組

  KeySize密鑰的所有位的大小

  LegalBlockSize 返回BlockSize的枚舉告訴你判斷包括最大值最小值和跳躍值在內的塊的大小跳躍值意思是還有多少值應該添加判斷值得到下一個值比如如果最小值是跳躍值是那麼下一個判斷值就是等等(Returns the BlockSize Enumeration which tells you legal values for block size including max value min value and Skip value Skip value means that how much value should be added to last legal value to get next value Like if min value is and Skipvalue is it means next legal values will be and so on

  Mode 位操作得到或者設置模式見上面描述值是CipherMode枚舉中的一個

  Padding 得到或者設置PaddingMode枚舉中的一個追加值(填充塊中空余的區域)

  LegalKeySize 和LegalBlockSize一樣但是處理的是KeySize

  Create 上面已經描述使用它創建默認算法實現的類的實例

  CreateEncryptor 返回一個可以手動加密數據的IcryptoTransform對象一會將仔細描述

  CreateDecryptor 返回一個可以手動解密數據的IcryptoTransform對象一會將仔細描述

  GeneratrKey and GenerateIV 在加密或者解密的過程中如果Key和IV是null則這些方法可以產生默認的密鑰和IV

  VaildKeySize 檢查給定的密鑰是不是算法的有效的密鑰

  Clear 清除和消除所有的資源以及象密鑰和IV這樣的內存信息

  在寫代碼之前讓我們說幾件對我們理解代碼非常用幫助的事情

  CreateEncryptor和CreateDecryptor

  SymmetricAlgorithm類的CreateEncryptor和CreateDecryptor方法返回ICryptoTransform對象IcryptoTransform是一個想要處理數據塊的類來實現的接口這個過程可以是加密解密散列基於的編碼和解碼等等這個接口的基本目的是完成數據處理分塊(The basic purpose of this Interface is to perform Blockwize processing of data你可以直接使用它的實例但是在大多數情況下為了方便我們通過其他的名叫CryptoStream來完成讓我們看一個例子是如何使用它的

  DES mCrypt = new SymmetricAlgorithmCreate(DES

  ICryptoTransform mTransform = mCryptCreateEncryptot()

  CreateEncryptor或者CreateDecryptor是兩個重裁的方法如果你沒有任何參數傳入其中那麼將使用默認的密鑰和IV(使用SymmetricAlgoruthm類裡面的GenerateKey和GenerateIV方法)另一方面你可以通過傳入一個IV和密鑰到CreateEncryptor和CreateDecryptor的對象中以致加密和解密將使用我們自己定義的IV和密鑰

  CryptoStream 類

  CryptoStream類通常被使用來讀寫數據同時也在讀或者寫的時候加密或者解密數據它是簡單的包裝了一下原始流類StreamIt uses the buffered Access taking all worries from you to manage buffer block sizes padding etc你可以使用下面的代碼得到它的實例

  DES mCrypt = SymmetricAlgorithmCreate(DES

  IcryptoTransform mTransform = mCryptCreateEncryptor()

  CryptoStream mStream = new CryptoStream(fileStreammTransformCryptoStramModeRead)

  fileStream是請求從硬盤或者內存中讀取數據的原始文件的流(或者是MemoryStream)現在通過使用mStream對象和StreamReader/StreamWriter對象讀寫數據當你將要讀寫時你的加密解密信息將依賴IcryptoTransform對象

  代碼例子

  現在我們有足夠關於SymmetricAlgorithm的信息最後讓我們看看將要編碼和解碼的代碼片斷我假設你擁有一個包含txtData和命令按鈕控件的窗體在命令按鈕的代碼事件裡寫如下代碼這個代碼將要加密TextBox裡面的文本並用MessageBox顯示在將加密結果寫回到TextBox中

  SymmetricAlgorithm mCryptProv

  MemoryStream mMemStr

  // 加密txtData中的數據然後將加密結果用MessageBox顯示並且回寫到TextBox中

  // 這裡你可以配置任何net支持的類

  DES mCryptProv = SymmetricAlgorithmCreate(Rijndael

  // 加密數據將要以流的形式存儲在內存中因此我們需要內存Stream對象

  mMemStr = new MemoryStream()

  // 創建ICryptTransform對象(在這裡我們使用默認的密鑰和初始向量)

  ICryptTramsform mTransform = mCryptProvCreateEncryptor()

  CryptoStream mCSWriter = new CryptoStream(mMemStrmTransformCryptoStreamModeWrite)

  StreamWriter mSWriter = StreamWriter(mCSWriter)

  mSwriterWriter(thistxtDataText)

  mSWriterFlush()

  mCSWriterFlushFinalBlock()

  有一件事情在這裡需要注意我們沒有在代碼的任何地方使用IV和密鑰事實上在我們在代碼裡面沒有指定他們的時候NET Framework將為我們自動產生但是本文包含的例子代碼使用的是用戶指定的密鑰和IV我們將加密以後的數據使用MemoryStream寫到內存中現在讓我們從內存中得到數據的代碼

  // 數據已經寫入內存但是我們需要回顯它到TextBox和MessageBox中因此要做下面的工作

  // 為接受數據創建字節數組

  byte[] mBytes = new byte[mMemStrLength ]

  mMemStrPosition =

  mMemStrRead(mBytesmMemStrLength)

  TextUTFEncoding mEnc = new TextUTFEncoding()

  String mEncData = mEncGetString(mBytes)

  MessageBoxShow(加密數據為\n+mEncData)

  ThistxtDataText = mEncData

  從字節轉換為字符串必須要編碼在這裡我使用了UTFEncoding最後讓我們將解密後的數據再次顯示在MessageBox和TextBox中

  // 現在讓我們從內存中得到解密後的數據

  // 因為我們的數據在內存中所以我們需要重新使用MemoryStream對象

  // 將內存點置

  mMemStrPosition =

  mTransform = mCryptProvCreateDecryptor()

  CryptoStream mCSReader = new CryptoStream(mMemStrmTransformCryptoStreamModeRead)

  StreamReader mStrReader = new StreamReader(mCSReader)

  String mDecData = mStrReaderReadToEnd()

  MessageBox(解密數據為\n+mDecData)

  ThistxtDataText = mDecData

  這是所有的工作解密那些數據我們使用了相同的內存流為了能從流的其實部分讀數據我們首先將它置為開始然後我們用SymmetricAlgorithm對象的CreateDecryptor方法創建IcryptoTransform對象我們在上面的代碼中為了解密重復使用了對象(mMemStr)你可以創建新的對象(使用新的變量)然後我們為了從內存中讀取數據需要StreamReader對象While reading that it will also decrypt that data since we passed CryptoStream object during the creation of StreamReader object

  最後的話

  NET為我們提供了一個非常好的托管途徑保護我們的數據我們可以使用NET內建的一組類來加密我們的數據雖然很多的類後台依然使用Crypto APIs技術我們使用老的Crypto APIs沒有任何問題但是我們可以不用擔心那些類的具體實現來安全的使用這些類在後面的文章我將描述非對稱加密算法的神話和用途

  關於例子

  該文章的例子代碼讓你可以選擇一個算法來加密或者解密數據而且它還讓你指定你自己的IV和密鑰代碼以兩種方式工作一種是TextBox意思是你在TextBox中寫些東西然後加密或者解密這些內容第二種你可以選擇要加密或者解密的文件


From:http://tw.wingwit.com/Article/program/net/201311/13972.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.