C#做的一个加密/解密的类 | |
前两年写的东西,现在整理一下发出来!以前公司需要做WebService,并且对WebService的SoapHeader进行加密,所以就写了这么个东东!使用这个类,需要密钥管理!为了保证数据的安全性往往要对数据进行加密,但是加密的缺点之一,就是影响程序的运行效率,所以,当时我的思路是只对用户的登录信息(用户名,密码)进行加密!数据用明文传输,用户信息验证没有通过的情况下, 不进行数据传输。 实际在网络通讯中,使用密钥匙的方式并非无懈可击,如果黑客可以捕捉到用密钥加密的,用户验证信息,然后,做个模拟请求,向提供WebService的服务器发请求,还是可以获得请求数据!所以,我又使用了IP或者域名绑定的方式!毕竟,WebService不是直接对最终用户提供的!所以,加上以上这些手段后,就算有不良企图者想通过非法方式获得WebService提供的服务,就再费点劲吧! 还有一点安全建议,就是定期的更换密钥,在这个例子中,我用的是对称加密,加密方和解密方的密钥一致!定期的更换密钥可以让安全性提高一大截! 大家要有更好的方法,或者建议,可以留言讨论一下!共同提高! 代码如下: using System; using System.Security.Cryptography ; using System.Text; using System.IO; namespace SEDO { /// <summary> /// SEDO 的摘要说明。 /// SEDO 实现的是用一个封装了4种对称加密方法(Des,Rc2,Rijndael,TripleDes)的组件 /// /// 注意事项: /// 1:TripleDes和Rijndael加密/解密对象使用16或者24位byte的Key /// 2:Rijndael只能使用16位的初始化向量IV /// 3:Des和Rc2均使用8位Byte的Key和IV /// 4:对需要加密/解密的数据流采用何种方法进行编码/解码,由调用组件的用户自己决定 /// 5:密钥和初始化向量IV由使用者自己定义 /// 程序员: 王海波 2003-05-19 hwnanghb@21cn.com /// </summary> //定义加密类型的枚举 public enum EncryptionAlgorithm {Des = 1, Rc2, Rijndael, TripleDes}; //定义加密类 internal class EncryptTransformer { private EncryptionAlgorithm algorithmID; private byte[] initVec; private byte[] encKey; internal EncryptTransformer(EncryptionAlgorithm algId) { //Save the algorithm being used. algorithmID = algId; } internal ICryptoTransform GetCryptoServiceProvider(byte[] bytesKey) { //当数据密钥Key或者初始化向量IV为空的时候,将使用加密对象自动产生的密钥Key或者初始化向量IV switch (algorithmID) { case EncryptionAlgorithm.Des: { DES des = new DESCryptoServiceProvider(); des.Mode = CipherMode.CBC; // See if a key was provided if (null == bytesKey) { encKey = des.Key; } else { des.Key = bytesKey; encKey = des.Key; } // See if the client provided an initialization vector if (null == initVec) { // Have the algorithm create one initVec = des.IV; } else { //No, give it to the algorithm des.IV = initVec; } return des.CreateEncryptor(); } case EncryptionAlgorithm.TripleDes: { TripleDES des3 = new TripleDESCryptoServiceProvider(); des3.Mode = CipherMode.CBC; // See if a key was provided if (null == bytesKey) { encKey = des3.Key; } else { des3.Key = bytesKey; encKey = des3.Key; } // See if the client provided an IV if (null == initVec) { //Yes, have the alg create one initVec = des3.IV; } else { //No, give it to the alg. des3.IV = initVec; } return des3.CreateEncryptor(); } case EncryptionAlgorithm.Rc2: { RC2 rc2 = new RC2CryptoServiceProvider(); rc2.Mode = CipherMode.CBC; // Test to see if a key was provided if (null == bytesKey) { encKey = rc2.Key; } else { rc2.Key = bytesKey; encKey = rc2.Key; } // See if the client provided an IV if (null == initVec) { //Yes, have the alg create one initVec = rc2.IV; } else { //No, give it to the alg. rc2.IV = initVec; } return rc2.CreateEncryptor(); } case EncryptionAlgorithm.Rijndael: { Rijndael rijndael = new RijndaelManaged(); rijndael.Mode = CipherMode.CBC; // Test to see if a key was provided if(null == bytesKey) { encKey = rijndael.Key; } else { rijndael.Key = bytesKey; encKey = rijndael.Key; } // See if the client provided an IV if(null == initVec) { //Yes, have the alg create one initVec = rijndael.IV; } else { //No, give it to the alg. rijndael.IV = initVec; } return rijndael.CreateEncryptor(); } default: { throw new CryptographicException("Algorithm ID ''" + algorithmID + "'' not supported."); } } } //加密的偏移向量 internal byte[] IV { get{return initVec;} set{initVec = value;} } //加密的密钥 internal byte[] Key { get{return encKey;} set{encKey = value;} } } //定义解密类 internal class DecryptTransformer { private EncryptionAlgorithm algorithmID; private byte[] initVec; private byte[] encKey; internal DecryptTransformer(EncryptionAlgorithm deCryptId) { algorithmID = deCryptId; } //加密的偏移向量 internal byte[] IV { get{return initVec;} set{initVec = value;} } //加密的密钥 internal byte[] Key { get{return encKey;} set{encKey = value;} } internal ICryptoTransform GetCryptoServiceProvider(byte[] bytesKey) { //当数据密钥Key或者初始化向量IV为空的时候,将使用加密对象自动产生的密钥Key或者初始化向量IV switch (algorithmID) { case EncryptionAlgorithm.Des: { DES des = new DESCryptoServiceProvider(); des.Mode = CipherMode.CBC; des.Key = bytesKey; des.IV = initVec; return des.CreateDecryptor(); } case EncryptionAlgorithm.TripleDes: { TripleDES des3 = new TripleDESCryptoServiceProvider(); des3.Mode = CipherMode.CBC; return des3.CreateDecryptor(bytesKey, initVec); } case EncryptionAlgorithm.Rc2: { RC2 rc2 = new RC2CryptoServiceProvider(); rc2.Mode = CipherMode.CBC; return rc2.CreateDecryptor(bytesKey, initVec); } case EncryptionAlgorithm.Rijndael: { Rijndael rijndael = new RijndaelManaged(); rijndael.Mode = CipherMode.CBC; return rijndael.CreateDecryptor(bytesKey, initVec); } default: { throw new CryptographicException("Algorithm ID ''" + algorithmID + "'' not supported."); } } } //end GetCryptoServiceProvider } //定义加密者类 public class Encryptor { private EncryptTransformer transformer; private byte[] initVec; private byte[] encKey; public Encryptor(EncryptionAlgorithm algId) { transformer = new EncryptTransformer(algId); } public byte[] Encrypt(byte[] bytesData, byte[] bytesKey,byte[] bytesIV) { //设置流对象用来保存加密数据字节流. MemoryStream memStreamEncryptedData = new MemoryStream(); transformer.IV=bytesIV; transformer.Key=bytesKey; ICryptoTransform transform = transformer.GetCryptoServiceProvider(bytesKey); CryptoStream encStream = new CryptoStream(memStreamEncryptedData,transform,CryptoStreamMode.Write); try { //将加密数据写进流对象 encStream.Write(bytesData, 0, bytesData.Length); } catch(Exception ex) { throw new Exception("在数据加密的时候出现错误!错误提示: \n" + ex.Message); } //设置加密的Key和初始向量IV属性 encKey = transformer.Key; initVec = transformer.IV; encStream.FlushFinalBlock(); encStream.Close(); //Send the data back. return memStreamEncryptedData.ToArray(); } public byte[] IV { get{return initVec;} set{initVec = value;} } public byte[] Key { get{return encKey;} set{encKey = value;} } } //定义解密者类 public class Decryptor { private DecryptTransformer transformer; private byte[] initVec; private byte[] encKey; public Decryptor(EncryptionAlgorithm algId) { transformer = new DecryptTransformer(algId); } public byte[] Decrypt(byte[] bytesData, byte[] bytesKey,byte[] bytesIV) { //设置流对象用来保存解密数据字节流. MemoryStream memStreamDecryptedData = new MemoryStream(); //Pass in the initialization vector. transformer.IV = bytesIV; transformer.Key = bytesKey; ICryptoTransform transform = transformer.GetCryptoServiceProvider(bytesKey); CryptoStream decStream = new CryptoStream(memStreamDecryptedData,transform, CryptoStreamMode.Write); try { decStream.Write(bytesData, 0, bytesData.Length); } catch(Exception ex) { throw new Exception("在数据解密的时候出现错误!错误提示: \n" + ex.Message); } decStream.FlushFinalBlock(); decStream.Close(); // 返回解密数据. return memStreamDecryptedData.ToArray(); } public byte[] IV { get{return initVec;} set{initVec = value;} } public byte[] Key { get{return encKey;} set{encKey = value;} } } //类描述:文件加密/解密类 public class SecurityFile { private DecryptTransformer Dec_Transformer; //解密转换器 private EncryptTransformer Enc_Transformer; //加密转换器 private byte[] initVec; private byte[] encKey; public SecurityFile(EncryptionAlgorithm algId) { Dec_Transformer = new DecryptTransformer(algId); Enc_Transformer = new EncryptTransformer(algId); } //加密的偏移向量 internal byte[] IV { get{return initVec;} set{initVec = value;} } //加密的密钥 internal byte[] Key { get{return encKey;} set{encKey = value;} } //功能描述:加密文件 public void EncryptFile(string inFileName, string outFileName, byte[] bytesKey, byte[] bytesIV) { try { FileStream fin = new FileStream(inFileName, FileMode.Open, FileAccess.Read); FileStream fout = new FileStream(outFileName, FileMode.OpenOrCreate, FileAccess.Write); fout.SetLength(0); //Create variables to help with read and write. byte[] bin = new byte[100]; //This is intermediate storage for the encryption. long rdlen = 0; //This is the total number of bytes written. long totlen = fin.Length; //This is the total length of the input file. int len; //This is the number of bytes to be written at a time. Enc_Transformer.IV=bytesIV; Enc_Transformer.Key=bytesKey; ICryptoTransform transform = Enc_Transformer.GetCryptoServiceProvider(bytesKey); CryptoStream encStream = new CryptoStream(fout, transform, CryptoStreamMode.Write); //Read from the input file, then encrypt and write to the output file. while(rdlen < totlen) { len = fin.Read(bin, 0, 100); encStream.Write(bin, 0, len); rdlen = rdlen + len; } encStream.Close(); fout.Close(); fin.Close(); } catch(Exception ex) { throw new Exception("在文件加密的时候出现错误!错误提示: \n" + ex.Message); } } //功能描述:解密文件 public void DecryptFile(string inFileName, string outFileName, byte[] bytesKey, byte[] bytesIV) { try { FileStream fin = new FileStream(inFileName, FileMode.Open, FileAccess.Read); FileStream fout = new FileStream(outFileName, FileMode.OpenOrCreate, FileAccess.Write); fout.SetLength(0); //Create variables to help with read and write. byte[] bin = new byte[100]; //This is intermediate storage for the encryption. long rdlen = 0; //This is the total number of bytes written. long totlen = fin.Length; //This is the total length of the input file. int len; //This is the number of bytes to be written at a time. Dec_Transformer.IV=bytesIV; Dec_Transformer.Key=bytesKey; ICryptoTransform transform = Dec_Transformer.GetCryptoServiceProvider(bytesKey); CryptoStream encStream = new CryptoStream(fout, transform, CryptoStreamMode.Write); //Read from the input file, then encrypt and write to the output file. while(rdlen < totlen) { len = fin.Read(bin, 0, 100); encStream.Write(bin, 0, len); rdlen = rdlen + len; } encStream.Close(); fout.Close(); fin.Close(); } catch(Exception ex) { throw new Exception("在文件加密的时候出现错误!错误提示: \n" + ex.Message); } } } } |