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

.NET對稱加密實踐 (新手教程)

2013-11-13 09:53:47  來源: .NET編程 

  在使用NET框架提供的加密算法實現類來執行加密任務時我們需要准備加密密鑰和初始化向量(IV)基於對稱加密的特點我們在加密數據之後一定要保存好密鑰和初始化向量因為解密要用到它們但是對於不同的數據加密我們要使用不同的密鑰和初始化向量理論上每次新的加密過程都應該使用全新的密鑰和初始化向量

  通常我們需要將加密密鑰和初始化向量傳遞給另一個人這時候需要使用非對稱加密算法來加密密鑰和初始化向量然後在網絡上傳輸

  那麼如何創建加密密鑰和初始化向量呢?有兩種基本方法一種是使用加密算法實現類的構造函數一種是使用GenerateIV()和GenerateKey()方法生成密鑰和初始化向量我們先測試構造函數的方法如代碼清單

  代碼清單 使用構造函數創建密鑰和初始化向量

  using System;

  using SystemText;

  using SystemSecurityCryptography;

  namespace Encription

  {

  class Program

  {

  static void Main(string[] args)

  {

  AesCryptoServiceProvider acsp = new AesCryptoServiceProvider();

  WriteKeyAndIV(acsp);

  AesManaged am = new AesManaged();

  WriteKeyAndIV(am);

  DESCryptoServiceProvider dsp = new DESCryptoServiceProvider();

  WriteKeyAndIV(dsp);

  TripleDESCryptoServiceProvider tdsp = new TripleDESCryptoServiceProvider();

  WriteKeyAndIV(tdsp);

  RijndaelManaged rm = new RijndaelManaged();

  WriteKeyAndIV(rm);

  ConsoleRead();

  }

  static void WriteKeyAndIV(SymmetricAlgorithm sa)

  {

  ConsoleWriteLine(GetStringFromByte(saKey));

  ConsoleWriteLine(*******);

  ConsoleWriteLine(GetStringFromByte(saIV));

  ConsoleWriteLine();

  }

  static string GetStringFromByte(byte[] bytes)

  {

  string s=;

  for (int i = ; i < bytesLength; i++)

  {

  s += bytes[i]ToString()+ ;

  }

  return s;

  }

  }

  }

  如代碼清單所示一共有三個方法Main方法用來初始化NET提供的種對稱加密實例WriteKeyAndIV方法用來輸出每個實例的密鑰和初始化向量GetStringFromByte方法用來輸出byte數組的原始值那麼現在我們看下輸出結果是不是如我們預料到的已經初始化了加密密鑰和初始化向量呢?如圖所示

  
代碼清單輸出結果

  如圖在控制台輸出了每個加密實例的密鑰和初始化向量當我們需要多個密鑰或者多個初始化向量的時候就需要采用GenerateIV()和GenerateKey()方法下面我們對代碼清單做簡要的修改如代碼清單所示

  代碼清單 使用GenerateIV()和GenerateKey()方法

  using System;

  using SystemCollectionsGeneric;

  using SystemLinq;

  using SystemText;

  using SystemSecurityCryptography;

  namespace Encription

  {

  class Program

  {

  static void Main(string[] args)

  {

  AesCryptoServiceProvider acsp = new AesCryptoServiceProvider();

  WriteKeyAndIV(acsp);

  acspGenerateIV();

  acspGenerateKey();

  WriteKeyAndIV(acsp);

  ConsoleRead();

  }

  static void WriteKeyAndIV(SymmetricAlgorithm sa)

  {

  ConsoleWriteLine(GetStringFromByte(saKey));

  ConsoleWriteLine(*******);

  ConsoleWriteLine(GetStringFromByte(saIV));

  ConsoleWriteLine();

  }

  static string GetStringFromByte(byte[] bytes)

  {

  string s=;

  for (int i = ; i < bytesLength; i++)

  {

  s += bytes[i]ToString()+ ;

  }

  return s;

  }

  }

  }

  如代碼清單我們所做的修改很簡單Main方法中只保留了AesCryptoServiceProvider實例再初始化該實例後又調用它的GenerateIV和GenerateKey方法看是否產生了新的加密密鑰和初始化向量結果如圖所示

  
