本文是利用一个简单的小例子,简述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算法核心代码如下:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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】。如下图所示:
关于对称加密算法,效果图如下:
对称加密算法的核心代码如下:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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就是他们三人姓氏开头字母拼在一起组成的。】【非对称加密算法对长度有一定的限制,适用于少量数据】
关于非对称加密算法,效果图如下:
关于数字签名,效果图如下:
关于非对称加密术和数字签名,核心代码如下:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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 }
本文旨在抛砖引玉,希望大家可以共同探讨,如有不足之处,还请指正。