在使用 NET框架提供的加密算法實現類來執行加密任務時 我們需要準備加密密鑰和初始化向量(IV) 基於對稱加密的特點 我們在加密數據之後壹定要保存好密鑰和初始化向量 因為解密要用到它們 但是對於不同的數據加密 我們要使用不同的密鑰和初始化向量 理論上每次新的加密過程都應該使用全新的密鑰和初始化向量
通常我們需要將加密密鑰和初始化向量傳遞給另壹個人 這時候需要使用非對稱加密算法來加密密鑰和初始化向量 然後在網絡上傳輸
那麽如何創建加密密鑰和初始化向量呢?有兩種基本方法 壹種是使用加密算法實現類的構造函數 壹種是使用GenerateIV()和GenerateKey()方法生成密鑰和初始化向量 我們先測試構造函數的方法 如代碼清單
代碼清單 使用構造函數創建密鑰和初始化向量
using System;
using System Text;
using System Security Cryptography;
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);
Console Read();
}
static void WriteKeyAndIV(SymmetricAlgorithm sa)
{
Console WriteLine(GetStringFromByte(sa Key));
Console WriteLine( ******* );
Console WriteLine(GetStringFromByte(sa IV));
Console WriteLine( );
}
static string GetStringFromByte(byte[] bytes)
{
string s= ;
for (int i = ; i < bytes Length; i++)
{
s += bytes[i] ToString()+ ;
}
return s;
}
}
}
如代碼清單 所示 壹***有三個方法 Main方法用來初始化 NET提供的 種對稱加密實例 WriteKeyAndIV方法用來輸出每個實例的密鑰和初始化向量 GetStringFromByte方法 用來輸出byte數組的原始值 那麽現在我們看下輸出結果 是不是如我們預料到的已經初始化了加密密鑰和初始化向量呢?如圖 所示
圖 代碼清單 輸出結果
如圖 在控制臺輸出了每個加密實例的密鑰和初始化向量 當我們需要多個密鑰或者多個初始化向量的時候 就需要采用GenerateIV()和GenerateKey()方法 下面我們對代碼清單 做簡要的修改 如代碼清單 所示
代碼清單 使用GenerateIV()和GenerateKey()方法
using System;
using System Collections Generic;
using System Linq;
using System Text;
using System Security Cryptography;
namespace Encription
{
class Program
{
static void Main(string[] args)
{
AesCryptoServiceProvider acsp = new AesCryptoServiceProvider();
WriteKeyAndIV(acsp);
acsp GenerateIV();
acsp GenerateKey();
WriteKeyAndIV(acsp);
Console Read();
}
static void WriteKeyAndIV(SymmetricAlgorithm sa)
{
Console WriteLine(GetStringFromByte(sa Key));
Console WriteLine( ******* );
Console WriteLine(GetStringFromByte(sa IV));
Console WriteLine( );
}
static string GetStringFromByte(byte[] bytes)
{
string s= ;
for (int i = ; i < bytes Length; i++)
{
s += bytes[i] ToString()+ ;
}
return s;
}
}
}
如代碼清單 我們所做的修改很簡單 Main方法中只保留了AesCryptoServiceProvider實例 再初始化該實例後 又調用它的GenerateIV和GenerateKey方法 看是否產生了新的加密密鑰和初始化向量 結果如圖 所示
圖 代碼清單 運行結果
如圖 我們可以看到使用GenerateIV和GenerateKey方法後 生成了新的密鑰和初始化向量
我們的準備工作完成了 下面要開始真正的加密之旅了 對稱加密需要和CryptoStream類的實例配合 加密流來實現數據加密 NET中的內存流 文件流 網絡流都可以使用 為了示例更明了 我們以AesCryptoServiceProvider類為例 使用內存流來演示如何使用對稱加密類加密 解密數據 先看代碼清單
代碼清單 加密解密數據示例
using System;
using System Collections Generic;
using System Linq;
using System Text;
using System Security Cryptography;
using System IO;
namespace Sample
{
class Program
{
static AesCryptoServiceProvider acsp = new AesCryptoServiceProvider();
static void Main(string[] args)
{
byte[] key = acsp Key;
byte[] iv = acsp IV;
string s = @ xuanhun加密測試 ;
byte[] *** yt = Encoding Default GetBytes(s);
byte []Enb = Encript( *** yt key iv);
byte []Deb = Decript(Enb key iv);
Console WriteLine(Encoding Default GetString(Enb));
Console WriteLine(Encoding Default GetString(Deb));
Console Read();
}
public static byte[] Encript(byte[] s byte[] key byte[] iv)
{
MemoryStream mstream = new MemoryStream();
CryptoStream cstream = new CryptoStream(mstream acsp CreateEncryptor(key iv) CryptoStreamMode Write);
cstream Write(s s Length);
cstream FlushFinalBlock();
byte[] outb = mstream ToArray();
cstream Close();
mstream Close();
return outb ;
}
public static byte[] Decript(byte[] s byte[] key byte[] iv)
{
MemoryStream mtream = new MemoryStream();
CryptoStream deStreame = new CryptoStream(mtream acsp CreateDecryptor(key iv) CryptoStreamMode Write);
deStreame Write(s s Length);
deStreame FlushFinalBlock();
byte[] outs = mtream ToArray();
mtream Close();
deStreame Close();
return outs ;
}
public static byte[] GetByteFromstring(string s)
{
return Encoding Default GetBytes(s);
}
}
}
如代碼清單 我們首先創建了AesCryptoServiceProvider實例 然後再Main方法中使用了局部變量key和iv來保存該實例的加密密鑰和初始化向量 字符串s是要加密的原始字符串 局部變量 *** yte保存了將字符串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方法中 通過Encoding Default GetString方法 獲得加密後的字符串 解密過程與此類似 不再贅述
現在我們看看改程序的運行結果 如圖 所示
圖 代碼清單 運行結果
lishixinzhi/Article/program/net/201311/11895