代碼清單運行結果

  如圖我們可以看到使用GenerateIV和GenerateKey方法後生成了新的密鑰和初始化向量

  我們的准備工作完成了下面要開始真正的加密之旅了對稱加密需要和CryptoStream類的實例配合加密流來實現數據加密NET中的內存流文件流網絡流都可以使用為了示例更明了我們以AesCryptoServiceProvider類為例使用內存流來演示如何使用對稱加密類加密解密數據先看代碼清單

  代碼清單 加密解密數據示例

  using System;

  using SystemCollectionsGeneric;

  using SystemLinq;

  using SystemText;

  using SystemSecurityCryptography;

  using SystemIO;

  namespace Sample

  {

  class Program

  {

  static AesCryptoServiceProvider acsp = new AesCryptoServiceProvider();

  static void Main(string[] args)

  {

  byte[] key = acspKey;

  byte[] iv = acspIV;

  string s = @xuanhun加密測試;

  byte[] sbyt = EncodingDefaultGetBytes(s);

  byte []Enb = Encript(sbyt key iv);

  byte []Deb = Decript(Enb key iv);

  ConsoleWriteLine(EncodingDefaultGetString(Enb));

  ConsoleWriteLine(EncodingDefaultGetString(Deb));

  ConsoleRead();

  }

  public static byte[] Encript(byte[] s byte[] key byte[] iv)

  {

  MemoryStream mstream = new MemoryStream();

  CryptoStream cstream = new CryptoStream(mstream acspCreateEncryptor(key iv) CryptoStreamModeWrite);

  cstreamWrite(s sLength);

  cstreamFlushFinalBlock();

  byte[] outb = mstreamToArray();

  cstreamClose();

  mstreamClose();

  return outb;

  }

  public static byte[] Decript(byte[] s byte[] key byte[] iv)

  {

  MemoryStream mtream = new MemoryStream();

  CryptoStream deStreame = new CryptoStream(mtream acspCreateDecryptor(key iv) CryptoStreamModeWrite);

  deStreameWrite(s sLength);

  deStreameFlushFinalBlock();

  byte[] outs = mtreamToArray();

  mtreamClose();

  deStreameClose();

  return outs;

  }

  public static byte[] GetByteFromstring(string s)

  {

  return EncodingDefaultGetBytes(s);

  }

  }

  }

  如代碼清單我們首先創建了AesCryptoServiceProvider實例然後再Main方法中使用了局部變量key和iv來保存該實例的加密密鑰和初始化向量字符串s是要加密的原始字符串局部變量sbyte保存了將字符串s轉化為byte數組後的結果我們的加密解密過程都是圍繞該byte數組進行的

  接下來我們介紹Main方法中調用的兩個靜態方法Encript和Decript方法分別用來實現加密和解密在Encript方法中我們首先初始化內存流MemoryStream的實例mstream然後以mstream為參數創建CryptoStream實例CryptoStream構造函數需要三個參數第一個是流實例第二個是加密或者解密器在加密函數中使用CreateEncryptor方法做參數在解密方法中使用CreateDecryptor做參數CreateEncryptor和CreateDecryptor方法需要傳入我們准備好的加密密鑰和初始化向量第三個參數是CryptoStreamMode枚舉該枚舉有兩個值Write和Read用來指示流的操作比如在網絡流中加密並輸出數據時要設置Write屬性接收並解密的一方要設置Read屬性本例中把加密和解密的數據都寫入內存流所以都設置了Write屬性在初始化CryptoStream實例之後調用該實例的Write方法將加密後的數據寫入內存流然後再調用內存流的ToArray方法讀出加密數據返回到Main方法中通過EncodingDefaultGetString方法獲得加密後的字符串解密過程與此類似不再贅述

  現在我們看看改程序的運行結果如圖所示

  
代碼清單運行結果

  從圖上看我們已經成功的實現了簡單的對稱加密解密過程NET中的其他對稱加密實現類的使用方法與此類似


From:http://tw.wingwit.com/Article/program/net/201311/11895.html
  • 上一篇文章:

  • 下一篇文章:
  • 推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.