《企业考试系统》项目实践(03):通用工具类库之对称加密算法

摘要:实现通用的对称加密算法工具类。

 

在.Net Framework中与安全、加密相关的共有三大类:

  • Hash算法:将一个流使用Hash算法计算其相应的Hash值,我们最常见的MD5、SHA1均属于Hash算法。
  • 对称算法:顾名思义,可以双向对一个流(Byte数组)进行加密和解密操作,本文主要使用的就是此算法
  • 非对称算法:只能单向“加密”一个流(Byte数组),而不能反向解密

在.Net Framework中,涉及对称加密的算法的类有如下一些,其继承结构图为:

1

其中:SymmetricAlgorithm类为对称算法的根类,其子类为几种对称加密算法,再子类是具体的实现类。

 

使用对称加密算法实现对称加密时,代码基本类似,我将其封装一下,定义两个类型:

  • SymmetricCryptographyTypeEnum枚举:表示系统支持的对称加密类型
  • SymmetricCryptographyUtility类:提供对于Byte数组及字符串进行加密及解密的方法

SymmetricCryptographyTypeEnum枚举的定义如下:

   1: namespace DHC_Certification_System.CommonLibrary.SymmetricCryptography
   2: {
   3:     /// <summary>
   4:     /// 使用的对称加密类型
   5:     /// </summary>
   6:     public enum SymmetricCryptographyTypeEnum
   7:     {
   8:         DESCryptoServiceProvider,
   9:         AesCryptoServiceProvider,
  10:         RC2CryptoServiceProvider,
  11:         RijndaelManaged,
  12:         TripleDESCryptoServiceProvider
  13:     }
  14: }

SymmetricCryptographyUtility类定义如下:

   1: using System;
   2: using System.IO;
   3: using System.Security.Cryptography;
   4: using System.Text;
   5:  
   6: namespace DHC_Certification_System.CommonLibrary.SymmetricCryptography
   7: {
   8:     /// <summary>
   9:     /// 对称加密工具类
  10:     /// </summary>
  11:     public sealed class SymmetricCryptographyUtility
  12:     {
  13:         /// <summary>
  14:         /// 对称加密类的驱动类型
  15:         /// </summary>
  16:         private readonly SymmetricAlgorithm _Provider;
  17:  
  18:         /// <summary>
  19:         /// 构造方法,使用自定义的的IV和KEY
  20:         /// </summary>
  21:         /// <param name="cryptType">使用的加密算法</param>
  22:         /// <param name="iv">IV值</param>
  23:         /// <param name="key">KEY值</param>
  24:         public SymmetricCryptographyUtility(
  25:             SymmetricCryptographyTypeEnum cryptType,
  26:             byte[] iv, byte[] key)
  27:         {
  28:             switch (cryptType)
  29:             {
  30:                 case SymmetricCryptographyTypeEnum.DESCryptoServiceProvider:
  31:                     _Provider = new DESCryptoServiceProvider();
  32:                     break;
  33:                 case SymmetricCryptographyTypeEnum.AesCryptoServiceProvider:
  34:                     _Provider = new AesCryptoServiceProvider();
  35:                     break;
  36:                 case SymmetricCryptographyTypeEnum.RC2CryptoServiceProvider:
  37:                     _Provider = new RC2CryptoServiceProvider();
  38:                     break;
  39:                 case SymmetricCryptographyTypeEnum.RijndaelManaged:
  40:                     _Provider = new RijndaelManaged();
  41:                     break;
  42:                 case SymmetricCryptographyTypeEnum.TripleDESCryptoServiceProvider:
  43:                     _Provider = new TripleDESCryptoServiceProvider();
  44:                     break;
  45:             }
  46:  
  47:             _Provider.IV = iv;
  48:             _Provider.Key = key;
  49:         }
  50:  
  51:         public SymmetricAlgorithm Provider
  52:         {
  53:             get
  54:             {
  55:                 return _Provider;
  56:             }
  57:         }
  58:  
  59:         /// <summary>
  60:         /// 加密字符串
  61:         /// </summary>
  62:         /// <param name="input"></param>
  63:         /// <returns></returns>
  64:         public string EncryptBase64String(string input)
  65:         {
  66:             string result = null;
  67:  
  68:             if (string.IsNullOrEmpty(input) == false)
  69:             {
  70:                 byte[] inputArray = Encoding.Unicode.GetBytes(input);
  71:                 byte[] cryptArray = EncryptByteArray(inputArray);
  72:  
  73:                 result = Convert.ToBase64String(cryptArray);
  74:             }
  75:  
  76:             return result;
  77:         }
  78:  
  79:         /// <summary>
  80:         /// 解密字符串
  81:         /// </summary>
  82:         /// <param name="input"></param>
  83:         /// <returns></returns>
  84:         public string DecryptBase64String(string input)
  85:         {
  86:             string result = null;
  87:  
  88:             if (string.IsNullOrEmpty(input) == false)
  89:             {
  90:                 byte[] inputArray = Convert.FromBase64String(input);
  91:                 byte[] cryptArray = DecryptByteArray(inputArray);
  92:  
  93:                 result = Encoding.Unicode.GetString(cryptArray);
  94:             }
  95:  
  96:             return result;
  97:         }
  98:  
  99:         /// <summary>
 100:         /// 加密Byte数组
 101:         /// </summary>
 102:         /// <param name="input"></param>
 103:         /// <returns></returns>
 104:         public byte[] EncryptByteArray(byte[] input)
 105:         {
 106:             MemoryStream ms = new MemoryStream();
 107:  
 108:             CryptoStream cs = new CryptoStream(
 109:                 ms, _Provider.CreateEncryptor(), CryptoStreamMode.Write);
 110:  
 111:             cs.Write(input, 0, input.Length);
 112:             cs.FlushFinalBlock();
 113:  
 114:             byte[] result = ms.ToArray();
 115:  
 116:             cs.Close();
 117:             ms.Close();
 118:  
 119:             return result;
 120:         }
 121:  
 122:         /// <summary>
 123:         /// 解密Byte数组
 124:         /// </summary>
 125:         /// <param name="input"></param>
 126:         /// <returns></returns>
 127:         public byte[] DecryptByteArray(byte[] input)
 128:         {
 129:             MemoryStream ms = new MemoryStream();
 130:  
 131:             CryptoStream cs = new CryptoStream(
 132:                 ms, _Provider.CreateDecryptor(), CryptoStreamMode.Write);
 133:  
 134:             cs.Write(input, 0, input.Length);
 135:             cs.FlushFinalBlock();
 136:  
 137:             byte[] result = ms.ToArray();
 138:  
 139:             cs.Close();
 140:             ms.Close();
 141:  
 142:             return result;
 143:         }
 144:     }
 145: }

