本文是利用一個簡單的小例子,簡述C#中和加密術有關的內容,僅供學習參考用。
概述
隨着信息技術的發展,計算機網絡為信息的獲取、傳輸、處理、利用與共享提供了一個高效、快捷、安全的通信環境和傳輸通道,網絡信息安全也變得越來越重要。信息安全主要包括兩個方面的內容:信息存儲安全和信息傳輸安全。保證網絡中信息安全的主要技術是數據的加密與解密。如下圖示,說明了加密與解密的過程。
公式算法表示如下:
加密公式:c=Eke(m) (11.1) 解密公式:m=Dkd(c) (11.2)其中m代表明文,c代表密文,E是加密算法,D是解密算法,參數ke稱為加密密鑰,參數kd稱為解密密鑰
涉及知識點
- HASH算法 :散列函數是現代密碼系統的基礎。這些函數將任意長度的二進制字符串映射為固定長度的二進制字符串(稱為散列值)
- 對稱加密算法:指對信息的加密和解密都使用相同的密鑰。
- 非對稱加密算法:非對稱加密算法對信息的加密與解密使用不同的密鑰,用來加密的密鑰是可以公開的,用來解密的密鑰需要保密
- 數字簽名術:數字簽名技術結合散列算法和非對稱加密技術來進行篡改檢測和解決相關的身份驗證問題。這就像在現實生活中用親筆簽名來保證文件或資料的真實性一樣。
散列算法
散列算法主要有MD5【Message Digest Algorithm】,RIPEMD160【RACE Integrity Primitives Evaluation Message Digest】和SHA【Secure Hash Algorithm】,SHA又分為SHA1,SHA256,SHA384,SHA512,【散列算法不可逆,是單向操作】如下如所示:
關於散列算法,效果圖如下:
HASH算法核心代碼如下:

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Security.Cryptography; 5 using System.Text; 6 using System.Threading.Tasks; 7 8 namespace DemoCrtpto 9 { 10 /// <summary> 11 /// 信息摘要幫助類 12 /// </summary> 13 public class HashHelper 14 { 15 #region 信息摘要 16 17 /// <summary> 18 /// MD5信息摘要 19 /// </summary> 20 /// <param name="source"></param> 21 /// <returns></returns> 22 public static string GetInfoByMd5(string source) 23 { 24 HashAlgorithm hash = getHashAlgorithm(HashType.MD5); 25 return Encrypto(hash, source); 26 } 27 28 public static string GetInfoBySHA1(string source) 29 { 30 HashAlgorithm hash = getHashAlgorithm(HashType.SHA1); 31 return Encrypto(hash, source); 32 } 33 34 public static string GetInfoBySHA256(string source) 35 { 36 HashAlgorithm hash = getHashAlgorithm(HashType.SHA256); 37 return Encrypto(hash, source); 38 } 39 40 public static string GetInfoBySHA384(string source) 41 { 42 HashAlgorithm hash = getHashAlgorithm(HashType.SHA384); 43 return Encrypto(hash, source); 44 } 45 46 public static string GetInfoBySHA512(string source) 47 { 48 HashAlgorithm hash = getHashAlgorithm(HashType.SHA512); 49 return Encrypto(hash, source); 50 } 51 52 public static string GetInfoByRipeMD(string source) 53 { 54 HashAlgorithm hash = getHashAlgorithm(HashType.RIPEMD); 55 return Encrypto(hash, source); 56 } 57 58 #endregion 59 60 /// <summary> 61 /// 根據類型獲取摘要算法名稱 62 /// </summary> 63 /// <param name="t"></param> 64 /// <returns></returns> 65 private static HashAlgorithm getHashAlgorithm(HashType t) { 66 HashAlgorithm hash; 67 switch (t) { 68 case HashType.MD5: 69 hash = new MD5CryptoServiceProvider(); 70 break; 71 case HashType.SHA1: 72 hash = new SHA1Managed(); 73 break; 74 case HashType.SHA256: 75 hash = new SHA256Managed(); 76 break; 77 case HashType.SHA384: 78 hash = new SHA384Managed(); 79 break; 80 case HashType.SHA512: 81 hash = new SHA512Managed(); 82 break; 83 case HashType.RIPEMD: 84 hash = new RIPEMD160Managed(); 85 break; 86 default: 87 hash = new MD5CryptoServiceProvider(); 88 break; 89 } 90 return hash; 91 } 92 93 /// <summary> 94 /// 加密 95 /// </summary> 96 /// <param name="hash"></param> 97 /// <param name="source"></param> 98 /// <returns></returns> 99 private static string Encrypto(HashAlgorithm hash, string source) { 100 string dest = string.Empty; 101 try 102 { 103 byte[] btSource = Encoding.Default.GetBytes(source); 104 byte[] btDest = hash.ComputeHash(btSource); 105 dest = Convert.ToBase64String(btDest, 0, btDest.Length); 106 } 107 catch (Exception ex) 108 { 109 throw ex; 110 } 111 return dest; 112 } 113 } 114 115 /// <summary> 116 /// 信息摘要類型 117 /// </summary> 118 public enum HashType { 119 MD5=0, 120 SHA1=1, 121 SHA256=2, 122 SHA384=3, 123 SHA512=4, 124 RIPEMD=5 125 } 126 }
對稱加密算法
關於對稱加密算法,主要有DES【Data Encryption Standard / 數據加密標准】 , 3DES【三重數據加密算法】,RC2【Rivest Cipher】,Rijndael【又稱AES:Advanced Encryption Standard】。如下圖所示:
關於對稱加密算法,效果圖如下:
對稱加密算法的核心代碼如下:

1 using System; 2 using System.Collections.Generic; 3 using System.IO; 4 using System.Linq; 5 using System.Security.Cryptography; 6 using System.Text; 7 using System.Threading.Tasks; 8 9 namespace DemoCrtpto 10 { 11 /// <summary> 12 /// 對稱加密算法幫助類 13 /// </summary> 14 public class SymHelper 15 { 16 #region DES加密 17 18 /// <summary> 19 /// DES加密 20 /// </summary> 21 /// <param name="source"></param> 22 /// <param name="key"></param> 23 /// <param name="iv"></param> 24 /// <returns></returns> 25 public static string GetEnCryptoInfoByDES(string source, string key, string iv) 26 { 27 SymmetricAlgorithm sym = getSymmetricAlgorithm(SymType.DES); 28 return Encrypto(sym, source, key, iv); 29 30 } 31 32 /// <summary> 33 /// DES解密 34 /// </summary> 35 /// <param name="dest"></param> 36 /// <param name="key"></param> 37 /// <param name="iv"></param> 38 /// <returns></returns> 39 public static string GetDeCryptoInfoByDES(string dest, string key, string iv) 40 { 41 SymmetricAlgorithm sym = getSymmetricAlgorithm(SymType.DES); 42 return Decrypto(sym, dest, key, iv); 43 44 } 45 46 #endregion 47 48 #region RC2加密與解密 49 50 /// <summary> 51 /// RC2加密 52 /// </summary> 53 /// <param name="source"></param> 54 /// <param name="key"></param> 55 /// <param name="iv"></param> 56 /// <returns></returns> 57 public static string GetEnCryptoInfoByRC2(string source, string key, string iv) 58 { 59 SymmetricAlgorithm sym = getSymmetricAlgorithm(SymType.RC2); 60 return Encrypto(sym, source, key, iv); 61 62 } 63 64 /// <summary> 65 /// RC2解密 66 /// </summary> 67 /// <param name="dest"></param> 68 /// <param name="key"></param> 69 /// <param name="iv"></param> 70 /// <returns></returns> 71 public static string GetDeCryptoInfoByRC2(string dest, string key, string iv) 72 { 73 SymmetricAlgorithm sym = getSymmetricAlgorithm(SymType.RC2); 74 return Decrypto(sym, dest, key, iv); 75 76 } 77 78 #endregion 79 80 #region 3DES加密與解密 81 82 /// <summary> 83 /// 3DES加密 84 /// </summary> 85 /// <param name="source"></param> 86 /// <param name="key"></param> 87 /// <param name="iv"></param> 88 /// <returns></returns> 89 public static string GetEnCryptoInfoBy3DES(string source, string key, string iv) 90 { 91 SymmetricAlgorithm sym = getSymmetricAlgorithm(SymType.TripleDES); 92 return Encrypto(sym, source, key, iv); 93 94 } 95 96 /// <summary> 97 /// 3DES解密 98 /// </summary> 99 /// <param name="dest"></param> 100 /// <param name="key"></param> 101 /// <param name="iv"></param> 102 /// <returns></returns> 103 public static string GetDeCryptoInfoBy3DES(string dest, string key, string iv) 104 { 105 SymmetricAlgorithm sym = getSymmetricAlgorithm(SymType.TripleDES); 106 return Decrypto(sym, dest, key, iv); 107 108 } 109 110 #endregion 111 112 #region Rijndael加密與解密 113 114 /// <summary> 115 /// Rijndael加密 116 /// </summary> 117 /// <param name="source"></param> 118 /// <param name="key"></param> 119 /// <param name="iv"></param> 120 /// <returns></returns> 121 public static string GetEnCryptoInfoByRijndael(string source, string key, string iv) 122 { 123 SymmetricAlgorithm sym = getSymmetricAlgorithm(SymType.Rijndael); 124 return Encrypto(sym, source, key, iv); 125 126 } 127 128 129 /// <summary> 130 /// Rijndael解密 131 /// </summary> 132 /// <param name="dest"></param> 133 /// <param name="key"></param> 134 /// <param name="iv"></param> 135 /// <returns></returns> 136 public static string GetDeCryptoInfoByRijndael(string dest, string key, string iv) 137 { 138 SymmetricAlgorithm sym = getSymmetricAlgorithm(SymType.Rijndael); 139 return Decrypto(sym, dest, key, iv); 140 } 141 142 #endregion 143 144 public static SymmetricAlgorithm getSymmetricAlgorithm(SymType t) 145 { 146 SymmetricAlgorithm sym; 147 switch (t) 148 { 149 case SymType.DES: 150 sym = new DESCryptoServiceProvider(); 151 break; 152 case SymType.RC2: 153 sym = new RC2CryptoServiceProvider(); 154 break; 155 case SymType.TripleDES: 156 sym = new TripleDESCryptoServiceProvider(); 157 break; 158 case SymType.Rijndael: 159 sym = new RijndaelManaged(); 160 break; 161 default: 162 sym = new DESCryptoServiceProvider(); 163 break; 164 } 165 return sym; 166 } 167 168 /// <summary> 169 /// 加密 170 /// </summary> 171 /// <param name="sym"></param> 172 /// <param name="source"></param> 173 /// <param name="key"></param> 174 /// <param name="iv"></param> 175 /// <returns></returns> 176 private static string Encrypto(SymmetricAlgorithm sym, string source, string key, string iv) 177 { 178 string dest = string.Empty; 179 try 180 { 181 byte[] btnSource = Encoding.Default.GetBytes(source); 182 //1.創建對稱加密算法實例創建對稱加密算法實例 183 sym.Mode = CipherMode.CBC; 184 int keyLen = sym.LegalKeySizes[0].MaxSize / 8; 185 int ivLen = sym.BlockSize / 8; 186 if (key.Length < keyLen) 187 { 188 key = key.PadRight(keyLen, '0'); 189 } 190 if (iv.Length < ivLen) 191 { 192 iv = iv.PadRight(ivLen, '0'); 193 } 194 //使用 PBKDF1 算法的擴展從密碼派生密鑰 195 PasswordDeriveBytes pkey = new PasswordDeriveBytes(key, 196 ASCIIEncoding.ASCII.GetBytes("123456")); 197 198 //2.設置初始化參數,包括密鑰和初始化向量等 199 sym.Key = pkey.GetBytes(key.Length); //Encoding.Default.GetBytes(key); 200 sym.IV = Encoding.Default.GetBytes(iv); 201 //3.使用CreateEncryptor方法創建加密實例 202 ICryptoTransform trans = sym.CreateEncryptor(); 203 //4.創建加密流 204 MemoryStream ms = new MemoryStream(); 205 CryptoStream cs = new CryptoStream(ms, trans, CryptoStreamMode.Write); 206 //5.利用加密流進行數據加密 207 cs.Write(btnSource, 0, btnSource.Length); 208 cs.FlushFinalBlock(); 209 //6.返回密文 210 byte[] cryptoByte = ms.ToArray(); 211 dest = Convert.ToBase64String(cryptoByte, 0, cryptoByte.GetLength(0)); 212 } 213 catch (Exception ex) 214 { 215 throw ex; 216 } 217 return dest; 218 } 219 220 /// <summary> 221 /// 解密 222 /// </summary> 223 /// <param name="sym"></param> 224 /// <param name="dest"></param> 225 /// <param name="key"></param> 226 /// <param name="iv"></param> 227 /// <returns></returns> 228 private static string Decrypto(SymmetricAlgorithm sym, string dest, string key, string iv) 229 { 230 string source = string.Empty; 231 try 232 { 233 byte[] btnDest = Convert.FromBase64String(dest); 234 //1.創建對稱加密算法實例創建對稱加密算法實例 235 sym.Mode = CipherMode.CBC; 236 int keyLen = sym.LegalKeySizes[0].MaxSize / 8; 237 int ivLen = sym.BlockSize / 8; 238 if (key.Length < keyLen) 239 { 240 key = key.PadRight(keyLen, '0'); 241 } 242 if (iv.Length < ivLen) 243 { 244 iv = iv.PadRight(ivLen, '0'); 245 } 246 //使用 PBKDF1 算法的擴展從密碼派生密鑰 247 PasswordDeriveBytes pkey = new PasswordDeriveBytes(key, 248 ASCIIEncoding.ASCII.GetBytes("123456")); 249 //2.設置初始化參數,包括密鑰和初始化向量等 250 sym.Key = pkey.GetBytes(key.Length); //Encoding.Default.GetBytes(key); 251 sym.IV = Encoding.Default.GetBytes(iv); 252 //3.使用CreateDecryptor方法創建解密實例 253 ICryptoTransform trans = sym.CreateDecryptor(); 254 //4.創建解密流 255 MemoryStream ms = new MemoryStream(btnDest, 0, btnDest.Length); 256 CryptoStream cs = new CryptoStream(ms, trans, CryptoStreamMode.Read); 257 258 //5.返回明文 259 StreamReader sr = new StreamReader(cs); 260 source = sr.ReadToEnd(); 261 } 262 catch (Exception ex) 263 { 264 throw ex; 265 } 266 return source; 267 } 268 } 269 270 /// <summary> 271 /// 加密類型 272 /// </summary> 273 public enum SymType { 274 DES=0, 275 RC2=1, 276 TripleDES=2, 277 Rijndael=3 278 } 279 }
非對稱加密算法和數字簽名
非對稱加密算法,主要要RSA【RSA公鑰加密算法是1977年由羅納德·李維斯特(Ron Rivest)、阿迪·薩莫爾(Adi Shamir)和倫納德·阿德曼(Leonard Adleman)一起提出的。1987年7月首次在美國公布,當時他們三人都在麻省理工學院工作實習。RSA就是他們三人姓氏開頭字母拼在一起組成的。】【非對稱加密算法對長度有一定的限制,適用於少量數據】
關於非對稱加密算法,效果圖如下:
關於數字簽名,效果圖如下:
關於非對稱加密術和數字簽名,核心代碼如下:

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Security.Cryptography; 5 using System.Text; 6 using System.Threading.Tasks; 7 8 namespace DemoCrtpto 9 { 10 /// <summary> 11 /// 非對稱加密算法幫助類 12 /// </summary> 13 public class AsymHelper 14 { 15 16 } 17 18 public class DSAHelper { 19 20 private static string keyContainerName = "star"; 21 22 private static string m_PriKey = string.Empty; 23 24 private static string m_PubKey = string.Empty; 25 26 27 public static string PriKey 28 { 29 get 30 { 31 return m_PriKey; 32 } 33 34 set 35 { 36 m_PriKey = value; 37 } 38 } 39 40 public static string PubKey 41 { 42 get 43 { 44 return m_PubKey; 45 } 46 47 set 48 { 49 m_PubKey = value; 50 } 51 } 52 53 public static void generateKey() 54 { 55 CspParameters m_CspParameters; 56 m_CspParameters = new CspParameters(); 57 m_CspParameters.KeyContainerName = keyContainerName; 58 DSACryptoServiceProvider asym = new DSACryptoServiceProvider(); 59 m_PriKey = asym.ToXmlString(true); 60 m_PubKey = asym.ToXmlString(false); 61 asym.PersistKeyInCsp = false; 62 asym.Clear(); 63 } 64 65 public static string Encrypto(string source) { 66 if (string.IsNullOrEmpty(m_PubKey) && string.IsNullOrEmpty(m_PriKey)) 67 { 68 generateKey(); 69 } 70 return getEncryptoInfoByDSA(source); 71 } 72 73 /// <summary> 74 /// 創建數字簽名 75 /// </summary> 76 /// <param name="source"></param> 77 /// <returns></returns> 78 public static string getEncryptoInfoByDSA(string source) 79 { 80 string dest = string.Empty; 81 string ss = HashHelper.GetInfoBySHA1(source); 82 byte[] btSource = Convert.FromBase64String(ss); 83 DSACryptoServiceProvider asym = new DSACryptoServiceProvider(); 84 asym.FromXmlString(m_PriKey); 85 DSASignatureFormatter dsaFormatter = new DSASignatureFormatter(asym); 86 dsaFormatter.SetHashAlgorithm("SHA1"); 87 byte[] btDest = dsaFormatter.CreateSignature(btSource); 88 dest = Convert.ToBase64String(btDest); 89 return dest; 90 } 91 92 /// <summary> 93 /// 驗證數字簽名 94 /// </summary> 95 /// <param name="source"></param> 96 /// <param name="dest"></param> 97 /// <returns></returns> 98 public static bool verifyInfo(string source, string dest) 99 { 100 string ss = HashHelper.GetInfoBySHA1(source); 101 byte[] btnSource = Convert.FromBase64String(ss); 102 byte[] btnDest = Convert.FromBase64String(dest); 103 DSACryptoServiceProvider asym = new DSACryptoServiceProvider(); 104 asym.FromXmlString(m_PubKey); 105 DSASignatureDeformatter dsaFormatter = new DSASignatureDeformatter(asym); 106 dsaFormatter.SetHashAlgorithm("SHA1"); 107 return dsaFormatter.VerifySignature(btnSource, btnDest); 108 } 109 } 110 111 public class RSAHelper { 112 113 private static string keyContainerName = "star"; 114 115 private static string m_PriKey = string.Empty; 116 117 private static string m_PubKey = string.Empty; 118 119 120 public static string PriKey 121 { 122 get 123 { 124 return m_PriKey; 125 } 126 127 set 128 { 129 m_PriKey = value; 130 } 131 } 132 133 public static string PubKey 134 { 135 get 136 { 137 return m_PubKey; 138 } 139 140 set 141 { 142 m_PubKey = value; 143 } 144 } 145 146 public static string Encrypto(string source) { 147 if (string.IsNullOrEmpty(m_PubKey) && string.IsNullOrEmpty(m_PriKey)) { 148 generateKey(); 149 } 150 return getEncryptoInfoByRSA(source); 151 } 152 153 public static string Decrypto(string dest) { 154 if (string.IsNullOrEmpty(m_PubKey) && string.IsNullOrEmpty(m_PriKey)) 155 { 156 generateKey(); 157 } 158 return getDecryptoInfoByRSA(dest); 159 } 160 161 public static void generateKey() 162 { 163 CspParameters m_CspParameters; 164 m_CspParameters = new CspParameters(); 165 m_CspParameters.KeyContainerName = keyContainerName; 166 RSACryptoServiceProvider asym = new RSACryptoServiceProvider(m_CspParameters); 167 168 m_PriKey = asym.ToXmlString(true); 169 m_PubKey = asym.ToXmlString(false); 170 asym.PersistKeyInCsp = false; 171 asym.Clear(); 172 } 173 174 public static string getEncryptoInfoByRSA(string source) 175 { 176 byte[] plainByte = Encoding.ASCII.GetBytes(source); 177 //初始化參數 178 RSACryptoServiceProvider asym = new RSACryptoServiceProvider(); 179 asym.FromXmlString(m_PubKey); 180 int keySize = asym.KeySize / 8;//非對稱加密,每次的長度不能太長,否則會報異常 181 int bufferSize = keySize - 11; 182 if (plainByte.Length > bufferSize) { 183 throw new Exception("非對稱加密最多支持【"+bufferSize+"】字節,實際長度【"+plainByte.Length+"】字節。"); 184 } 185 byte[] cryptoByte = asym.Encrypt(plainByte, false); 186 return Convert.ToBase64String(cryptoByte); 187 } 188 189 public static string getDecryptoInfoByRSA(string dest) 190 { 191 byte[] btDest = Convert.FromBase64String(dest); 192 //初始化參數 193 RSACryptoServiceProvider asym = new RSACryptoServiceProvider(); 194 asym.FromXmlString(m_PriKey); 195 int keySize = asym.KeySize / 8;//非對稱加密,每次的長度不能太長,否則會報異常 196 //int bufferSize = keySize - 11; 197 if (btDest.Length > keySize) 198 { 199 throw new Exception("非對稱解密最多支持【" + keySize + "】字節,實際長度【" + btDest.Length + "】字節。"); 200 } 201 byte[] cryptoByte = asym.Decrypt(btDest, false); 202 return Encoding.ASCII.GetString(cryptoByte); 203 } 204 } 205 206 207 208 public enum AsymType{ 209 DSA=0, 210 RSA=1 211 } 212 }
本文旨在拋磚引玉,希望大家可以共同探討,如有不足之處,還請指正。