夜的第七章

WEB开发个人博客。

« Jmail乱码问题idHook参数的取值 »

如何创建加密库

如何创建加密库

更新日期: 2004年04月20日
 
本页内容

目标 目标
适用范围 适用范围
如何使用本章内容 如何使用本章内容
摘要 摘要
创建 Visual C# 类库 创建 Visual C# 类库
创建控制台测试应用程序 创建控制台测试应用程序
其他资源 其他资源

目标

本章的目标是:

创建一个通用加密库,以便使用 DES(数字加密标准)、三重 DES、Rijndeal 或 RC2 算法对数据进行加密和解密。

在应用程序中使用加密库。

适用范围

本章适用于以下产品和技术:

Microsoft Windows® XP 或 Windows 2000 Server (Service Pack 3) 以及更高版本的操作系统

.NET Framework 版本 1.0 (Service Pack 2) 和更高版本

Microsoft Visual C#® .NET

如何使用本章内容

本章详细介绍了使用 Visual C# 创建通用加密库的步骤及所需的代码。若要学好本章内容:

您必须具有使用 Visual C# .NET 和 Microsoft Visual Studio® .NET 的经验。

阅读如何在注册表中存储加密的连接字符串,以了解有关如何使用本章所介绍的库的示例。

摘要

Microsoft(r) .NET Framework 为各种最广泛使用的对称加密算法提供了支持。用于表示这些算法的类结构完善并提供了通用的使用模式。这意味着,您不必在每个应用程序中编写代码来对机密数据进行加密和解密,只需轻松创建一个可重复使用的库,就可以使用任何可用的对称加密算法来加密和解密数据。本章将介绍如何创建这类库。

创建 Visual C# 类库

此过程将创建 Visual C# 类库,以提供加密和解密功能。

创建 Visual C# 类库

1.

启动 Visual Studio .NET 并创建一个新的名为 Encryption 的 Visual C# 类库项目。

2.

使用解决方案资源管理器将 class1.cs 重命名为 EncryptTransformer.cs。

3.

在 EncryptTransformer.cs 中,将 Class1 重命名为 EncryptTransformer

4.

将该类的作用域由 public 更改为 internal

internal class EncryptTransformer

5.

在文件的顶部添加以下 using 语句。

using System.Security.Cryptography;

6.

将以下枚举类型添加到 Encryption 命名空间中。

public enum EncryptionAlgorithm {Des = 1, Rc2, Rijndael, TripleDes};

7.

将下面的私有成员变量添加到 EncryptTransformer 类中。

private EncryptionAlgorithm algorithmID;private byte[] initVec;private byte[] encKey;

8.

用下面的构造函数替换默认构造函数。