此类的类成员为:

2

  • 构造方法有三个参数:一个为使用的对称加密算法的类型,后两个是对称加密算法对应的IV及KEY值(需要注意的是,不同的算法要求的IV和KEY使用的Byte数组的长度不同,具体可查阅MSDN)
  • EncryptByteArray和DecryptByteArray两个方法是针对于Byte数组的加密与解密
  • EncryptBase64String和DecryptBase64String两个方法是针对于字符串的加密与解密

 

定义如下的单体测试代码:

   1: using System;
   2: using System.Text;
   3: using CommonUtilityLibrary.SymmetricCryptography;
   4: using Microsoft.VisualStudio.TestTools.UnitTesting;
   5:  
   6: namespace ExamSolution.SolutionUnitTestProject.CommonUtilityLibrary.SymmetricCryptography
   7: {
   8:     /// <summary>
   9:     /// 对称加密算法加密、解密测试
  10:     /// </summary>
  11:     [TestClass]
  12:     public class SymmetricCryptUnitTest
  13:     {
  14:         #region 各种Provider的对称加字算法的默认IV和KEY
  15:         private const string IV_DESCRYPTOSERVICEPROVIDER = @"/KiP+1c5dZA=";
  16:         private const string KEY_DESCRYPTOSERVICEPROVIDER = @"AuNOICVT27g=";
  17:  
  18:         private const string IV_AESCRYPTOSERVICEPROVIDER = @"xMHcVFe6M0cFuj2XwDxW4g==";
  19:         private const string KEY_AESCRYPTOSERVICEPROVIDER = @"2lrJwsLB3yejIqaxp5AHo+KFIzQnHbMG6bJB70L4bfo=";
  20:  
  21:         private const string IV_RC2CRYPTOSERVICEPROVIDER = @"SfcSRMSyCD4=";
  22:         private const string KEY_RC2CRYPTOSERVICEPROVIDER = @"IN4Gg2FNrlEl82VRUBewaA==";
  23:  
  24:         private const string IV_RIJNDAELMANAGED = @"bv28soM12cTLKd1ObZV5RA==";
  25:         private const string KEY_RIJNDAELMANAGED = @"u7R7DbMcCrh9MynjARrEsr0wIUFy9GujyHddE2k7Ric=";
  26:  
  27:         private const string IV_TRIPLEDESCRYPTOSERVICEPROVIDER = @"cd8FQK7xXDk=";
  28:         private const string KEY_TRIPLEDESCRYPTOSERVICEPROVIDER = @"RpbofS6+6f1cE6HzpoAhmZ8kM0PXvNS/";
  29:         #endregion
  30:  
  31:         /// <summary>
  32:         /// 测试方法
  33:         /// </summary>
  34:         [TestMethod]
  35:         public void SymmetricCryptographyUtility()
  36:         {
  37:             Console.WriteLine("测试开始:");
  38:  
  39:             string baseString = "Hello World";
  40:             byte[] baseByte = new byte[] {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
  41:  
  42:             Console.WriteLine("原始字符串为:{0}",baseString);
  43:             Console.WriteLine("原始Byte数组为:{0}", ConvertByteToHexString(baseByte));
  44:  
  45:             SymmetricCryptographyUtility[] crypts = new SymmetricCryptographyUtility[5];
  46:  
  47:             crypts[0] = new SymmetricCryptographyUtility(
  48:                 SymmetricCryptographyTypeEnum.DESCryptoServiceProvider,
  49:                 Convert.FromBase64String(IV_DESCRYPTOSERVICEPROVIDER), 
  50:                 Convert.FromBase64String(KEY_DESCRYPTOSERVICEPROVIDER));
  51:             crypts[1] = new SymmetricCryptographyUtility(
  52:                 SymmetricCryptographyTypeEnum.AesCryptoServiceProvider,
  53:                 Convert.FromBase64String(IV_AESCRYPTOSERVICEPROVIDER),
  54:                 Convert.FromBase64String(KEY_AESCRYPTOSERVICEPROVIDER));
  55:             crypts[2] = new SymmetricCryptographyUtility(
  56:                 SymmetricCryptographyTypeEnum.RC2CryptoServiceProvider,
  57:                 Convert.FromBase64String(IV_RC2CRYPTOSERVICEPROVIDER),
  58:                 Convert.FromBase64String(KEY_RC2CRYPTOSERVICEPROVIDER));
  59:             crypts[3] = new SymmetricCryptographyUtility(
  60:                 SymmetricCryptographyTypeEnum.RijndaelManaged,
  61:                 Convert.FromBase64String(IV_RIJNDAELMANAGED),
  62:                 Convert.FromBase64String(KEY_RIJNDAELMANAGED));
  63:             crypts[4] = new SymmetricCryptographyUtility(
  64:                 SymmetricCryptographyTypeEnum.TripleDESCryptoServiceProvider,
  65:                 Convert.FromBase64String(IV_TRIPLEDESCRYPTOSERVICEPROVIDER),
  66:                 Convert.FromBase64String(KEY_TRIPLEDESCRYPTOSERVICEPROVIDER));
  67:  
  68:             foreach (SymmetricCryptographyUtility crypt in crypts)
  69:             {
  70:                 Console.WriteLine("====================================================");
  71:                 Console.WriteLine("加密算法的类型为:{0}", crypt.Provider.GetType().Name);
  72:  
  73:                 string cryptString = crypt.EncryptBase64String(baseString);
  74:                 string deCryptString = crypt.DecryptBase64String(cryptString);
  75:                 Console.WriteLine("加密后的字符串为:{0}",cryptString);
  76:                 Console.WriteLine("解密后的字符串为:{0}", deCryptString);
  77:  
  78:                 byte[] cryptByte = crypt.EncryptByteArray(baseByte);
  79:                 byte[] deCryptByte = crypt.DecryptByteArray(cryptByte);
  80:                 Console.WriteLine("加密后的Byte数组为:{0}", ConvertByteToHexString(cryptByte));
  81:                 Console.WriteLine("解密后的Byte数组为:{0}", ConvertByteToHexString(deCryptByte));
  82:             }
  83:         }
  84:  
  85:         /// <summary>
  86:         /// 将Byte数组转换为字符串,其中每个Byte转换为两位十六进制的数字表示的字符串
  87:         /// </summary>
  88:         /// <param name="items"></param>
  89:         /// <returns></returns>
  90:         private string ConvertByteToHexString(byte[] items)
  91:         {
  92:             StringBuilder builder = new StringBuilder();
  93:             foreach (byte item in items)
  94:             {
  95:                 builder.Append(item.ToString("X2"));
  96:             }
  97:             return builder.ToString();
  98:         }
  99:     }
 100: }

测试结果如下:

3

本文源代码下载

https://files.cnblogs.com/DragonInSea/ExamSolution_03.rar

 

《企业考试系统》项目实践索引页:http://www.cnblogs.com/DragonInSea/archive/2010/06/02/1749762.html
posted @ 2010-06-02 14:48  龙腾于海  阅读(2958)  评论(3编辑  收藏  举报