编码、加密、哈希的区别:
编码:是信息从一种形式或格式转换成另一种的过程,是可逆的。如:url编码、base64、utf-8
加密:是可逆的,通过特定的秘钥加解密,加解密算法算法有两种:对称加密、非对称加密
哈希:也叫散列,把任意长度的数据转换成固定长度的指纹,过程不可逆
Hash算法:MD5、SHA(1、224、256、384、512)……
无论消息有多长,计算出的摘要长度都是固定的
用途:文件校验、数字签名(防篡改),建议用SHA系列
HMAC算法:
HMAC是具密钥的哈希算法,以一个密钥和一个消息为输入,生成摘要作为输出,消息 + 密钥 + 算法 ==》 输出摘要包括:HMAC-MD5、HMAC-SHA1、HMAC-SHA256、HMAC-SHA384、
HMAC-SHA512
对称加密算法:DES、AES、IDEA、RC2、RC4、SKIPJACK……
加解密使用相同密钥,这个是对称加密。对称加密相比非对称加密优点是速度快
非对称加密算法:RSA、DSA、DH、ECC、EL GAMAL……
公钥加密数据,然后私钥解密的情况被称为加密解密;
因为公钥加密的数据只有它相对应的私钥可以解开,所以你可以把公钥给人和人,让他加密他想要传送给你的数据,这个数据只有到了有私钥的你这里,才可以解开成有用的数据,其他人就是得到了,也看懂内容
实际应用中,一般都是和对方交换公钥,然后你要发给对方的数据,用他的公钥加密,他得到后用他的私钥解密,他要发给你的数据,用你的公钥加密,你得到后用你的私钥解密,这样最大程度保证了安全性.
缺点速度慢
数字签名:
私钥签名和公钥验证签名;RSA可以用来做签名、验签
如果你用你的私钥对数据进行签名,那这个数据就只有配对的公钥可以解开,有这个私钥的只有你,所以如果配对的公钥解开了数据,就说明这数据是你发的,相反,则不是.这个被称为签名。数字签名的意义就是这些数据与原文数据比对是否修改过。
DES助手类:
1 /// <summary>
2 /// 可逆对称加密 密钥长度8
3 /// </summary>
4 public class DesEncrypt
5 {
6 private static string _key = "fanfanfanfanfan";
7 private static byte[] _rgbKey = ASCIIEncoding.ASCII.GetBytes(_key.Substring(0, 8));
8 private static byte[] _rgbIV = ASCIIEncoding.ASCII.GetBytes(_key.Insert(0, "w").Substring(0, 8));
9
10 /// <summary>
11 /// DES 加密
12 /// </summary>
13 /// <param name="text">需要加密的值</param>
14 /// <returns>加密后的结果</returns>
15 public static string Encrypt(string text)
16 {
17 DESCryptoServiceProvider dsp = new DESCryptoServiceProvider();
18 using (MemoryStream memStream = new MemoryStream())
19 {
20 CryptoStream crypStream = new CryptoStream(memStream, dsp.CreateEncryptor(_rgbKey, _rgbIV), CryptoStreamMode.Write);
21 StreamWriter sWriter = new StreamWriter(crypStream);
22 sWriter.Write(text);
23 sWriter.Flush();
24 crypStream.FlushFinalBlock();
25 memStream.Flush();
26 return Convert.ToBase64String(memStream.GetBuffer(), 0, (int)memStream.Length);
27 }
28 }
29
30 /// <summary>
31 /// DES 解密
32 /// </summary>
33 /// <param name="encryptText"></param>
34 /// <returns>解密后的结果</returns>
35 public static string Decrypt(string encryptText)
36 {
37 DESCryptoServiceProvider dsp = new DESCryptoServiceProvider();
38 byte[] buffer = Convert.FromBase64String(encryptText);
39
40 using (MemoryStream memStream = new MemoryStream())
41 {
42 CryptoStream crypStream = new CryptoStream(memStream, dsp.CreateDecryptor(_rgbKey, _rgbIV), CryptoStreamMode.Write);
43 crypStream.Write(buffer, 0, buffer.Length);
44 crypStream.FlushFinalBlock();
45 return ASCIIEncoding.UTF8.GetString(memStream.ToArray());
46 }
47 }
48 }
AES助手类:
1 /// <summary>
2 /// AES加密解密
4 /// 密码必须是16位,否则会报错哈
5 /// </summary>
6 public class AESCryptoHelper
7 {
8 /// <summary>
9 /// APP默认加密Key
10 /// </summary>
11 public static string Default_AESKey = "1111111111111111";//必须是十六位
12
13 /// <summary>
14 /// AES 加密
15 /// </summary>
16 /// <param name="plainText">明文</param>
17 /// <param name="key">密码必须是16位,否则会报错哈</param>
18 /// <returns>密文</returns>
19 public static string Encrypt(string plainText, string key)
20 {
21 string result = null;
22 if (string.IsNullOrEmpty(plainText))
23 {
24 return result;
25 }
26 byte[] plainTextArray = Encoding.UTF8.GetBytes(plainText);
27 using (RijndaelManaged rijndaelManaged = new RijndaelManaged
28 {
29 Key = Encoding.UTF8.GetBytes(key),
30 Mode = CipherMode.ECB,
31 Padding = PaddingMode.PKCS7
32 })
33 {
34 using (ICryptoTransform cryptoTransform = rijndaelManaged.CreateEncryptor())
35 {
36 byte[] resultArray = cryptoTransform.TransformFinalBlock(plainTextArray, 0, plainTextArray.Length);
37 result = Convert.ToBase64String(resultArray, 0, resultArray.Length);
38 Array.Clear(resultArray, 0, resultArray.Length);
39 resultArray = null;
40 }
41 }
42 Array.Clear(plainTextArray, 0, plainTextArray.Length);
43 plainTextArray = null;
44 return result;
45 }
46
47 /// <summary>
48 /// AES 解密
49 /// </summary>
50 /// <param name="encryptText">密文</param>
51 /// <param name="key">密码必须是16位,否则会报错哈</param>
52 /// <returns>明文</returns>
53 public static string Decrypt(string encryptText, string key)
54 {
55 string result = null;
56 if (string.IsNullOrEmpty(encryptText))
57 {
58 return result;
59 }
60 byte[] encryptTextArray = Convert.FromBase64String(encryptText);
61 using (RijndaelManaged rijndaelManaged = new RijndaelManaged
62 {
63 Key = Encoding.UTF8.GetBytes(key),
64 Mode = CipherMode.ECB,
65 Padding = PaddingMode.PKCS7
66 })
67 {
68 using (ICryptoTransform cryptoTransform = rijndaelManaged.CreateDecryptor())
69 {
70 byte[] resultArray = cryptoTransform.TransformFinalBlock(encryptTextArray, 0, encryptTextArray.Length);
71 result = Encoding.UTF8.GetString(resultArray);
72 Array.Clear(resultArray, 0, resultArray.Length);
73 resultArray = null;
74 }
75 }
76 Array.Clear(encryptTextArray, 0, encryptTextArray.Length);
77 encryptTextArray = null;
78 return result;
79 }
80
81 /// <summary>
82 /// AES 加密(URL传参数加密)
83 /// </summary>
84 /// <param name="plainText">明文</param>
85 /// <param name="key"></param>
86 /// <returns>加密之后URL编码</returns>
87 public static string UrlEncrypt(string plainText, string key)
88 {
89 string encryptText = Encrypt(plainText, key);
90 return HttpUtilityHelper.UrlEncode(encryptText);
91 }
92
93 /// <summary>
94 /// AES 解密(URL传参数解密)
95 /// </summary>
96 /// <param name="encodeEncryptText">URL编码之后的密文</param>
97 /// <param name="key"></param>
98 /// <returns>明文</returns>
99 public static string UrlDecrypt(string encodeEncryptText, string key)
100 {
101 if (!string.IsNullOrEmpty(encodeEncryptText))
102 {
103 string encodeText = HttpUtilityHelper.UrlDecode(encodeEncryptText);
104 return Decrypt(encodeText, key);
105 }
106 return "";
107 }
108 }
MD5助手类:
1 /// <summary>
2 /// MD5
3 /// </summary>
4 public class MD5Encrypt
5 {
6 #region MD5
7 /// <summary>
8 /// MD5加密,和动网上的16/32位MD5加密结果相同,
9 /// 使用的UTF8编码
10 /// </summary>
11 /// <param name="source">待加密字串</param>
12 /// <param name="length">16或32值之一,其它则采用.net默认MD5加密算法</param>
13 /// <returns>加密后的字串</returns>
14 public static string Encrypt(string source, int length = 32)//默认参数
15 {
16 if (string.IsNullOrEmpty(source)) return string.Empty;
17 HashAlgorithm provider = CryptoConfig.CreateFromName("MD5") as HashAlgorithm;
18 byte[] bytes = Encoding.UTF8.GetBytes(source);//这里需要区别编码的
19 byte[] hashValue = provider.ComputeHash(bytes);
20 StringBuilder sb = new StringBuilder();
21 switch (length)
22 {
23 case 16://16位密文是32位密文的9到24位字符
24 for (int i = 4; i < 12; i++)
25 {
26 sb.Append(hashValue[i].ToString("x2"));
27 }
28 break;
29 case 32:
30 for (int i = 0; i < 16; i++)
31 {
32 sb.Append(hashValue[i].ToString("x2"));
33 }
34 break;
35 default:
36 for (int i = 0; i < hashValue.Length; i++)
37 {
38 sb.Append(hashValue[i].ToString("x2"));
39 }
40 break;
41 }
42 return sb.ToString();
43 }
44 #endregion MD5
45
46 #region MD5摘要
47 /// <summary>
48 /// 获取文件的MD5摘要
49 /// </summary>
50 /// <param name="fileName"></param>
51 /// <returns></returns>
52 public static string AbstractFile(string fileName)
53 {
54 using (FileStream file = new FileStream(fileName, FileMode.Open))
55 {
56 return AbstractFile(file);
57 }
58 }
59
60 /// <summary>
61 /// 根据stream获取文件摘要
62 /// </summary>
63 /// <param name="stream"></param>
64 /// <returns></returns>
65 public static string AbstractFile(Stream stream)
66 {
67 MD5 md5 = new MD5CryptoServiceProvider();
68 byte[] retVal = md5.ComputeHash(stream);
69
70 StringBuilder sb = new StringBuilder();
71 for (int i = 0; i < retVal.Length; i++)
72 {
73 sb.Append(retVal[i].ToString("x2"));
74 }
75 return sb.ToString();
76 }
77 #endregion
78 }
RSA助手类:
1 /// <summary>
2 /// RSA
3 /// </summary>
4 public class RsaEncrypt
5 {
6 /// <summary>
7 /// 生成公钥、私钥
8 /// </summary>
9 /// <returns>Encrypt Decrypt</returns>
10 public static KeyValuePair<string, string> GetKeyPair()
11 {
12 RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
13 string publicKey = RSA.ToXmlString(false);
14 string privateKey = RSA.ToXmlString(true);
15 return new KeyValuePair<string, string>(publicKey, privateKey);
16 }
17
18 /// <summary>
19 /// 加密:内容+加密key
20 /// </summary>
21 /// <param name="content"></param>
22 /// <param name="publicKey">加密key</param>
23 /// <returns></returns>
24 public static string Encrypt(string content, string publicKey)
25 {
26 RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
27 rsa.FromXmlString(publicKey);
28 UnicodeEncoding ByteConverter = new UnicodeEncoding();
29 byte[] DataToEncrypt = ByteConverter.GetBytes(content);
30 byte[] resultBytes = rsa.Encrypt(DataToEncrypt, false);
31 return Convert.ToBase64String(resultBytes);
32 }
33
34 /// <summary>
35 /// 解密 内容+解密key
36 /// </summary>
37 /// <param name="content"></param>
38 /// <param name="privateKey">解密key</param>
39 /// <returns></returns>
40 public static string Decrypt(string content, string privateKey)
41 {
42 byte[] dataToDecrypt = Convert.FromBase64String(content);
43 RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
44 RSA.FromXmlString(privateKey);
45 byte[] resultBytes = RSA.Decrypt(dataToDecrypt, false);
46 UnicodeEncoding ByteConverter = new UnicodeEncoding();
47 return ByteConverter.GetString(resultBytes);
48 }
49
50
51 /// <summary>
52 /// 可以合并在一起的,,每次产生一组新的密钥
53 /// </summary>
54 /// <param name="content"></param>
55 /// <param name="encryptKey">加密key</param>
56 /// <param name="decryptKey">解密key</param>
57 /// <returns>加密后结果</returns>
58 private static string Encrypt(string content, out string publicKey, out string privateKey)
59 {
60 RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider();
61 publicKey = rsaProvider.ToXmlString(false);
62 privateKey = rsaProvider.ToXmlString(true);
63
64 UnicodeEncoding ByteConverter = new UnicodeEncoding();
65 byte[] DataToEncrypt = ByteConverter.GetBytes(content);
66 byte[] resultBytes = rsaProvider.Encrypt(DataToEncrypt, false);
67 return Convert.ToBase64String(resultBytes);
68 }
69 }
Core版算法开源库
说明:通过Nuget安装:【NETCore.Encrypt】,版本为【2.0.8】,需要依赖Newtonsoft.json的版本 大于等于:12.0.1,包括的算法有:Base64、MD5、SHA系列、HAMC系列、AES、DES、RSA。
PS:还支持MD5、SHA系列、HMAC系列 对于String类型的扩展,如:var hashed3 = "ypf".MD5(); 大部分算法支持 string和byte[] 两种格式。
{ //1. Base64的编码和解码 var srcString = "ypf001"; var hashed1 = EncryptProvider.Base64Encrypt(srcString); //default encoding is UTF-8 var hashed2 = EncryptProvider.Base64Encrypt(srcString, Encoding.ASCII); //按照ascii进行编码 var strValue1 = EncryptProvider.Base64Decrypt(hashed1); //default encoding is UTF-8 var strValue2 = EncryptProvider.Base64Decrypt(hashed2, Encoding.ASCII); //按照ascii进行解码 } { //2. MD5 var srcString = "ypf001"; var hashed1 = EncryptProvider.Md5(srcString); //默认32位 var hashed2 = EncryptProvider.Md5(srcString, MD5Length.L16); //16位 Console.WriteLine($"ypf001的MD5加密(32位):{hashed1}"); Console.WriteLine($"ypf002的MD5加密(64位):{hashed2}"); //扩展用法 var hashed3 = srcString.MD5(); } { //3. SHA相关 var srcString = "ypf001"; var hashed1 = EncryptProvider.Sha1(srcString); var hashed2 = EncryptProvider.Sha256(srcString); var hashed3 = EncryptProvider.Sha384(srcString); var hashed4 = EncryptProvider.Sha512(srcString); //扩展用法(如下,其余类似) var extHash = srcString.SHA1(); } { //4. HAMC相关 var secretKey = "sflkasfkksfs"; var srcString = "ypf001"; var hashed1 = EncryptProvider.HMACMD5(srcString, secretKey); var hashed2 = EncryptProvider.HMACSHA1(srcString, secretKey); var hashed3 = EncryptProvider.HMACSHA256(srcString, secretKey); var hashed4 = EncryptProvider.HMACSHA384(srcString, secretKey); var hashed5 = EncryptProvider.HMACSHA512(srcString, secretKey); //扩展用法(如下,其余类似) var extHash = srcString.HMACSHA1(secretKey); } { //5. AES //利用算法生成key和iv(32位和16位),当然这里可以自己指定并保存好 //var aesKey = EncryptProvider.CreateAesKey(); //var key = aesKey.Key; //var iv = aesKey.IV; var secretKey = "asdfjketjnddkkaakkuyerbdsbgrtsaw"; //这里的key得32位 var iv = "ioeruwoeruo2aqwe"; //加密和解密的过程中可以加上iv矢量,使其安全性更高,这里的iv得16位 var srcString = "ypf001"; //加密 var encrypted1 = EncryptProvider.AESEncrypt(srcString, secretKey); var encrypted2 = EncryptProvider.AESEncrypt(srcString, secretKey, iv); //解密 var decrypted1 = EncryptProvider.AESDecrypt(encrypted1, secretKey); var decrypted2 = EncryptProvider.AESDecrypt(encrypted2, secretKey, iv); //PS:这里除了string加密,还可以对byte数组加密 } { //6. DES //利用算法生成key(24位),当然这里可以自己指定并保存好 //var desKey = EncryptProvider.CreateDesKey(); var secretKey = "asdfjketjnddkkaakkuyerbd"; //这里的key得24位 var srcString = "ypf001"; //加密 var encrypted1 = EncryptProvider.DESEncrypt(srcString, secretKey); //解密 var decrypted1 = EncryptProvider.DESDecrypt(encrypted1, secretKey); //PS:这里除了string加密,还可以对byte数组加密 } { //7.RSA //利用算法生成公钥和私钥,然后保存;当然这里可以自己指定并保存好 var rsaKey = EncryptProvider.CreateRsaKey(); //default is 2048 // var rsaKey = EncryptProvider.CreateRsaKey(RsaSize.R3072); var publicKey = rsaKey.PublicKey; var privateKey = rsaKey.PrivateKey; var srcString = "ypf001"; //加密 var encrypted1 = EncryptProvider.RSAEncrypt(publicKey, srcString); //公钥加密 //解密 var decrypted = EncryptProvider.RSADecrypt(privateKey, encrypted1); //私钥解密 } public enum RsaSize { R2048 = 2048, R3072 = 3072, R4096 = 4096 }
助手类封装:
/// <summary> /// 各种加密解密算法 /// 依赖程序集【NETCore.Encrypt】 /// </summary> public class SecurityHelp { /// <summary> /// Base64编码 /// </summary> /// <param name="srcString">需要编码的字符串</param> /// <returns></returns> public static string Base64Encrypt(string srcString) { return EncryptProvider.Base64Encrypt(srcString); //default encoding is UTF-8 } /// <summary> /// Base64编码 /// </summary> /// <param name="encString">需要解码的字符串</param> /// <returns></returns> public static string Base64Decrypt(string encString) { return EncryptProvider.Base64Decrypt(encString); //default encoding is UTF-8 } /// <summary> /// MD5加密 /// </summary> /// <param name="srcString">需要加密的字符串</param> /// <param name="num">位数,默认为32位,也可以是16位</param> /// <returns></returns> public static string Md5(string srcString, int num = 32) { if (num == 32) { return EncryptProvider.Md5(srcString); //默认32位 } else { return EncryptProvider.Md5(srcString, MD5Length.L16); //16位 } } /// <summary> /// SHA系列算法 /// </summary> /// <param name="srcString">需要加密的字符串</param> /// <param name="kind">类型</param> /// <returns></returns> public static string SHA(string srcString, string kind = "Sha512") { if (kind.Equals("Sha1")) { return EncryptProvider.Sha1(srcString); } else if (kind.Equals("Sha256")) { return EncryptProvider.Sha256(srcString); } else if (kind.Equals("Sha384")) { return EncryptProvider.Sha384(srcString); } else { return EncryptProvider.Sha512(srcString); } } /// <summary> /// HMAC系列算法 /// </summary> /// <param name="srcString">需要加密的字符串</param> /// <param name="secretKey">密钥</param> /// <param name="kind">类型</param> /// <returns></returns> public static string HMAC(string srcString, string secretKey, string kind = "HMACSHA512") { if (kind.Equals("HMACMD5")) { return EncryptProvider.HMACMD5(srcString, secretKey); } else if (kind.Equals("HMACSHA1")) { return EncryptProvider.HMACSHA1(srcString, secretKey); } else if (kind.Equals("HMACSHA256")) { return EncryptProvider.HMACSHA256(srcString, secretKey); } else if (kind.Equals("HMACSHA384")) { return EncryptProvider.HMACSHA384(srcString, secretKey); } else { return EncryptProvider.HMACSHA512(srcString, secretKey); } } /// <summary> /// 生成AES算法所需的Key和iv /// (当然这里可以自己指定并保存好) /// </summary> /// <param name="key">加密所需的key</param> /// <param name="iv">加密所需的矢量</param> public static void CreateAesKey(ref string key, ref string iv) { //利用算法生成key和iv(32位和16位),当然这里可以自己指定并保存好 var aesKey = EncryptProvider.CreateAesKey(); key = aesKey.Key; iv = aesKey.IV; } /// <summary> /// AES加密算法 /// </summary> /// <param name="srcString">需要加密的字符串</param> /// <param name="secretKey">密钥</param> /// <param name="iv">矢量(可以不填)</param> /// <returns></returns> public static string AESEncrypt(string srcString, string secretKey, string iv = "") { if (string.IsNullOrEmpty(iv)) { return EncryptProvider.AESEncrypt(srcString, secretKey); //表示不需要iv矢量的AES加密算法 } else { return EncryptProvider.AESEncrypt(srcString, secretKey, iv); //表示需要iv矢量的AES加密算法 } } /// <summary> /// AES解密算法 /// </summary> /// <param name="encString">需要解密的字符串</param> /// <param name="secretKey">密钥</param> /// <param name="iv">矢量(可以不填)</param> /// <returns></returns> public static string AESDecrypt(string encString, string secretKey, string iv = "") { if (string.IsNullOrEmpty(iv)) { return EncryptProvider.AESDecrypt(encString, secretKey); //表示不需要iv矢量的AES解密算法 } else { return EncryptProvider.AESDecrypt(encString, secretKey, iv); //表示需要iv矢量的AES解密算法 } } /// <summary> /// DES加密算法 /// </summary> /// <param name="srcString">需要加密的字符串</param> /// <param name="secretKey">密钥(这里的密钥需要是24位)</param> /// <returns></returns> public static string EDSEncrypt(string srcString, string secretKey) { return EncryptProvider.DESEncrypt(srcString, secretKey); } /// <summary> /// DES解密算法 /// </summary> /// <param name="encString">需要解密的字符串</param> /// <param name="secretKey">密钥</param> /// <returns></returns> public static string DESDecrypt(string encString, string secretKey) { return EncryptProvider.DESDecrypt(encString, secretKey); } /// <summary> /// 生成RSA算法所需的Key和iv /// (当然这里可以自己指定并保存好) /// </summary> /// <param name="PublicKey">公钥</param> /// <param name="PrivateKey">私钥</param> public static void CreateRsaKey(ref string PublicKey, ref string PrivateKey) { //利用算法生成公钥和私钥,然后保存;当然这里可以自己指定并保存好 var rsaKey = EncryptProvider.CreateRsaKey(); //default is 2048 // var rsaKey = EncryptProvider.CreateRsaKey(RsaSize.R3072); PublicKey = rsaKey.PublicKey; PrivateKey = rsaKey.PrivateKey; } /// <summary> /// RSA加密算法 /// </summary> /// <param name="srcString">需要加密的字符串</param> /// <param name="publicKey">公钥 加密</param> /// <returns></returns> public static string RSAEncrypt(string srcString, string publicKey) { return EncryptProvider.RSAEncrypt(publicKey, srcString); //公钥加密 } /// <summary> /// RSA解密算法 /// </summary> /// <param name="encString">需要解密的字符串</param> /// <param name="privateKey">私钥 解密</param> /// <returns></returns> public static string RSADecrypt(string encString, string privateKey) { return EncryptProvider.RSADecrypt(privateKey, encString); //私钥解密 } } public enum RsaSize { R2048 = 2048, R3072 = 3072, R4096 = 4096 }
未完待续...