你好,欢迎来到电脑编程技巧与维护杂志社! 杂志社简介广告服务读者反馈编程社区  
合订本订阅
 
 
您的位置:技术专栏 / Java专栏
.net下可逆的加密算法
 

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

大家在使用的时候不要忘记导入命名空间
  推荐精品文章

·2024年6月目录 
·2024年5月目录 
·2024年4月目录 
·2024年3月目录 
·2024年2月目录 
·2024年1月目录
·2023年12月目录
·2023年11月目录
·2023年10月目录
·2023年9月目录 
·2023年8月目录 
·2023年7月目录
·2023年6月目录 
·2023年5月目录

  联系方式
TEL:010-82561037
Fax: 010-82561614
QQ: 100164630
Mail:gaojian@comprg.com.cn

  友情链接
 
Copyright 2001-2010, www.comprg.com.cn, All Rights Reserved
京ICP备14022230号-1,电话/传真:010-82561037 82561614 ,Mail:gaojian@comprg.com.cn
地址:北京市海淀区远大路20号宝蓝大厦E座704,邮编:100089