internal EncryptTransformer(EncryptionAlgorithm algId){  //保存正在使用的算法。  algorithmID = algId;}

9.

将下面的方法添加到该类。

internal ICryptoTransform GetCryptoServiceProvider(byte[] bytesKey){  // 选取提供程序。  switch (algorithmID)  {    case EncryptionAlgorithm.Des:    {      DES des = new DESCryptoServiceProvider();      des.Mode = CipherMode.CBC;      // 查看是否提供了密钥      if (null == bytesKey)      {        encKey = des.Key;      }      else      {        des.Key = bytesKey;        encKey = des.Key;      }      // 查看客户端是否提供了初始化向量      if (null == initVec)      { // 让算法创建一个        initVec = des.IV;      }      else      { //不,将它提供给算法        des.IV = initVec;      }      return des.CreateEncryptor();    }    case EncryptionAlgorithm.TripleDes:    {      TripleDES des3 = new TripleDESCryptoServiceProvider();      des3.Mode = CipherMode.CBC;      // See if a key was provided      if (null == bytesKey)      {        encKey = des3.Key;      }      else      {        des3.Key = bytesKey;        encKey = des3.Key;      }      // 查看客户端是否提供了初始化向量      if (null == initVec)      { //是,让算法创建一个        initVec = des3.IV;      }      else      { //不,将它提供给算法。        des3.IV = initVec;      }      return des3.CreateEncryptor();    }    case EncryptionAlgorithm.Rc2:    {      RC2 rc2 = new RC2CryptoServiceProvider();      rc2.Mode = CipherMode.CBC;      // 测试是否提供了密钥      if (null == bytesKey)      {        encKey = rc2.Key;      }      else      {        rc2.Key = bytesKey;        encKey = rc2.Key;      }      // 查看客户端是否提供了初始化向量      if (null == initVec)      { //是,让算法创建一个        initVec = rc2.IV;      }      else      { //不,将它提供给算法。        rc2.IV = initVec;      }      return rc2.CreateEncryptor();    }    case EncryptionAlgorithm.Rijndael:    {      Rijndael rijndael = new RijndaelManaged();      rijndael.Mode = CipherMode.CBC;      // 测试是否提供了密钥      if(null == bytesKey)      {        encKey = rijndael.Key;      }      else      {        rijndael.Key = bytesKey;        encKey = rijndael.Key;      }      // 查看客户端是否提供了初始化向量      if(null == initVec)      { //是,让算法创建一个        initVec = rijndael.IV;      }      else      { //不,将它提供给算法。        rijndael.IV = initVec;      }      return rijndael.CreateEncryptor();    }     default:    {      throw new CryptographicException("算法 ID '" + algorithmID +                                        "' 不受支持。");    }  }}

10.

将下面的属性添加到该类。

internal byte[] IV{  get{return initVec;}  set{initVec = value;}}internal byte[] Key{  get{return encKey;}}

11.

将名为 DecryptTransformer 的新类添加到项目中。

12.

在 DecryptTransformer.cs 文件的顶部添加以下 using 语句。

using System.Security.Cryptography;

13.

将类作用域由 public 更改为 internal

14.

用下面的构造函数替换默认构造函数。

internal DecryptTransformer(EncryptionAlgorithm deCryptId){  algorithmID = deCryptId;}

15.

将下面的私有变量添加到该类。

private EncryptionAlgorithm algorithmID;private byte[] initVec;

16.

将下面的方法添加到该类。

internal ICryptoTransform GetCryptoServiceProvider(byte[] bytesKey){  // Pick the provider.  switch (algorithmID)  {    case EncryptionAlgorithm.Des:    {      DES des = new DESCryptoServiceProvider();      des.Mode = CipherMode.CBC;      des.Key = bytesKey;      des.IV = initVec;      return des.CreateDecryptor();    }    case EncryptionAlgorithm.TripleDes:    {      TripleDES des3 = new TripleDESCryptoServiceProvider();      des3.Mode = CipherMode.CBC;      return des3.CreateDecryptor(bytesKey, initVec);    }    case EncryptionAlgorithm.Rc2:    {      RC2 rc2 = new RC2CryptoServiceProvider();      rc2.Mode = CipherMode.CBC;      return rc2.CreateDecryptor(bytesKey, initVec);    }    case EncryptionAlgorithm.Rijndael:    {      Rijndael rijndael = new RijndaelManaged();      rijndael.Mode = CipherMode.CBC;      return rijndael.CreateDecryptor(bytesKey, initVec);    }     default:    {      throw new CryptographicException("算法 ID '" + algorithmID +                                        "' 不支持。");    }  }} //end GetCryptoServiceProvider

17.

将下面的属性添加到该类。

internal byte[] IV{  set{initVec = value;}}

18.

将名为 Encryptor 的新类添加到项目中。

19.

在 Encryptor.cs 的顶部添加以下 using 语句。

using System.Security.Cryptography;using System.IO;

20.

用下面的构造函数替换默认构造函数。

public Encryptor(EncryptionAlgorithm algId){  transformer = new EncryptTransformer(algId);}

21.

将下面的私有成员变量添加到该类。

private EncryptTransformer transformer;private byte[] initVec;private byte[] encKey;

22.

将下面的 Encrypt 方法添加到该类。

public byte[] Encrypt(byte[] bytesData, byte[] bytesKey){  //设置将保存加密数据的流。  MemoryStream memStreamEncryptedData = new MemoryStream();  transformer.IV = initVec;  ICryptoTransform transform = transformer.GetCryptoServiceProvider  (bytesKey);  CryptoStream encStream = new CryptoStream(memStreamEncryptedData,                                             transform,                                             CryptoStreamMode.Write);  try  {    //加密数据,并将它们写入内存流。    encStream.Write(bytesData, 0, bytesData.Length);  }  catch(Exception ex)  {    throw new Exception("将加密数据写入流时     出错: \n"                         + ex.Message);  }  //为客户端进行检索设置初始化向量和密钥  encKey = transformer.Key;  initVec = transformer.IV;  encStream.FlushFinalBlock();  encStream.Close();  //发送回数据。  return memStreamEncryptedData.ToArray();}//end Encrypt

23.

将下面的属性添加到该类。

public byte[] IV{  get{return initVec;}  set{initVec = value;}}public byte[] Key{  get{return encKey;}}

24.

将名为 Decryptor 的新类添加到项目中。

25.

在 Decryptor.cs 的顶部添加以下 using 语句

using System.Security.Cryptography;using System.IO;

26.

用下面的构造函数替换默认构造函数。

public Decryptor(EncryptionAlgorithm algId){  transformer = new DecryptTransformer(algId);}

27.

将下面的私有成员变量添加到该类。

private DecryptTransformer transformer;private byte[] initVec;

28.

将下面的 Decrypt 方法添加到该类。

public byte[] Decrypt(byte[] bytesData, byte[] bytesKey){  //为解密数据设置内存流。  MemoryStream memStreamDecryptedData = new MemoryStream();  //传递初始化向量。  transformer.IV = initVec;  ICryptoTransform transform = transformer.GetCryptoServiceProvider  (bytesKey);  CryptoStream decStream = new CryptoStream(memStreamDecryptedData,                                             transform,                                             CryptoStreamMode.Write);  try  {    decStream.Write(bytesData, 0, bytesData.Length);  }  catch(Exception ex)  {    throw new Exception("将加密数据写入流时    出错: \n"                         + ex.Message);  }  decStream.FlushFinalBlock();  decStream.Close();  // 发送回数据。  return memStreamDecryptedData.ToArray();} //end Decrypt

29.

将下面的属性添加到该类。

public byte[] IV{  set{initVec = value;}}

30.

在“生成”菜单中,单击“生成解决方案”。

创建控制台测试应用程序

此过程创建一个简单的控制台测试应用程序以测试加密和解密功能。

创建控制台测试应用程序

1.

将一个新的名为 EncryptionTester 的 Visual C# 控制台应用程序添加到当前解决方案中。

2.

在解决方案资源管理器中,右键单击 EncryptionTester 项目,然后单击“设为启动项目”。

3.

使用解决方案资源管理器将 class1.cs 重命名为 EncryptionTest.cs。

4.

在 EncryptionTest.cs 中,将 Class1 重命名为 EncryptionTest

5.

添加对 Encryption 项目的项目引用。

6.

在 EncryptionTest.cs 的顶部添加以下 using 语句。

using System.Text;using Encryption;

7.

将以下代码添加到 Main 方法中。

// 设置需要的算法EncryptionAlgorithm algorithm = EncryptionAlgorithm.Des;// Init variables.byte[] IV = null;byte[] cipherText = null;byte[] key = null;try{ //试图加密。  //创建 Encryptor。  Encryptor enc = new Encryptor(EncryptionAlgorithm.Des);  byte[] plainText = Encoding.ASCII.GetBytes("测试字符串");  if ((EncryptionAlgorithm.TripleDes == algorithm) ||       (EncryptionAlgorithm.Rijndael == algorithm))  { //3Des 仅与 16 或 24 字节密钥一起使用。    key = Encoding.ASCII.GetBytes("password12345678");    if (EncryptionAlgorithm.Rijndael == algorithm)    { // 对于 Rijndael,必须为 16 字节。      IV = Encoding.ASCII.GetBytes("init vec is big.");    }    else    {      IV = Encoding.ASCII.GetBytes("init vec");    }  }  else  { //Des 仅使用 8 字节的密钥。其他使用长度可变的密钥。    //将密钥设置为空以生成一个新密钥。    key = Encoding.ASCII.GetBytes("password");    IV = Encoding.ASCII.GetBytes("init vec");  }  // 取消注释后面的行,为您生成密钥或初始化向量。  // key = null;  // IV = null;  enc.IV = IV;  // Perform the encryption.  cipherText = enc.Encrypt(plainText, key);  // 检索初始化向量和密钥。您将需要它   // 进行解密。  IV = enc.IV;  key = enc.Key;  // 查看您的加密文本和初始化向量。  Console.WriteLine("          密码文本: " +                     Convert.ToBase64String(cipherText));  Console.WriteLine("初始化向量: " + Convert.ToBase64  String(IV));  Console.WriteLine("                  Key: " + Convert.ToBase64  String(key));}catch(Exception ex){  Console.WriteLine("加密时发生异常. " + ex.Message);  return;}try{ //试图解密。  //设置您的解密,将它提供给算法和初始化   向量。  Decryptor dec = new Decryptor(algorithm);  dec.IV = IV;  // 继续并解密。  byte[] plainText = dec.Decrypt(cipherText, key);  // 查看您的纯文本。  Console.WriteLine("           纯文本: " +                     Encoding.ASCII.GetString(plainText));}catch(Exception ex){  Console.WriteLine("解密时发生异常。 " + ex.Message);  return;}

8.

在“生成”菜单中,单击“生成解决方案”。

9.

运行测试应用程序以验证 Encryptor Decryptor 类的操作。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。



[2007 - 2011] © Leadnt.com