先问个问题:为什么要使用加密算法?
因为数据在网络中传输时面临4个问题:
加密技术就是用来解决“窃听”这个问题的。通常分为两大类:对称加密和非对称加密。
有人可能会问,上面两类加密方式怎么没有MD5?MD5……严格意义上说不是一种加密算法,因为它不能解密。它只是一种密码散列算法,只是为了校验信息用的:保证信息没有篡改。如:你下载软件或游戏时,在下载页面官方都会提供一个“MD5字符串”,你下载完成后可以用md5工具对下载到的软件md5校验,如果得到的md5串和下载页面的一致,就说明软件或游戏没有被篡改过,可放心使用。
下面我们就一块来实战几种常见的加密方式和散列算法:
分类:对称加密
DES全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,1977年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),并授权在非密级政府通信中使用,随后该算法在国际上广泛流传开来。
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 |
using System; using System.IO; using System.Security.Cryptography; using System.Text; namespace EncryptionPractice.Utils { public class DESUtils { /// <summary> /// 加密数据 /// </summary> /// <param name="text"></param> /// <param name="sessionKey"></param> /// <returns></returns> public static string Encrypt(string text, string sessionKey) { try { var des = GetDESProvider(sessionKey); var bytes = Encoding.Default.GetBytes(text); using var memoryStream = GetMemoryStream(des.CreateEncryptor(), bytes); var result = new StringBuilder(); foreach (var byteItem in memoryStream.ToArray()) { result.AppendFormat("{0:X2}", byteItem); } return result.ToString(); } catch { return string.Empty; } } /// <summary> /// 解密数据 /// </summary> /// <param name="ciphertext"></param> /// <param name="sessionKey"></param> /// <returns></returns> public static string Decrypt(string ciphertext, string sessionKey) { try { var length = ciphertext.Length / 2; var bytes = new byte[length]; for (var i=0; i<length; i++) { var j = Convert.ToInt32(ciphertext.Substring(i * 2, 2), 16); bytes[i] = (byte) j; } var des = GetDESProvider(sessionKey); using var memoryStream = GetMemoryStream(des.CreateDecryptor(), bytes); return Encoding.Default.GetString(memoryStream.ToArray()); } catch { return string.Empty; } } /// <summary> /// 获取DES引擎 /// </summary> /// <param name="sessionKey"></param> /// <returns></returns> private static DESCryptoServiceProvider GetDESProvider(string sessionKey) { var md5Key = MD5Utils.Get32(sessionKey).Substring(8, 8); var des = new DESCryptoServiceProvider { Key = Encoding.ASCII.GetBytes(md5Key), IV = Encoding.ASCII.GetBytes(md5Key) }; return des; } /// <summary> /// 获取内存流 /// </summary> /// <param name="cryptoTransform"></param> /// <param name="bytes"></param> /// <returns></returns> private static MemoryStream GetMemoryStream(ICryptoTransform cryptoTransform, byte[] bytes) { var memoryStream = new MemoryStream(); using var cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Write); cryptoStream.Write(bytes, 0, bytes.Length); cryptoStream.FlushFinalBlock(); return memoryStream; } } } |
分类:对称加密
高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES(Data Encryption Standard),已经被多方分析且广为全世界所使用。
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 |
using System; using System.IO; using System.Security.Cryptography; using System.Text; namespace EncryptionPractice.Utils { public class AESUtils { /// <summary> /// 默认Key /// </summary> const string KEY = "E10ADC3949BA59AB"; /// <summary> /// 默认偏移量 /// </summary> const string IV = "BE56E057F20F883E"; /// <summary> /// 加密 /// </summary> /// <param name="text"></param> /// <param name="key"></param> /// <param name="iv"></param> /// <returns></returns> public static string Encrypt(string text, string key = KEY, string iv = IV) { var bytes = Encoding.UTF8.GetBytes(text); var result = Origin(bytes, false, key, iv); return Convert.ToBase64String(result, 0, result.Length); } /// <summary> /// 解密 /// </summary> /// <param name="ciphertext"></param> /// <param name="key"></param> /// <param name="iv"></param> /// <returns></returns> public static string Decrypt(string ciphertext, string key = KEY, string iv = IV) { var bytes = Convert.FromBase64String(ciphertext); var result = Origin(bytes, true, key, iv); if (result.Length < 1) return string.Empty; return Encoding.UTF8.GetString(result); } /// <summary> /// 底层方法 /// </summary> /// <param name="bytes"></param> /// <param name="isDecrypt"></param> /// <param name="key"></param> /// <param name="iv"></param> /// <returns></returns> private static byte[] Origin(byte[] bytes, bool isDecrypt, string key = KEY, string iv = IV) { try { var keyBytes = Encoding.UTF8.GetBytes(key); var ivBytes = Encoding.UTF8.GetBytes(iv); var rijndaelManaged = new RijndaelManaged { BlockSize = 128, KeySize = 256, FeedbackSize = 128, Padding = PaddingMode.PKCS7, Key = keyBytes, IV = ivBytes, Mode = CipherMode.CBC }; var cryptoTransform = isDecrypt ? rijndaelManaged.CreateDecryptor() : rijndaelManaged.CreateEncryptor(); var result = cryptoTransform.TransformFinalBlock(bytes, 0, bytes.Length); return result; } catch { return new byte[] { }; } } } } |
分类:非对称加密
RSA是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。RSA就是他们三人姓氏开头字母拼在一起组成的。RSA公开密钥密码体制是一种使用不同的加密密钥与解密密钥,“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制。
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 |
using System; using System.IO; using System.Security.Cryptography; using System.Text; namespace EncryptionPractice.Utils { public class RSAUtils { /// <summary> /// 加密 /// </summary> /// <param name="text">明文</param> /// <param name="publicKey">公钥</param> /// <returns>密文</returns> public static string Encrypt(string text, string publicKey) { var blockSize = 256; // 加密块大小,越大越慢 var bytes = Encoding.UTF8.GetBytes(text); var length = bytes.Length; // rsa实例 var rsa = new RSACryptoServiceProvider(); rsa.FromXmlString(publicKey); var offSet = 0; // 游标 var i = 0; byte[] cache; var ms = new MemoryStream(); while (length - offSet > 0) { var len = length - offSet > blockSize ? blockSize : length - offSet; var temp = new byte[len]; Array.Copy(bytes, offSet, temp, 0, len); cache = rsa.Encrypt(bytes, false); ms.Write(cache, 0, cache.Length); i++; offSet = i * blockSize; } var cipherBytes = ms.ToArray(); return Convert.ToBase64String(cipherBytes); } /// <summary> /// RSA解密 /// </summary> /// <param name="ciphertext">密文</param> /// <param name="privateKey">私钥</param> /// <returns>明文</returns> public static string Decrypt(string ciphertext, string privateKey) { var blockSize = 256; var bytes = Convert.FromBase64String(ciphertext); var length = bytes.Length; // rsa实例 var rsa = new RSACryptoServiceProvider(); rsa.FromXmlString(privateKey); var offSet = 0; // 游标 var i = 0; byte[] cache; var ms = new MemoryStream(); while (length - offSet > 0) { var len = length - offSet > blockSize ? blockSize : length - offSet; var temp = new byte[len]; Array.Copy(bytes, offSet, temp, 0, len); cache = rsa.Decrypt(temp, false); ms.Write(cache, 0, cache.Length); i++; offSet = i * blockSize; } var cipherBytes = ms.ToArray(); return Encoding.UTF8.GetString(cipherBytes); } } } |
生成公钥/密钥的方法(只适用于C#,其他编程语言使用需要转换)
1 2 3 |
var rsa = new RSACryptoServiceProvider(); var publicKey = rsa.ToXmlString(false); var privateKey = rsa.ToXmlString(true); |
分类:散列算法
MD5信息摘要算法(MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。MD5由美国密码学家罗纳德·李维斯特(Ronald Linn Rivest)设计,于1992年公开。1996年后该算法被证实存在弱点,可以被加以破解,对于需要高度安全性的数据,专家一般建议改用其他算法,如SHA-2。
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 |
using System; using System.Security.Cryptography; using System.Text; namespace EncryptionPractice.Utils { public class MD5Utils { /// <summary> /// 获取16位散列值 /// </summary> /// <param name="text"></param> /// <returns></returns> public static string Get16(string text) { return Get32(text).Substring(7, 16); } /// <summary> /// 获取32位散列值 /// </summary> /// <param name="text"></param> /// <returns></returns> public static string Get32(string text) { using var md5 = MD5.Create(); var hash = md5.ComputeHash(Encoding.UTF8.GetBytes(text)); var result = BitConverter.ToString(hash); return result.Replace("-", "").ToUpper(); } /// <summary> /// 获取16位散列值 v2 /// </summary> /// <param name="text"></param> /// <returns></returns> public static string Get16v2(string text) { return Get32v2(text).Substring(7, 16); } /// <summary> /// 获取32位散列值 /// </summary> /// <param name="text">字符串</param> /// <returns></returns> public static string Get32v2(string text) { var md5 = new MD5CryptoServiceProvider(); var hash = md5.ComputeHash(Encoding.Default.GetBytes(text)); var resutl = new StringBuilder(); for (int i = 0; i < hash.Length; i++) { resutl.Append(hash[i].ToString("x2")); } return resutl.ToString().ToUpper(); } } } |
分类:散列算法
SHA-2,名称来自于安全散列算法2(英语:Secure Hash Algorithm 2)的缩写,一种密码散列函数算法标准,由美国国家安全局研发,由美国国家标准与技术研究院(NIST)在2001年发布。属于SHA算法之一,是SHA-1的后继者。其下又可再分为六个不同的算法标准,包括了:SHA-224、SHA-256、SHA-384、SHA-512、SHA-512/224、SHA-512/256。
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 |
using System.Security.Cryptography; using System.Text; namespace EncryptionPractice.Utils { public class SHAUtils { /// <summary> /// SHA256加密 /// </summary> /// <param name="data"></param> /// <returns></returns> public static string Encrypt(string data) { var bytes = Encoding.UTF8.GetBytes(data); var hash = SHA256.Create().ComputeHash(bytes); var result = new StringBuilder(); for (int i = 0; i < hash.Length; i++) { result.Append(hash[i].ToString("x2")); } return result.ToString(); } } } |
欢迎转载,请注明出处:龙生时代