SecurityHelper 加密解密帮助类

SecurityHelper 帮助类

该帮助类主要实现了 MD5 算法的 加密DES3DESRSA 算法的 加密解密,内部简单实现了一个混淆算法。

MD5 加密算法

MD5 消息摘要算法:全称是 Message-Digest Algorithm,一种被广泛使用的密码散列函数,可以产生出一个 128位16字节)的 散列值hash value),用于确保信息传输完整一致。。

MD5主要用途:

  • 对一段信息生成信息摘要,该摘要对该信息具有唯一性,可以作为数字签名
  • 用于验证文件的有效性(是否有丢失或损坏的数据)
  • 对用户密码的加密
  • 在哈希函数中计算散列值

从上边的主要用途中我们看到,由于算法的某些不可逆特征,在加密应用上有较好的安全性。通过使用 MD5 加密算法,我们输入一个任意长度的字节串,都会生成一个128位 的整数。所以根据这一点 MD5 被广泛的用作密码加密。

SecurityHelper 中调用的方法:

1
string str = SecurityHelper.EncryptByMD5("测试");

DES3DES 加密算法

DES 全称为 Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法。DES 算法的入口参数有三个:KeyDataMode。其中 Key7个字节56位,是 DES算法 的工作密钥;Data8个字节 64位,是要被加密或被解密的数据;ModeDES 的工作方式,有两种:加密或解密。其速度较快,适用于加密大量数据的场合。

SecurityHelper 中调用的方法:

1
2
string encryptStr = SecurityHelper.EncryptByDES("测试");
string str = SecurityHelper.DecryptByDES(encryptStr);

3DES(即 Triple DES)是 DESAES 过渡的加密算法,它使用 3条 56位 的密钥对数据进行 三次加密。是 DES 的一个更安全的变形。它以 DES 为基本模块,通过组合分组方法设计出分组加密算法。比起最初的 DES3DES 更为安全。

SecurityHelper 中调用的方法:

1
2
string encryptStr = SecurityHelper.EncryptByTDES("测试");
string str = SecurityHelper.DecryptByTDES(encryptStr);

RSA 加密算法

RSA 加密算法是一种 非对称 加密算法。在公开密钥加密和电子商业中 RSA 被广泛使用。

RSA 算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作。RSA 是被研究得最广泛的公钥算法,从提出到现今的三十多年里,经历了各种攻击的考验,逐渐为人们接受,截止 2017年 被普遍认为是最优秀的公钥方案之一。

SecurityHelper 中调用的方法:

1
2
3
4
5
// 生成公钥与私钥
var kv = SecurityHelper.GeneralRSAKeys();

string encryptStr = SecurityHelper.EncryptByRSAFromXmlString("测试", kv.Key);
string str = SecurityHelper.DecryptByRSAFromXmlString(encryptStr, kv.Value);

混淆反混淆

当需求对数据的传输有不高的安全加密,且加密的时间复杂度越低越好,这时我们可以使用简单的混淆算法,SecurityHelper 实现了一个简单的混淆算法供开发人员调用。

1
2
string encryptStr = SecurityHelper.MixUp("测试");
string str = SecurityHelper.ClearUp(encryptStr);

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;

namespace System
{
/// <summary>
/// 加密安全帮助类
/// </summary>
public class SecurityHelper
{
/// <summary>
/// MD5加密字符串 (不可逆)
/// </summary>
/// <param name="text">需要加密的内容</param>
/// <param name="key">加密密钥,防止简单密码被破解</param>
/// <param name="binaryStyle">加密后结果内容样式。true:HEX格式加密结果,含“-”;Base64格式加密结果。</param>
/// <returns>加密结果</returns>
public static string EncryptByMD5(string text, string key = default(string), bool binaryStyle = true)
{
MD5 md5 = MD5.Create();
byte[] bytes = md5.ComputeHash(Encoding.UTF8.GetBytes(text + key));
return binaryStyle ? BitConverter.ToString(bytes) : Convert.ToBase64String(bytes);
}

/// <summary>
/// DES加密字符串 (可逆)
/// </summary>
/// <param name="text">待加密的字符串</param>
/// <param name="key">DES加密的私钥,必须是字节长度8位的字符串,否则会补0。</param>
/// <param name="iv">DES加密偏移量,必须是>=8位长的字符串,否则会补0。</param>
/// <param name="binaryStyle">加密后结果内容样式。true:HEX格式加密结果,含“-”;Base64格式加密结果。</param>
/// <returns>加密后的字符串</returns>
public static string EncryptByDES(string text, string key = "", string iv = "", bool binaryStyle = true)
{
List<byte> bKey = Encoding.UTF8.GetBytes(key).ToList();
for (int i = bKey.Count; i < 8; i++)
{
bKey.Add((byte)i);
}
bKey = bKey.GetRange(0, 8);
List<byte> bIV = Encoding.UTF8.GetBytes(iv).ToList();
for (int i = bIV.Count; i < 8; i++)
{
bIV.Add((byte)i);
}
using (DESCryptoServiceProvider des = new DESCryptoServiceProvider())
using (MemoryStream ms = new MemoryStream())
{
byte[] inData = Encoding.UTF8.GetBytes(text);
using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(bKey.ToArray(), bIV.ToArray()), CryptoStreamMode.Write))
{
cs.Write(inData, 0, inData.Length);
cs.FlushFinalBlock();
}
return binaryStyle ? BitConverter.ToString(ms.ToArray()) : Convert.ToBase64String(ms.ToArray());
}
}

