.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位。