.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