《企业考试系统》项目实践(03):通用工具类库之对称加密算法
摘要:实现通用的对称加密算法工具类。
在.Net Framework中与安全、加密相关的共有三大类:
- Hash算法:将一个流使用Hash算法计算其相应的Hash值,我们最常见的MD5、SHA1均属于Hash算法。
- 对称算法:顾名思义,可以双向对一个流(Byte数组)进行加密和解密操作,本文主要使用的就是此算法
- 非对称算法:只能单向“加密”一个流(Byte数组),而不能反向解密
在.Net Framework中,涉及对称加密的算法的类有如下一些,其继承结构图为:
其中: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: }
此类的类成员为:
- 构造方法有三个参数:一个为使用的对称加密算法的类型,后两个是对称加密算法对应的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: }
测试结果如下:
本文源代码下载
https://files.cnblogs.com/DragonInSea/ExamSolution_03.rar
本文版权归作者所有,未经同意,请勿用作商业用途。