/// <summary>
/// DES解密字符串
/// </summary>
/// <param name="text">待解密的字符串</param>
/// <param name="key">DES加密的私钥,必须是字节长度8位的字符串,否则会补0。</param>
/// <param name="iv">DES加密偏移量,必须是>=8位长的字符串,否则会补0。</param>
/// <param name="binaryStyle">解密内容样式。true:HEX格式加密结果,含“-”;Base64格式加密结果。</param>
/// <returns>解密后的字符串</returns>
public static string DecryptByDES(string text, string key = "", string iv = "", bool binaryStyle = true)
{
List<byte> bKey = Encoding.UTF8.GetBytes(key).ToList();
for (int i = bKey.Count; i < 8; i++)
{
bKey.Add((byte)i);
}
bKey = bKey.GetRange(0, 8);
List<byte> bIV = Encoding.UTF8.GetBytes(iv).ToList();
for (int i = bIV.Count; i < 8; i++)
{
bIV.Add((byte)i);
}
using (DESCryptoServiceProvider des = new DESCryptoServiceProvider())
using (MemoryStream ms = new MemoryStream())
{
byte[] inData = binaryStyle ? text.GetBytesFromBitConverter() : Convert.FromBase64String(text);
using (CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(bKey.ToArray(), bIV.ToArray()), CryptoStreamMode.Write))
{
cs.Write(inData, 0, inData.Length);
cs.FlushFinalBlock();
}
return Encoding.UTF8.GetString(ms.ToArray());
}
}

/// <summary>
/// TDES加密字符串 (可逆)
/// </summary>
/// <param name="text">待加密的字符串</param>
/// <param name="key">TDES加密的私钥,必须是字节长度24位的字符串,否则会自动补位。</param>
/// <param name="iv">TDES加密偏移量,必须是字节长度>=8位的字符串,否则会自动补位。</param>
/// <param name="binaryStyle">加密后结果内容样式。true:HEX格式加密结果,含“-”;Base64格式加密结果。</param>
/// <returns>加密后的字符串</returns>
public static string EncryptByTDES(string text, string key = "", string iv = "", bool binaryStyle = true)
{
List<byte> bKey = Encoding.UTF8.GetBytes(key).ToList();
for (int i = bKey.Count; i < 24; i++)
{
bKey.Add((byte)i);
}
bKey = bKey.GetRange(0, 24);
List<byte> bIV = Encoding.UTF8.GetBytes(iv).ToList();
for (int i = bIV.Count; i < 8; i++)
{
bIV.Add((byte)i);
}
using (TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider())
using (MemoryStream ms = new MemoryStream())
{
byte[] inData = Encoding.UTF8.GetBytes(text);
using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(bKey.ToArray(), bIV.ToArray()), CryptoStreamMode.Write))
{
cs.Write(inData, 0, inData.Length);
cs.FlushFinalBlock();
}
return binaryStyle ? BitConverter.ToString(ms.ToArray()) : Convert.ToBase64String(ms.ToArray());
}
}

/// <summary>
/// TDES解密字符串
/// </summary>
/// <param name="text">待解密的字符串</param>
/// <param name="key">TDES加密的私钥,必须是字节长度24位的字符串,否则会自动补位。</param>
/// <param name="iv">TDES加密偏移量,必须是字节长度>=8位的字符串,否则会自动补位。</param>
/// <param name="binaryStyle">解密内容样式。true:HEX格式加密结果,含“-”;Base64格式加密结果。</param>
/// <returns>解密后的字符串</returns>
public static string DecryptByTDES(string text, string key = "", string iv = "", bool binaryStyle = true)
{
List<byte> bKey = Encoding.UTF8.GetBytes(key).ToList();
for (int i = bKey.Count; i < 24; i++)
{
bKey.Add((byte)i);
}
bKey = bKey.GetRange(0, 24);
List<byte> bIV = Encoding.UTF8.GetBytes(iv).ToList();
for (int i = bIV.Count; i < 8; i++)
{
bIV.Add((byte)i);
}
using (TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider())
using (MemoryStream ms = new MemoryStream())
{
byte[] inData = binaryStyle ? text.GetBytesFromBitConverter() : Convert.FromBase64String(text);
using (CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(bKey.ToArray(), bIV.ToArray()), CryptoStreamMode.Write))
{
cs.Write(inData, 0, inData.Length);
cs.FlushFinalBlock();
}
return Encoding.UTF8.GetString(ms.ToArray());
}
}

