如何创建加密库

目标

本章的目标是:

创建一个通用加密库,以便使用 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 类的操作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值