.Net提供了许多可你的加密算法,总有一种适合你的加密需求。java中也有同类算法的实现,可以和.Net相互操作。网上的加密算法的文章很多,好用的却没有几个。MS上有一篇关于可逆加密算法实现的文章写得不错。估计是外国人写的,不支持中文。另外,他的结构也不是很符合我们常用的需求。我对他进行了一些改进,使它具有中国特色。
using System; using System.Security.Cryptography; using System.IO; using System.Text;
namespace Core { /// <summary> /// Encryption 的摘要说明。 /// </summary> public class Decryptor {
private DecryptTransformer transformer; private byte[] initVec;
public Decryptor(EncryptionAlgorithm algId) { transformer = new DecryptTransformer(algId); }
public byte[] Decrypt(byte[] bytesData, byte[] bytesKey) { //为解密数据设置内存流。 MemoryStream memStreamDecryptedData = new MemoryStream();
//传递初始化向量。 if(initVec!=null) { transformer.IV = initVec; } 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(); } //end Decrypt
public byte[] IV { set{initVec = value;} }
}
internal class DecryptTransformer {
private EncryptionAlgorithm algorithmID; private byte[] initVec;
internal DecryptTransformer(EncryptionAlgorithm deCryptId) { algorithmID = deCryptId; } internal ICryptoTransform GetCryptoServiceProvider(byte[] bytesKey) { // Pick the provider. switch (algorithmID) { case EncryptionAlgorithm.Des: { DES des = new DESCryptoServiceProvider(); des.Mode = CipherMode.CBC; des.Key = bytesKey; if(initVec!=null) { 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("算法 ID '" + algorithmID + "' 不支持。"); } } } //end GetCryptoServiceProvider internal byte[] IV { set{initVec = value;} }
}
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) { //设置将保存加密数据的流。 MemoryStream memStreamEncryptedData = new MemoryStream(); if(initVec!=null) { transformer.IV = initVec; } 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); } //为客户端进行检索设置初始化向量和密钥 encKey = transformer.Key; if(transformer.IV!=null) { initVec = transformer.IV; } encStream.FlushFinalBlock(); encStream.Close();
//发送回数据。 return memStreamEncryptedData.ToArray(); }//end Encrypt
public byte[] IV { get{return initVec;} set{initVec = value;} }
public byte[] Key { get{return encKey;} }
}
public enum EncryptionAlgorithm {Des = 1, Rc2, Rijndael, TripleDes};
internal class EncryptTransformer {
private EncryptionAlgorithm algorithmID; private byte[] initVec; private byte[] encKey;
internal byte[] IV { get{return initVec;} set{initVec = value;} } internal byte[] Key { get{return encKey;} }
internal EncryptTransformer(EncryptionAlgorithm algId) { //保存正在使用的算法。 algorithmID = algId; }
internal ICryptoTransform GetCryptoServiceProvider(byte[] bytesKey) { // 选取提供程序。 switch (algorithmID) { case EncryptionAlgorithm.Des: { DES des = new DESCryptoServiceProvider(); des.Mode = CipherMode.CBC;
// 查看是否提供了密钥 if (null == bytesKey) { encKey = des.Key; } else { des.Key = bytesKey; encKey = des.Key; } // 查看客户端是否提供了初始化向量 if (null == initVec) { // 让算法创建一个 //initVec = des.IV; } else { //不,将它提供给算法 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; } // 查看客户端是否提供了初始化向量 if (null == initVec) { //是,让算法创建一个 initVec = des3.IV; } else { //不,将它提供给算法。 des3.IV = initVec; } return des3.CreateEncryptor(); } case EncryptionAlgorithm.Rc2: { RC2 rc2 = new RC2CryptoServiceProvider(); rc2.Mode = CipherMode.CBC; // 测试是否提供了密钥 if (null == bytesKey) { encKey = rc2.Key; } else { rc2.Key = bytesKey; encKey = rc2.Key; } // 查看客户端是否提供了初始化向量 if (null == initVec) { //是,让算法创建一个 initVec = rc2.IV; } else { //不,将它提供给算法。 rc2.IV = initVec; } return rc2.CreateEncryptor(); } case EncryptionAlgorithm.Rijndael: { Rijndael rijndael = new RijndaelManaged(); rijndael.Mode = CipherMode.CBC; // 测试是否提供了密钥 if(null == bytesKey) { encKey = rijndael.Key; } else { rijndael.Key = bytesKey; encKey = rijndael.Key; } // 查看客户端是否提供了初始化向量 if(null == initVec) { //是,让算法创建一个 initVec = rijndael.IV; } else { //不,将它提供给算法。 rijndael.IV = initVec; } return rijndael.CreateEncryptor(); } default: { throw new CryptographicException("算法 ID '" + algorithmID + "' 不受支持。"); } } }
} public class Cryptography { public static string EncryptData(string plainstr,string ASCIIKey, string ASCIIInitializationVector,EncryptionAlgorithm algorithm) { try { // Init variables. byte[] IV = null; byte[] cipherText = null; byte[] key = null;
//试图加密。 //创建 Encryptor。 Encryptor enc = new Encryptor(algorithm);//EncryptionAlgorithm.Des); byte[] plainText = Encoding.UTF8.GetBytes(plainstr);
if ((EncryptionAlgorithm.TripleDes == algorithm) || (EncryptionAlgorithm.Rijndael == algorithm)) { //3Des 仅与 16 或 24 字节密钥一起使用。 //key = Encoding.ASCII.GetBytes("password12345678");//?Key key = Encoding.ASCII.GetBytes(ASCIIKey);//?Key if (EncryptionAlgorithm.Rijndael == algorithm) { // 对于 Rijndael,必须为 16 字节。 // IV = Encoding.ASCII.GetBytes("init vec is big."); if(ASCIIInitializationVector!=null) { IV = Encoding.ASCII.GetBytes(ASCIIInitializationVector); } } else { if(ASCIIInitializationVector!=null) { // IV = Encoding.ASCII.GetBytes("init vec"); IV = Encoding.ASCII.GetBytes(ASCIIInitializationVector); } } } else { //Des 仅使用 8 字节的密钥。其他使用长度可变的密钥。 //将密钥设置为空以生成一个新密钥。
key = Encoding.ASCII.GetBytes(ASCIIKey); if(ASCIIInitializationVector!=null) { IV = Encoding.ASCII.GetBytes(ASCIIInitializationVector); } } // 取消注释后面的行,为您生成密钥或初始化向量。 if(ASCIIInitializationVector!=null) { enc.IV = IV; } // Perform the encryption. cipherText = enc.Encrypt(plainText, key);
string str=Bytes2StrAccordingPosition(cipherText); return str; } catch(Exception ex) { //Console.WriteLine("加密时发生异常. " + ex.Message); return ""; }
}
private static string Bytes2StrAccordingPosition(byte[] cbytes) { string str=""; for(int i=0;i<cbytes.Length;i++) { str=str+Convert.ToChar(cbytes[i]); } return str; }
private static byte[] Str2BytesAccordingPositon(string str) { char[] strchars=str.ToCharArray(); byte[] bytes=new byte[str.Length];
for(int i=0;i<str.Length;i++) { bytes[i]=Convert.ToByte(strchars[i]); } return bytes; } public static string DecryptData(string cipherText,string ASCIIKey, string ASCIIInitializationVector,EncryptionAlgorithm algorithm) {
try { byte[] IV = Encoding.ASCII.GetBytes(ASCIIInitializationVector); byte[] key =Encoding.ASCII.GetBytes(ASCIIKey);
Decryptor dec = new Decryptor(algorithm); if(ASCIIInitializationVector!=null) { dec.IV = IV; } // 继续并解密。 byte[] cipherTextbytes=Str2BytesAccordingPositon(cipherText); byte[] plainText = dec.Decrypt(cipherTextbytes, key); return Encoding.UTF8.GetString(plainText); } catch(Exception ex) { return "";
}
}
} } 如何使用呢?
很简单:
[Test] public void Des() { string plaintext="haha"; string encodestr=Cryptography.EncryptData(plaintext,"password","ini vect",EncryptionAlgorithm.Des); string decodestr=Cryptography.DecryptData(encodestr,"password","ini vect",EncryptionAlgorithm.Des); Assert.IsTrue(plaintext==decodestr); } [Test] public void RC2() { string plaintext="haha"; string encodestr=Cryptography.EncryptData(plaintext,"password","ini vect",EncryptionAlgorithm.Rc2); string decodestr=Cryptography.DecryptData(encodestr,"password","ini vect",EncryptionAlgorithm.Rc2); Assert.IsTrue(plaintext==decodestr); } [Test] public void TripleDes() { string plaintext="haha"; string encodestr=Cryptography.EncryptData(plaintext,"password12345678","init vec",EncryptionAlgorithm.TripleDes); string decodestr=Cryptography.DecryptData(encodestr,"password12345678","init vec",EncryptionAlgorithm.TripleDes); Assert.IsTrue(plaintext==decodestr); } [Test] public void Rijndael() { string plaintext="haha"; string encodestr=Cryptography.EncryptData(plaintext,"password12345678","password12345679",EncryptionAlgorithm.Rijndael); string decodestr=Cryptography.DecryptData(encodestr,"password12345678","password12345679",EncryptionAlgorithm.Rijndael); Assert.IsTrue(plaintext==decodestr); }
注意:不同的加密算法要求的密码,初始向量有长度限制。要注意看代码中的注释。例如:des中key,vect要求是8位。 大家在使用的时候不要忘记导入命名空间
|