/// <summary>
/// 获取RSA加密公钥和私钥
/// </summary>
/// <returns>key:公钥 value:公钥和私钥</returns>
public static KeyValuePair<string, string> GeneralRSAKeys()
{
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
return new KeyValuePair<string, string>(rsa.ToXmlString(false), rsa.ToXmlString(true));
}
}

/// <summary>
/// RSA加密字符串 (可逆)
/// </summary>
/// <param name="text">待加密的字符串</param>
/// <param name="name">密钥容器的名称。</param>
/// <param name="binaryStyle">加密后结果内容样式。true:HEX格式加密结果,含“-”;Base64格式加密结果。</param>
/// <returns>加密后的字符串</returns>
public static string EncryptByRSA(string text, string name, bool binaryStyle = true)
{
CspParameters param = new CspParameters() { KeyContainerName = name };
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(param))
{
byte[] plaindata = Encoding.UTF8.GetBytes(text);
byte[] encryptdata = rsa.Encrypt(plaindata, false);
return binaryStyle ? BitConverter.ToString(encryptdata) : Convert.ToBase64String(encryptdata);
}
}

/// <summary>
/// RSA解密字符串
/// </summary>
/// <param name="text">待解密的字符串</param>
/// <param name="name">密钥容器的名称。</param>
/// <param name="binaryStyle">解密内容样式。true:HEX格式加密结果,含“-”;Base64格式加密结果。</param>
/// <returns>解密后的字符串</returns>
public static string DecryptByRSA(string text, string name, bool binaryStyle = true)
{
CspParameters param = new CspParameters() { KeyContainerName = name };
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(param))
{
byte[] encryptdata = binaryStyle ? text.GetBytesFromBitConverter() : Convert.FromBase64String(text);
byte[] decryptdata = rsa.Decrypt(encryptdata, false);
return Encoding.UTF8.GetString(decryptdata);
}
}

/// <summary>
/// RSA加密字符串 (可逆)
/// </summary>
/// <param name="text">待加密的字符串</param>
/// <param name="xml">含有密钥信息的xml字符串。</param>
/// <param name="binaryStyle">加密后结果内容样式。true:HEX格式加密结果,含“-”;Base64格式加密结果。</param>
/// <returns>加密后的字符串</returns>
public static string EncryptByRSAFromXmlString(string text, string xml, bool binaryStyle = true)
{
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
rsa.FromXmlString(xml);
byte[] plaindata = Encoding.UTF8.GetBytes(text);
byte[] encryptdata = rsa.Encrypt(plaindata, false);
return binaryStyle ? BitConverter.ToString(encryptdata) : Convert.ToBase64String(encryptdata);
}
}

/// <summary>
/// RSA解密字符串
/// </summary>
/// <param name="text">待解密的字符串</param>
/// <param name="xml">含有密钥信息的xml字符串。</param>
/// <param name="binaryStyle">解密内容样式。true:HEX格式加密结果,含“-”;Base64格式加密结果。</param>
/// <returns>解密后的字符串</returns>
public static string DecryptByRSAFromXmlString(string text, string xml, bool binaryStyle = true)
{
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
rsa.FromXmlString(xml);
byte[] encryptdata = binaryStyle ? text.GetBytesFromBitConverter() : Convert.FromBase64String(text);
byte[] decryptdata = rsa.Decrypt(encryptdata, false);
return Encoding.UTF8.GetString(decryptdata);
}
}

/// <summary>
/// 用时间简单混淆
/// </summary>
/// <param name="text">原始文本</param>
/// <param name="timestampLength">混淆用时间戳长度</param>
/// <returns>混淆后文本</returns>
public static string MixUp(string text,int timestampLength = 36)
{
var timestamp = Guid.NewGuid().ToString();
var count = text.Length + timestampLength;
var sbd = new StringBuilder(count);
int j = 0;
int k = 0;
for (int i = 0; i < count; i++)
{
if (j < timestampLength && k < text.Length)
{
if (i % 2 == 0)
{
sbd.Append(text[k]);
k++;
}
else
{
sbd.Append(timestamp[j]);
j++;
}
}
else if (j >= timestampLength)
{
sbd.Append(text[k]);
k++;
}
else if (k >= text.Length)
{
break;
}
}

return sbd.ToString();
}

/// <summary>
/// 简单反混淆
/// </summary>
/// <param name="text">需要执行反混淆的文本</param>
/// <param name="timestampLength">混淆用时间戳长度</param>
/// <returns>原始文本</returns>
public static string ClearUp(string text, int timestampLength = 36)
{
var sbd = new StringBuilder();
int j = 0;
for (int i = 0; i < text.Length; i++)
{
if (i % 2 == 0)
{
sbd.Append(text[i]);
}
else
{
j++;
}

if (j > timestampLength)
{
sbd.Append(text.Substring(i));
break;
}
}

return sbd.ToString();
}
}
}

注意: 刚刚发现部分代码调用了我自己封装的一个扩展方法的文件,主要是字符串与二进制流转换的处理,可以根据方法名含义自行调整对应方法,后面我也会将这部分代码上传上来,这里就偷个懒不做修改了。