.NET中的加密類(對稱加密)
對象層次結構
.NET Framework 安全係統實現可擴展模式的派生類繼承。層次結構如下所示:
算法類型類,例如 SymmetricAlgorithm 或 HashAlgorithm。該級別為抽象。
從算法類型類繼承的算法類,例如 RC2 或 SHA1。該級別為抽象。
從算法類繼承的算法類的實現,例如 RC2CryptoServiceProvider 或 SHA1Managed。該級別是完全實現的。
使用這種模式的派生類,很容易添加新算法或現有算法的新實現。例如,若要創建新的公鑰算法,則應從 AsymmetricAlgorithm 類繼承。若要創建特定算法的新實現,應創建該算法的非抽象派生類。
流設計
公共語言運行庫使用麵向流的設計實現對稱算法和哈希算法。此設計的核心是 CryptoStream 類,它派生自 Stream 類。基於流的加密對象全都支持用於處理對象的數據傳輸部分的單個標準接口 (CryptoStream)。由於所有對象都在標準接口上生成,所以可以將多個對象(如一個哈希對象後跟一個加密對象)鏈接在一起,並且可以對數據執行多個操作而不需要為數據提供任何中間存儲。使用流模型時還可以用更小的對象生成對象。例如,可以將加密算法和哈希算法的組合視為單個流對象(即使該對象可能是從一組流對象生成的)。
下麵以一個靜態加密類為例(注釋說明):
【對稱加密】
public static class SymmetricEncryptionUtility
{
private static bool _ProtectKey;//是否需要使用DPAPI來保護密鑰;
private static string _AlgorithmName;//加密算法的名稱;
public static string AlgorithmName
{
get { return _AlgorithmName; }
set { _AlgorithmName = value; }
}
public static bool ProtectKey
{
get { return _ProtectKey; }
set { _ProtectKey = value; }
}
/// <summary>
///【根據加密算法類來生成密鑰文件】;
/// </summary>
/// <param name="targetFile">保存密鑰的文件</param>
public static void GenerateKey(string targetFile)
{
//創建加密算法;
SymmetricAlgorithm Algorithm = SymmetricAlgorithm.Create(AlgorithmName);
Algorithm.GenerateKey();//當在派生類中重寫時,生成用於該算法的隨機密鑰;
//得到密鑰;
byte[] Key = Algorithm.Key;
if (ProtectKey)
{
//使用DPAPI來加密密鑰;
Key = ProtectedData.Protect(Key, null, DataProtectionScope.LocalMachine);
}
//把密鑰保存到key.config。
using (FileStream fs = new FileStream(targetFile, FileMode.Create))
{
fs.Write(Key, 0, Key.Length);
}
}
/// <summary>
/// 【從密鑰文件中讀取密鑰】;
/// </summary>
/// <param name="algorithm">加密的算法</param>
/// <param name="keyFile">密鑰文件路徑</param>
public static void ReadKey(SymmetricAlgorithm algorithm, string keyFile)
{
byte[] Key;
using (FileStream fs = new FileStream(keyFile, FileMode.Open))
{
Key = new byte[fs.Length];
fs.Read(Key, 0, (int)fs.Length);
}
if (ProtectKey)
algorithm.Key = ProtectedData.Unprotect(Key, null, DataProtectionScope.LocalMachine);
else
algorithm.Key = Key;
}
/// <summary>
/// 【加密數據】
/// </summary>
/// <param name="data">原始數據</param>
/// <param name="keyFile">密鑰文件路徑</param>
/// <returns></returns>
public static byte[] EncryptData(string data, string keyFile)
{
//將要加密的字符串數據轉換為字符數組;
byte[] ClearData = Encoding.UTF8.GetBytes(data);
//創建加密算法;
SymmetricAlgorithm Algorithm = SymmetricAlgorithm.Create(AlgorithmName);
ReadKey(Algorithm, keyFile);
//加密信息;
MemoryStream Target = new MemoryStream();
//生成隨機的初始化向量;
Algorithm.GenerateIV();
Target.Write(Algorithm.IV, 0, Algorithm.IV.Length);
//加密實際的數據;
CryptoStream cs = new CryptoStream(Target, Algorithm.CreateEncryptor(), CryptoStreamMode.Write);
//參數1:對其執行加密轉換的流。
//參數2:要對流執行的加密轉換。
//參數3:對加密流的訪問方式。
cs.Write(ClearData, 0, ClearData.Length);
cs.FlushFinalBlock();
//將加密後的結果作為字符數組返回;
return Target.ToArray();
}
/// <summary>
/// 【解密數據】
/// </summary>
/// <param name="data">原始數據</param>
/// <param name="keyFile">密鑰文件路徑</param>
/// <returns></returns>
public static string DecryptData(byte[] data, string keyFile)
{
// 對稱加密:加密算法和解密算法一致;
SymmetricAlgorithm Algorithm = SymmetricAlgorithm.Create(AlgorithmName);
ReadKey(Algorithm, keyFile);
// 解密信息;
MemoryStream Target = new MemoryStream();
// 讀取IV,並使用它初始化解密算法;
int ReadPos = 0;
byte[] IV = new byte[Algorithm.IV.Length];
Array.Copy(data, IV, IV.Length);
Algorithm.IV = IV;
ReadPos += Algorithm.IV.Length;
CryptoStream cs = new CryptoStream(Target, Algorithm.CreateDecryptor(), CryptoStreamMode.Write);
cs.Write(data, ReadPos, data.Length - ReadPos);
cs.FlushFinalBlock();
// 從內存數據流中獲得字節並將它轉換為文本;
return Encoding.UTF8.GetString(Target.ToArray());
}
}
最後更新:2017-04-02 04:01:44