計算機網絡安全 —— 對稱加密算法 DES (一)


一、對稱加密算法概念

​ 我們通過計算機網絡傳輸數據時,如果無法防止他人竊聽, 可以利用密碼學技術將發送的數據變換成對任何不知道如何做逆變換的人都不可理解的形式, 從而保證了數據的機密性。這種變換被稱為加密( encryption),被加密的數據被稱為密 文( ciphertext),而加密前的數據被稱為明文( plaintext)。 接收方必須能通過某種逆變換將密文重新變換回原來的明文,該逆變換被稱為解密( decryption)。加密和解密過程可以以一個密鑰( key)為參數,並且加密和解密過程可以公開, 而只有密鑰需要保密。 即只有知道密鑰的人才能解密密文,而任何人,即使知道加密或解密算法也無法解密密文。

​ 加密密鑰和解密密鑰可以相同,也可以不同,取決於采用的是對稱密鑰密碼體制還是公開密鑰密碼體制

​ 所謂對稱密鑰密碼體制是一種加密密鑰與解密密鑰相同的密碼體制。在這種加密系統中, 兩個參與者共享同一個秘密密鑰,如果用一個特定的密鑰加密一條消息,也必須要使用相同的密鑰來解密該消息。該系統又稱為對稱密鑰系統。

數據加密標准( Data Encryption Standard, DES)是對稱密鑰密碼的典型代表,由IBM公司研制,於1977年被美國定為聯邦信息標准 。其加密解密基本流程如下圖:

img

二、.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萬億年的時間才有可能。

img

​ 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         }

img

相關內容:計算機網絡安全 —— 非對稱加密算法 RSA 和數字簽名(二)計算機網絡安全 —— 報文摘要算法 ME5 (三)計算機網絡安全 —— 實體鑒別與生成大隨機數(四)

代碼示例:https://github.com/Dwayne112401/encryption


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM