【散列类型】 不可逆,严格说不算加密算法,是一种保证数据完整性的算法或数字签名.
1 public static string EnMd5(string str) 2 { 3 string pwd = ""; 4 MD5 md5 = MD5.Create(); 5 //注意编码UTF8/Unicode 6 byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(str)); 7 for (int i = 0; i < s.Length; i++) 8 { 9 pwd = pwd + s[i].ToString("x2"); 10 } 11 return pwd; 12 }
1 public string SHA1_Encrypt(string Source_String) 2 { 3 byte[] StrRes = Encoding.UTF8.GetBytes(Source_String); 4 HashAlgorithm iSHA = new SHA1CryptoServiceProvider(); 5 StrRes = iSHA.ComputeHash(StrRes); 6 StringBuilder EnText = new StringBuilder(); 7 foreach (byte iByte in StrRes) 8 { 9 EnText.AppendFormat("{0:x2}", iByte); 10 } 11 return EnText.ToString(); 12 }
1 public static string GetStreamMD5(Stream stream) 2 { 3 MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider(); 4 5 md5.ComputeHash(stream); 6 7 byte[] hash = md5.Hash; 8 9 StringBuilder result = new StringBuilder(); 10 11 foreach (byte byt in hash) 12 { 13 result.Append(String.Format("{0:X1}", byt)); 14 } 15 16 return result.ToString(); 17 }
【对称类型】使用相同的密钥进行数据的加密和解密.
3DES(Triple DES):是基于DES的对称算法,对一块数据用三个不同的密钥进行三次加密,强度更高, 因此,DES使用8B的加密向量和密钥,3DES使用24B的加密向量和密钥.
1 public class DESUtil 2 { 3 private static string DesKey8 = "abcd1234"; 4 //默认密钥向量 5 private static byte[] IV64 = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF }; 6 7 8 public static string EnDES(string encryptString) 9 { 10 return EnDES(encryptString, DesKey8); 11 } 12 public static string DeDES(string decryptString) 13 { 14 return DeDES(decryptString, DesKey8); 15 } 16 /// <summary> 17 /// DES加密字符串 18 /// </summary> 19 /// <param name="encryptString">待加密的字符串</param> 20 /// <param name="encryptKey">加密密钥,要求为8B</param> 21 /// <returns>加密成功返回加密后的字符串,失败返回源串</returns> 22 public static string EnDES(string encryptString, string encryptKey) 23 { 24 try 25 { 26 byte[] rgbKey = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 8)); 27 byte[] rgbIV = IV64; 28 byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString); 29 DESCryptoServiceProvider dCSP = new DESCryptoServiceProvider(); 30 MemoryStream mStream = new MemoryStream(); 31 CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write); 32 cStream.Write(inputByteArray, 0, inputByteArray.Length); 33 cStream.FlushFinalBlock(); 34 return Convert.ToBase64String(mStream.ToArray()); 35 } 36 catch 37 { 38 return encryptString; 39 } 40 } 41 42 /// <summary> 43 /// DES解密字符串 44 /// </summary> 45 /// <param name="decryptString">待解密的字符串</param> 46 /// <param name="decryptKey">解密密钥,要求为8B,和加密密钥相同</param> 47 /// <returns>解密成功返回解密后的字符串,失败返源串</returns> 48 public static string DeDES(string decryptString, string decryptKey) 49 { 50 try 51 { 52 byte[] rgbKey = Encoding.UTF8.GetBytes(decryptKey); 53 byte[] rgbIV = IV64; 54 byte[] inputByteArray = Convert.FromBase64String(decryptString); 55 DESCryptoServiceProvider DCSP = new DESCryptoServiceProvider(); 56 MemoryStream mStream = new MemoryStream(); 57 CryptoStream cStream = new CryptoStream(mStream, DCSP.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write); 58 cStream.Write(inputByteArray, 0, inputByteArray.Length); 59 cStream.FlushFinalBlock(); 60 return Encoding.UTF8.GetString(mStream.ToArray()); 61 } 62 catch 63 { 64 return decryptString; 65 } 66 } 67 }
1 public class DES3Util 2 { 3 4 private static string DesKey24="abcdddw6dwww5e1Jggge2E4oDF54G44"; 5 private static byte[] IV192= { 0xD2, 0xEE, 0xA6, 0x28, 0x93, 0x3B, 0xCD, 0x9F, 0x16, 0xC4, 0xF1, 0x7D, 0x30, 0xBA, 0x4D, 0xF9, 0xE2, 0x14, 0xC7, 0xE5, 0xA0, 0xBA, 0x4D, 0xF2 }; 6 7 /// <summary> 8 /// 3DES加密字符串 9 /// </summary> 10 /// <param name="encryptString">待加密的字符串</param> 11 /// <param name="encryptKey">加密密钥,要求24B</param> 12 /// <returns>加密成功返回加密后的字符串,失败返回源串</returns> 13 public static string En3DES(string encryptString) 14 { 15 return En3DES(encryptString, DesKey24); 16 } 17 public static string De3DES(string decryptString) 18 { 19 return De3DES(decryptString, DesKey24); 20 } 21 22 /// <summary> 23 /// 3DES加密字符串 24 /// </summary> 25 /// <param name="encryptString">待加密的字符串</param> 26 /// <param name="encryptKey">加密密钥,要求为8位</param> 27 /// <returns>加密成功返回加密后的字符串,失败返回源串</returns> 28 public static string En3DES(string encryptString, string encryptKey) 29 { 30 try 31 { 32 byte[] rgbKey = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 24)); 33 byte[] rgbIV =IV192; 34 byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString); 35 36 TripleDES dCSP = new TripleDESCryptoServiceProvider(); 37 MemoryStream mStream = new MemoryStream(); 38 CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, 39 rgbIV), CryptoStreamMode.Write); 40 cStream.Write(inputByteArray, 0, inputByteArray.Length); 41 cStream.FlushFinalBlock(); 42 cStream.Close(); 43 byte[] content=mStream.ToArray(); 44 mStream.Close(); 45 return Convert.ToBase64String(content); 46 } 47 catch (Exception e) 48 { 49 return encryptString; 50 } 51 } 52 53 54 /// <summary> 55 /// 3DES解密字符串 56 /// </summary> 57 /// <param name="decryptString">待解密的字符串</param> 58 /// <param name="decryptKey">解密密钥,要求为24B,和加密密钥相同</param> 59 /// <returns>解密成功返回解密后的字符串,失败返源串</returns> 60 public static string De3DES(string decryptString, string decryptKey) 61 { 62 try 63 { 64 byte[] rgbKey = Encoding.UTF8.GetBytes(decryptKey.Substring(0, 24)); 65 byte[] rgbIV = IV192; 66 byte[] inputByteArray = Convert.FromBase64String(decryptString); 67 TripleDES DCSP = new TripleDESCryptoServiceProvider(); 68 MemoryStream mStream = new MemoryStream(inputByteArray); 69 70 CryptoStream cStream = new CryptoStream(mStream, DCSP.CreateDecryptor(rgbKey, 71 rgbIV), CryptoStreamMode.Read); 72 StreamReader reader=new StreamReader(cStream); 73 string content=reader.ReadToEnd(); 74 reader.Close(); 75 cStream.Close(); 76 mStream.Close(); 77 78 return content; 79 } 80 catch 81 { 82 return decryptString; 83 } 84 } 85 }
【非对称类型】 使用不同的密钥进行加密和解密.
非对称式加密就是加密和解密所使用的不是同一个密钥,通常有两个密钥,称为“公钥”和“私钥”,它们两个必需配对使用,否则不能打开加密文件。这里的“公钥”是指可以对外公布的,“私钥”则不能,只能由持有人一个人知道。它的优越性就在这里,因为对称式的加密方法如果是在网络上传输加密文件就很难把密钥告诉对方,不管用什么方法都有可能被别窃取。而非对称式的加密方法有两个密钥,且其中的“公钥”是可以公开的,也就不怕别人知道,收件人解密时只要用自己的私钥即可以,这样就很好地避免了密钥的传输安全性问题。
在不对称加密中,如果使用一个公钥进行加密,就应该使用对应的私钥进行解密,如果使用私钥加密,就应该使用对应的公钥进行解密.
例如:A给B发一份邮件,A希望除了B以外其他人都不能阅读改邮件,所以使用B的公钥加密,这样B打开邮件并用他的私钥解密,这种方式可以保证除了B以外其他人无法阅读改邮件.还有一个问题是,除了A以外还有C,D,E都可以给B发送邮件,这样就必须先解决一个问题,就是要确定发送者,而且关键是要避免发送方的签名被人盗用.
这时可以使用发送方的私钥对一个固定的字符串进行加密,让后接收方通过使用发送方的公钥进行检验,确定其真实性,这样A发送的邮件确保只有B能阅读,而B接收的邮件也确定是A发送的.
1 public class ECDSAUtil 2 { 3 //CngKey类支持的系统: 4 //Windows 7, 5 //Windows Vista SP1 或更高版本, 6 //Windows Server 2008(不支持服务器核心), 7 //Windows Server 2008 R2(支持 SP1 或更高版本的服务器核心) 8 //http://msdn.microsoft.com/zh-cn/library/system.security.cryptography.cngalgorithm.ecdiffiehellmanp256%28v=vs.100%29.aspx 9 10 public static void Test() 11 { 12 CreateKey(); 13 byte[] SrcData = Encoding.UTF8.GetBytes("Qiang"); 14 byte[] signature = EnSignature(SrcData, Key); 15 bool IsRight = VerifySignature(SrcData, signature, PubicKey); 16 17 } 18 19 20 public static CngKey Key; 21 public static byte[] PubicKey; 22 public static string TempXmlPublicKey;//用于传输 23 24 public static void CreateKey() 25 { 26 Key = CngKey.Create(CngAlgorithm.ECDsaP256); 27 PubicKey = Key.Export(CngKeyBlobFormat.GenericPublicBlob); 28 TempXmlPublicKey = new ECDsaCng(Key).ToXmlString(false); 29 } 30 31 public static byte[] EnSignature(byte[] srcdata, CngKey key) 32 { 33 ECDsaCng alg = new ECDsaCng(key); 34 byte[] result = alg.SignData(srcdata); 35 alg.Clear(); 36 return result; 37 } 38 39 40 public static bool VerifySignature(byte[] srcdata, byte[] signature, byte[] pubickey) 41 { 42 bool result=false; 43 using (CngKey key = CngKey.Import(pubickey,CngKeyBlobFormat.GenericPublicBlob)) 44 { 45 ECDsaCng alg = new ECDsaCng(key); 46 result = alg.VerifyData(srcdata, signature); 47 alg.Clear(); 48 } 49 return result; 50 } 51 52 }
1 public class ECDiffieHellmanUtil 2 { 3 static CngKey KeyA; 4 static CngKey KeyB; 5 static byte[] pubKeyA; 6 static byte[] pubKeyB; 7 static void CreateKey() 8 { 9 KeyA = CngKey.Create(CngAlgorithm.ECDiffieHellmanP256); 10 KeyB = CngKey.Create(CngAlgorithm.ECDiffieHellmanP256); 11 pubKeyA = KeyA.Export(CngKeyBlobFormat.EccPublicBlob); 12 pubKeyB = KeyB.Export(CngKeyBlobFormat.EccPublicBlob); 13 } 14 public static bool Test() 15 { 16 CreateKey(); 17 byte[] symmkeyA, symmkeyB; 18 19 using( ECDiffieHellmanCng algA = new ECDiffieHellmanCng(KeyA)) 20 using(CngKey pubkey_B = CngKey.Import(pubKeyB, CngKeyBlobFormat.EccPublicBlob)) 21 { 22 symmkeyA = algA.DeriveKeyMaterial(pubkey_B); 23 algA.Clear(); 24 } 25 using(ECDiffieHellmanCng algB = new ECDiffieHellmanCng(KeyB)) 26 using(CngKey pubkey_A = CngKey.Import(pubKeyA, CngKeyBlobFormat.EccPublicBlob)) 27 { 28 symmkeyB = algB.DeriveKeyMaterial(pubkey_A); 29 algB.Clear(); 30 } 31 32 return symmkeyA == symmkeyB; 33 34 } 35 36 37 }
[注1]Cng前缀或后缀的类支持的平台:Windows 7, Windows Vista SP1 或更高版本, Windows Server 2008(不支持服务器核心), Windows Server 2008 R2(支持 SP1 或更高版本的服务器核心)
[注2]在Cng的加密过程中,不要使用Encoding类将加密的字节数组转换为字符串在进行解密,Encoding类验证和转换Unicode不允许使用的无效值,转为字符串再解密可能变为不一样的结果.
[注3]在网络通信中,经常是先使用非对称的密钥进行互换,然后再使用对称密钥加密在线上发送的数据.
ECDiffieHellman算法用于密钥的互换,从而进行安全传送.
在ECDiffieHellman实例中,使用发送方的私钥以及接收方的公钥生成的字节数组作为对称加密的密钥,对发送的内容进行加密,而接收方可以使用自己的私钥以及发送方的公钥也生成一个相同的密钥,对发送的内容进行解密.这就避免了对称加密的密钥传输过程.当然在此之前必须还要判断发送方以确定其公钥。这种情况可以先用发送方的的私钥加密生成一个签名,然后接收方使用发送方公钥进行验证,这样就可以确定发送方了。
[注4]完整的密钥互换和安全传送:A给B发送邮件.
1. A使用ECDsa算法先对一个字符串常量使用A的私钥进行加密,生成一个签名用于确定发送方的真实性.
2. A使用ECDiffieHellman算法,用A私钥和B的公钥生成一个密钥.
3. A使用生成的密钥对发送的内容进行加密.
4.B使用ECDsa算法对A的签名进行验证,确定是A发送的.
5.B使用 使用ECDiffieHellman算法,用B私钥和A的公钥生成一个密钥.
6.B 使用生成的密钥对发送的内容进行解密.