一、对称加密算法概念
我们通过计算机网络传输数据时,如果无法防止他人窃听, 可以利用密码学技术将发送的数据变换成对任何不知道如何做逆变换的人都不可理解的形式, 从而保证了数据的机密性。这种变换被称为加密( encryption),被加密的数据被称为密 文( ciphertext),而加密前的数据被称为明文( plaintext)。 接收方必须能通过某种逆变换将密文重新变换回原来的明文,该逆变换被称为解密( decryption)。加密和解密过程可以以一个密钥( key)为参数,并且加密和解密过程可以公开, 而只有密钥需要保密。 即只有知道密钥的人才能解密密文,而任何人,即使知道加密或解密算法也无法解密密文。
加密密钥和解密密钥可以相同,也可以不同,取决于采用的是对称密钥密码体制还是公开密钥密码体制。
所谓对称密钥密码体制是一种加密密钥与解密密钥相同的密码体制。在这种加密系统中, 两个参与者共享同一个秘密密钥,如果用一个特定的密钥加密一条消息,也必须要使用相同的密钥来解密该消息。该系统又称为对称密钥系统。
数据加密标准( Data Encryption Standard, DES)是对称密钥密码的典型代表,由IBM公司研制,于1977年被美国定为联邦信息标准 。其加密解密基本流程如下图:
二、.NET 使用 DES 加密
DES使用的密钥为64 位( 实际密钥长度为56 位,有8位用于奇偶校验)。密码的字节长度不能低于64位(8个字节),下面是实现代码:
1 using System;
2 using System.IO;
3 using System.Linq;
4 using System.Security.Cryptography;
5 using System.Text;
6
7 namespace encryption.des
8 {
9 /// <summary>
10 /// DES 加密与解密
11 /// DES加密:https://www.zhihu.com/question/36767829
12 /// 加密基本知识:https://www.biaodianfu.com/des.html
13 /// </summary>
14 public class DesAlgorithm
15 {
16 public Encoding Encoding { get; set; }
17 public PaddingMode Padding { get; set; }
18 public CipherMode Mode { get; set; }
19 public string PassWord { get; private set; }
20 private DESCryptoServiceProvider _des;
21
22 #region .ctor
23
24 public DesAlgorithm()
25 {
26 _des = new DESCryptoServiceProvider();
27 PassWord = Convert.ToBase64String(_des.Key);
28 Encoding = Encoding.UTF8;
29 Padding = PaddingMode.PKCS7;
30 Mode = CipherMode.CBC;
31 }
32 #endregion
33
34
35 /// <summary>
36 /// 通过字符串生成新的密钥
37 /// </summary>
38 /// <param name="password">密码</param>
39 /// <returns></returns>
40 public DESCryptoServiceProvider CreateNewkey(string password)
41 {
42 try
43 {
44 byte[] buffer = Encoding.GetBytes(password).Skip(0).Take(8).ToArray();
45 _des = new DESCryptoServiceProvider()
46 {
47 Key = buffer,
48 IV=buffer,
49 };
50 PassWord = password;
51 return _des;
52 }
53 catch (Exception e)
54 {
55 Console.WriteLine($"Wrong Length:{e.Message},{e.InnerException}");
56 return null;
57 }
58 }
59
60 /// <summary>
61 /// DES加密
62 /// </summary>
63 /// <param name="pToEncrypt">需要加密的字符串<see cref="string"/></param>
64 /// <returns></returns>
65 public string Encrypt(string pToEncrypt)
66 {
67 byte[] inputByteArray = Encoding.GetBytes(pToEncrypt);
68 return Convert.ToBase64String(this.Encrypt(inputByteArray));
69 }
70
71 /// <summary>
72 /// DES加密
73 /// </summary>
74 /// <param name="pToEncrypt">待加密的byte数组<see cref="byte"/></param>
75 /// <returns></returns>
76 public byte[] Encrypt(byte[] pToEncrypt)
77 {
78 byte[] base64 = null;
79 using (var ms = new MemoryStream())
80 {
81 using (var cs = new CryptoStream(ms, _des.CreateEncryptor(), CryptoStreamMode.Write))
82 {
83 cs.Write(pToEncrypt, 0, pToEncrypt.Length);
84 cs.FlushFinalBlock();
85 }
86 base64 = ms.ToArray();
87 }
88 return base64;
89 }
90
91 /// <summary>
92 /// DES解密
93 /// </summary>
94 /// <param name="pToDecrypt">需要解密的字符串</param>
95 /// <returns></returns>
96 public string Decrypt(string pToDecrypt)
97 {
98 byte[] inputByteArray = Convert.FromBase64String(pToDecrypt);
99 return Encoding.GetString(this.Decrypt(inputByteArray));
100 }
101
102 /// <summary>
103 /// DES解密
104 /// </summary>
105 /// <param name="pToDecrypt">待解密的byte数组<see cref="byte"/></param>
106 /// <returns></returns>
107 public byte[] Decrypt(byte[] pToDecrypt)
108 {
109 byte[] data = null;
110 using (var ms = new MemoryStream())
111 {
112 using (CryptoStream cs = new CryptoStream(ms, _des.CreateDecryptor(), CryptoStreamMode.Write))
113 {
114 cs.Write(pToDecrypt, 0, pToDecrypt.Length);
115 cs.FlushFinalBlock();
116 }
117 data = ms.ToArray();
118 }
119 return data;
120 }
121 }
122 }
三、.NET 使用 3DES 加密
DES使用的密钥为64 位,它是一个优秀的密码算法,目前还没有发现比蛮力攻击更好的破解方法。但随着计算机运算速度的快速提高,56位长的密钥已显得太短。56位长的密钥意味着共有256种可能的密钥,也就是说,共约有7. 6 × 1016 种密钥。假设一台计算机1 µ s可执行一次DES加密,同时假定平均只需搜索密钥空间的一半即可找到密钥,那么破译DES要超过1千年。但现在利用并行计算技术已经设计出搜索DES密钥的专用芯片。例如,在1999年有一批在因特网上合作的人借助于一台不到25万美元的专用计算机,在略大于22h的时间就破译了56 位密钥的DES。
为解决DES密钥太短的问题,人们提出了三重DES(Triple DES, 3DES),并在1985年成为美国的一个商用加密标准[ RFC 2420]。3DES在加密时,用三个密钥,执行三次DES算法: 即 E运算 → D运算 → E运算。 解密时,按相反顺序使用这三个密钥,执行D运算 → E运算 → D运算。
3DES目前正在被2001年发布的高级加密标准( Advanced Encryption Standard, AES)所替代。AES能够使用128位、192位和256位长的密钥,用硬件和软件都可以快速实现。它不需要太多内存,因此适用于小型移动设备。美国国家标准与技术研究所NIST估计,如果用1s破解56位DES的计算机来破解一个128位的AES密钥的话,要用大约149万亿年的时间才有可能。
3DES 使用现有的DES算法,并且当三个密钥相同时,效果就和DES一样。这有利于逐步推广使用3DES。也可以仅使用两个密钥,即 K1= K3,相当于密钥长度112位,这对于多数商业应用也已经足够长了。下面代码我们采用密钥长度56*3=168位的3EDS算法:
1 using System;
2 using System.IO;
3 using System.Linq;
4 using System.Security.Cryptography;
5 using System.Text;
6
7 namespace encryption.des
8 {
9 /// <summary>
10 /// 3DES加密与解密
11 /// </summary>
12 public class TripleDesAlgorithm
13 {
14 public Encoding Encoding { get; set; }
15 public PaddingMode Padding { get; set; }
16 public CipherMode Mode { get; set; }
17 public string PassWord { get; private set; }
18
19 private TripleDESCng _des;
20
21 #region .ctor
22
23 public TripleDesAlgorithm()
24 {
25 _des = new TripleDESCng();
26 PassWord = Convert.ToBase64String(_des.Key);
27 Encoding = Encoding.UTF8;
28 Padding = PaddingMode.PKCS7;
29 Mode = CipherMode.CBC;
30 }
31 #endregion
32
33 /// <summary>
34 /// 通过字符串生成新的密钥
35 /// </summary>
36 /// <param name="password">密码</param>
37 /// <returns></returns>
38 public TripleDESCng CreateNewkey(string password)
39 {
40 try
41 {
42 byte[] key = Encoding.GetBytes(password).Skip(0).Take(24).ToArray();
43 byte[] iv = Encoding.GetBytes(password).Skip(0).Take(8).ToArray();
44 _des = new TripleDESCng()
45 {
46 Key = key,
47 IV = iv,
48 };
49 PassWord = password;
50 return _des;
51 }
52 catch (Exception e)
53 {
54 Console.WriteLine($"Wrong Length:{e.Message},{e.InnerException}");
55 return null;
56 }
57 }
58
59 /// <summary>
60 /// 3DES加密
61 /// </summary>
62 /// <param name="pToEncrypt">需要加密的字符串<see cref="string"/></param>
63 /// <returns></returns>
64 public string Encrypt(string pToEncrypt)
65 {
66 byte[] inputByteArray = Encoding.GetBytes(pToEncrypt);
67 return Convert.ToBase64String(this.Encrypt(inputByteArray));
68 }
69
70 /// <summary>
71 /// 3DES加密
72 /// </summary>
73 /// <param name="pToEncrypt">需要加密的byte数组<see cref="byte"/></param>
74 /// <returns></returns>
75 public byte[] Encrypt(byte[] pToEncrypt)
76 {
77 byte[] base64 = null;
78 using (var ms = new MemoryStream())
79 {
80 using (var cs = new CryptoStream(ms, _des.CreateEncryptor(), CryptoStreamMode.Write))
81 {
82 cs.Write(pToEncrypt, 0, pToEncrypt.Length);
83 cs.FlushFinalBlock();
84 }
85 base64 = ms.ToArray();
86 }
87 return base64;
88 }
89
90 /// <summary>
91 /// 3DES解密
92 /// </summary>
93 /// <param name="pToDecrypt">需要解密的字符串<see cref="string"/></param>
94 /// <returns></returns>
95 public string Decrypt(string pToDecrypt)
96 {
97 byte[] inputByteArray = Convert.FromBase64String(pToDecrypt);
98 return Encoding.GetString(this.Decrypt(inputByteArray));
99 }
100
101 /// <summary>
102 /// 3DES解密
103 /// </summary>
104 /// <param name="pToDecrypt">需要解密的byte数组<see cref="byte"/></param>
105 /// <returns></returns>
106 public byte[] Decrypt(byte[] pToDecrypt)
107 {
108 byte[] data = null;
109 using (var ms = new MemoryStream())
110 {
111 using (CryptoStream cs = new CryptoStream(ms, _des.CreateDecryptor(), CryptoStreamMode.Write))
112 {
113 cs.Write(pToDecrypt, 0, pToDecrypt.Length);
114 cs.FlushFinalBlock();
115 }
116 data = (ms.ToArray());
117 }
118 return data;
119 }
120 }
121 }
四、测试代码与效果
1 static void Main(string[] args)
2 {
3 // DES字符串加密与解密
4 {
5 Console.WriteLine("-----------------------------------------------------DES字符串加密与解密--------------------------------------------------");
6 var input = "数据加密标准( Data Encryption Standard, DES)是对称密钥密码的典型代表,由IBM公司研制,于1977年被美国定为联邦信息标准 。";
7 Console.Write($"加密内容:\r\n{input}\r\n");
8 var des = new DesAlgorithm();
9 // TEST:可使用该方法通过字符串生成新的密钥
10 //des.CreateNewkey("https://www.cnblogs.com/dongweian");
11 Console.WriteLine($"DES密钥:\r\n{des.PassWord}\r\n");
12 var encrypt = des.Encrypt(input);
13 Console.WriteLine($"DES加密后内容:\r\n{encrypt}\r\n");
14 var decrypt = des.Decrypt(encrypt);
15 Console.WriteLine($"DES解密后内容:\r\n{decrypt}\r\n");
16 }
17
18 // DES文件加密与解密
19 {
20 Console.WriteLine("---------------------------------------------------DES文件加密与解密--------------------------------------------------");
21 var input = System.IO.File.ReadAllBytes(@"C:\Users\97460\Desktop\1.rar");
22 Console.Write($"加密内容:\r\n{Convert.ToBase64String(input)}\r\n");
23 var des = new DesAlgorithm();
24 // TEST:可使用该方法通过字符串生成新的密钥
25 //des.CreateNewkey("https://www.cnblogs.com/dongweian");
26 Console.WriteLine($"DES密钥:\r\n{des.PassWord}\r\n");
27 var encrypt = des.Encrypt(input);
28 Console.WriteLine($"DES加密后内容:\r\n{Convert.ToBase64String(encrypt)}\r\n");
29 var decrypt = des.Decrypt(encrypt);
30 Console.WriteLine($"DES解密后内容:\r\n{Convert.ToBase64String(decrypt)}\r\n");
31 System.IO.File.WriteAllBytes("1.rar", decrypt);
32 }
33
34
35
36 // 3DES字符串加密与解密
37 {
38 Console.WriteLine("---------------------------------------------------3DES字符串加密与解密--------------------------------------------------");
39 var input = "数据加密标准( Data Encryption Standard, DES)是对称密钥密码的典型代表,由IBM公司研制,于1977年被美国定为联邦信息标准 。";
40 Console.Write($"加密内容:\r\n{input}\r\n");
41 var des = new TripleDesAlgorithm();
42 // TEST:可使用该方法通过字符串生成新的密钥
43 //des.CreateNewkey("https://www.cnblogs.com/dongweian");
44 Console.WriteLine($"3DES密钥:\r\n{des.PassWord}\r\n");
45 var encrypt = des.Encrypt(input);
46 Console.WriteLine($"3DES加密后内容:\r\n{encrypt}\r\n");
47 var decrypt = des.Decrypt(encrypt);
48 Console.WriteLine($"DES解密后内容:\r\n{decrypt}\r\n");
49 }
50
51 // 3DES文件加密与解密
52 {
53 Console.WriteLine("---------------------------------------------------3DES文件加密与解密--------------------------------------------------");
54 var input = System.IO.File.ReadAllBytes(@"C:\Users\97460\Desktop\1.rar");
55 Console.Write($"加密内容:\r\n{Convert.ToBase64String(input)}\r\n");
56 var des = new TripleDesAlgorithm();
57 // TEST:可使用该方法通过字符串生成新的密钥
58 //des.CreateNewkey("https://www.cnblogs.com/dongweian");
59 Console.WriteLine($"3DES密钥:\r\n{des.PassWord}\r\n");
60 var encrypt = des.Encrypt(input);
61 Console.WriteLine($"3DES加密后内容:\r\n{Convert.ToBase64String(encrypt)}\r\n");
62 var decrypt = des.Decrypt(encrypt);
63 Console.WriteLine($"3DES解密后内容:\r\n{Convert.ToBase64String(decrypt)}\r\n");
64 System.IO.File.WriteAllBytes("1.rar", decrypt);
65 }
66 Console.ReadKey();
67 }
相关内容:计算机网络安全 —— 非对称加密算法 RSA 和数字签名(二)、计算机网络安全 —— 报文摘要算法 ME5 (三)、计算机网络安全 —— 实体鉴别与生成大随机数(四)
代码示例:https://github.com/Dwayne112401/encryption