JAVA和C# 3DES加密解密

最近 一个项目.net 要调用JAVA的WEB SERVICE,数据采用3DES加密,涉及到两种语言3DES一致性的问题,
下面分享一下,
这里的KEY采用Base64编码,便用分发,因为Java的Byte范围为-128至127,c#的Byte范围是0-255
核心是确定Mode和Padding,关于这两个的意思可以搜索3DES算法相关文章
一个是C#采用CBC Mode,PKCS7 Padding,Java采用CBC Mode,PKCS5Padding Padding,
另一个是C#采用ECB Mode,PKCS7 Padding,Java采用ECB Mode,PKCS5Padding Padding,
Java的ECB模式不需要IV
对字符加密时,双方采用的都是UTF-8编码

下面是C#代码

  /// <summary>
     /// DES3加密解密
     /// </summary>
     public  class  Des3
     {
         #region CBC模式**
 
         /// <summary>
         /// DES3 CBC模式加密
         /// </summary>
         /// <param name="key">密钥</param>
         /// <param name="iv">IV</param>
         /// <param name="data">明文的byte数组</param>
         /// <returns>密文的byte数组</returns>
         public  static  byte [] Des3EncodeCBC(  byte [] key,  byte [] iv,  byte [] data )
         {
             //复制于MSDN
 
             try
             {
                 // Create a MemoryStream.
                 MemoryStream mStream =  new  MemoryStream();
 
                 TripleDESCryptoServiceProvider tdsp =  new  TripleDESCryptoServiceProvider();
                 tdsp.Mode = CipherMode.CBC;              //默认值
                 tdsp.Padding = PaddingMode.PKCS7;        //默认值
 
                 // Create a CryptoStream using the MemoryStream 
                 // and the passed key and initialization vector (IV).
                 CryptoStream cStream =  new  CryptoStream( mStream,
                     tdsp.CreateEncryptor( key, iv ),
                     CryptoStreamMode.Write );
 
                 // Write the byte array to the crypto stream and flush it.
                 cStream.Write( data, 0, data.Length );
                 cStream.FlushFinalBlock();
 
                 // Get an array of bytes from the 
                 // MemoryStream that holds the 
                 // encrypted data.
                 byte [] ret = mStream.ToArray();
 
                 // Close the streams.
                 cStream.Close();
                 mStream.Close();
 
                 // Return the encrypted buffer.
                 return  ret;
             }
             catch  ( CryptographicException e )
             {
                 Console.WriteLine(  "A Cryptographic error occurred: {0}" , e.Message );
                 return  null ;
             }
         }
 
         /// <summary>
         /// DES3 CBC模式解密
         /// </summary>
         /// <param name="key">密钥</param>
         /// <param name="iv">IV</param>
         /// <param name="data">密文的byte数组</param>
         /// <returns>明文的byte数组</returns>
         public  static  byte [] Des3DecodeCBC(  byte [] key,  byte [] iv,  byte [] data )
         {
             try
             {
                 // Create a new MemoryStream using the passed 
                 // array of encrypted data.
                 MemoryStream msDecrypt =  new  MemoryStream( data );
 
                 TripleDESCryptoServiceProvider tdsp =  new  TripleDESCryptoServiceProvider();
                 tdsp.Mode = CipherMode.CBC;
                 tdsp.Padding = PaddingMode.PKCS7;
 
                 // Create a CryptoStream using the MemoryStream 
                 // and the passed key and initialization vector (IV).
                 CryptoStream csDecrypt =  new  CryptoStream( msDecrypt,
                     tdsp.CreateDecryptor( key, iv ),
                     CryptoStreamMode.Read );
 
                 // Create buffer to hold the decrypted data.
                 byte [] fromEncrypt =  new  byte [data.Length];
 
                 // Read the decrypted data out of the crypto stream
                 // and place it into the temporary buffer.
                 csDecrypt.Read( fromEncrypt, 0, fromEncrypt.Length );
 
                 //Convert the buffer into a string and return it.
                 return  fromEncrypt;
             }
             catch  ( CryptographicException e )
             {
                 Console.WriteLine(  "A Cryptographic error occurred: {0}" , e.Message );
                 return  null ;
             }
         }
 
         #endregion
 
         #region ECB模式
 
         /// <summary>
         /// DES3 ECB模式加密
         /// </summary>
         /// <param name="key">密钥</param>
         /// <param name="iv">IV(当模式为ECB时,IV无用)</param>
         /// <param name="str">明文的byte数组</param>
         /// <returns>密文的byte数组</returns>
         public  static  byte [] Des3EncodeECB(  byte [] key,  byte [] iv,  byte [] data )
         {
             try
             {
                 // Create a MemoryStream.
                 MemoryStream mStream =  new  MemoryStream();
 
                 TripleDESCryptoServiceProvider tdsp =  new  TripleDESCryptoServiceProvider();
                 tdsp.Mode = CipherMode.ECB;
                 tdsp.Padding = PaddingMode.PKCS7;
                 // Create a CryptoStream using the MemoryStream 
                 // and the passed key and initialization vector (IV).
                 CryptoStream cStream =  new  CryptoStream( mStream,
                     tdsp.CreateEncryptor( key, iv ),
                     CryptoStreamMode.Write );
 
                 // Write the byte array to the crypto stream and flush it.
                 cStream.Write( data, 0, data.Length );
                 cStream.FlushFinalBlock();
 
                 // Get an array of bytes from the 
                 // MemoryStream that holds the 
                 // encrypted data.
                 byte [] ret = mStream.ToArray();
 
                 // Close the streams.
                 cStream.Close();
                 mStream.Close();
 
                 // Return the encrypted buffer.
                 return  ret;
             }
             catch  ( CryptographicException e )
             {
                 Console.WriteLine(  "A Cryptographic error occurred: {0}" , e.Message );
                 return  null ;
             }
 
         }
 
         /// <summary>
         /// DES3 ECB模式解密
         /// </summary>
         /// <param name="key">密钥</param>
         /// <param name="iv">IV(当模式为ECB时,IV无用)</param>
         /// <param name="str">密文的byte数组</param>
         /// <returns>明文的byte数组</returns>
         public  static  byte [] Des3DecodeECB(  byte [] key,  byte [] iv,  byte [] data )
         {
             try
             {
                 // Create a new MemoryStream using the passed 
                 // array of encrypted data.
                 MemoryStream msDecrypt =  new  MemoryStream( data );
 
                 TripleDESCryptoServiceProvider tdsp =  new  TripleDESCryptoServiceProvider();
                 tdsp.Mode = CipherMode.ECB;
                 tdsp.Padding = PaddingMode.PKCS7;
 
                 // Create a CryptoStream using the MemoryStream 
                 // and the passed key and initialization vector (IV).
                 CryptoStream csDecrypt =  new  CryptoStream( msDecrypt,
                     tdsp.CreateDecryptor( key, iv ),
                     CryptoStreamMode.Read );
 
                 // Create buffer to hold the decrypted data.
                 byte [] fromEncrypt =  new  byte [data.Length];
 
                 // Read the decrypted data out of the crypto stream
                 // and place it into the temporary buffer.
                 csDecrypt.Read( fromEncrypt, 0, fromEncrypt.Length );
 
                 //Convert the buffer into a string and return it.
                 return  fromEncrypt;
             }
             catch  ( CryptographicException e )
             {
                 Console.WriteLine(  "A Cryptographic error occurred: {0}" , e.Message );
                 return  null ;
             }
         }
 
         #endregion
 
         /// <summary>
         /// 类测试
         /// </summary>
         public  static  void  Test()
         {
             System.Text.Encoding utf8 = System.Text.Encoding.UTF8;
 
             //key为abcdefghijklmnopqrstuvwx的Base64编码
             byte [] key = Convert.FromBase64String(  "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4"  );
             byte [] iv =  new  byte [] { 1, 2, 3, 4, 5, 6, 7, 8 };       //当模式为ECB时,IV无用
             byte [] data = utf8.GetBytes(  "中国ABCabc123"  );
 
             System.Console.WriteLine(  "ECB模式:"  );
             byte [] str1 = Des3.Des3EncodeECB( key, iv, data );
             byte [] str2 = Des3.Des3DecodeECB( key, iv, str1 );
             System.Console.WriteLine( Convert.ToBase64String( str1 ) );
             System.Console.WriteLine( System.Text.Encoding.UTF8.GetString( str2 ) );
 
             System.Console.WriteLine();
 
             System.Console.WriteLine(  "CBC模式:"  );
             byte [] str3 = Des3.Des3EncodeCBC( key, iv, data );
             byte [] str4 = Des3.Des3DecodeCBC( key, iv, str3 );
             System.Console.WriteLine( Convert.ToBase64String( str3 ) );
             System.Console.WriteLine( utf8.GetString( str4 ) );
 
             System.Console.WriteLine();
 
         }
 
     }
 
 
接着是Java代码
 
 
import  java.security.Key;
 
import  javax.crypto.Cipher;
import  javax.crypto.SecretKeyFactory;
import  javax.crypto.spec.DESedeKeySpec;
import  javax.crypto.spec.IvParameterSpec;
 
import  sun.misc.BASE64Decoder;
import  sun.misc.BASE64Encoder;
 
public  class  Des3 {
     public  static  void  main(String[] args)  throws  Exception {
 
         byte [] key= new  BASE64Decoder().decodeBuffer( "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4" );
         byte [] keyiv = {  1 2 3 4 5 6 7 8  };
 
         byte [] data= "中国ABCabc123" .getBytes( "UTF-8" );
         
         System.out.println( "ECB加密解密" );
         byte [] str3 = des3EncodeECB(key,data );
         byte [] str4 = ees3DecodeECB(key, str3);
         System.out.println( new  BASE64Encoder().encode(str3));
         System.out.println( new  String(str4,  "UTF-8" ));
 
         System.out.println();
 
         System.out.println( "CBC加密解密" );
         byte [] str5 = des3EncodeCBC(key, keyiv, data);
         byte [] str6 = des3DecodeCBC(key, keyiv, str5);
         System.out.println( new  BASE64Encoder().encode(str5));
         System.out.println( new  String(str6,  "UTF-8" ));
 
     }
 
     /**
      * ECB加密,不要IV
      * @param key 密钥
      * @param data 明文
      * @return Base64编码的密文
      * @throws Exception
      */
     public  static  byte [] des3EncodeECB( byte [] key,  byte [] data)
             throws  Exception {
 
         Key deskey =  null ;
         DESedeKeySpec spec =  new  DESedeKeySpec(key);
         SecretKeyFactory keyfactory = SecretKeyFactory.getInstance( "desede" );
         deskey = keyfactory.generateSecret(spec);
 
         Cipher cipher = Cipher.getInstance( "desede"  "/ECB/PKCS5Padding" );
 
         cipher.init(Cipher.ENCRYPT_MODE, deskey);
         byte [] bOut = cipher.doFinal(data);
 
         return  bOut;
     }
 
     /**
      * ECB解密,不要IV
      * @param key 密钥
      * @param data Base64编码的密文
      * @return 明文
      * @throws Exception
      */
     public  static  byte [] ees3DecodeECB( byte [] key,  byte [] data)
             throws  Exception {
 
         Key deskey =  null ;
         DESedeKeySpec spec =  new  DESedeKeySpec(key);
         SecretKeyFactory keyfactory = SecretKeyFactory.getInstance( "desede" );
         deskey = keyfactory.generateSecret(spec);
 
         Cipher cipher = Cipher.getInstance( "desede"  "/ECB/PKCS5Padding" );
 
         cipher.init(Cipher.DECRYPT_MODE, deskey);
 
         byte [] bOut = cipher.doFinal(data);
 
         return  bOut;
 
     }
 
     /**
      * CBC加密
      * @param key 密钥
      * @param keyiv IV
      * @param data 明文
      * @return Base64编码的密文
      * @throws Exception
      */
     public  static  byte [] des3EncodeCBC( byte [] key,  byte [] keyiv,  byte [] data)
             throws  Exception {
 
         Key deskey =  null ;
         DESedeKeySpec spec =  new  DESedeKeySpec(key);
         SecretKeyFactory keyfactory = SecretKeyFactory.getInstance( "desede" );
         deskey = keyfactory.generateSecret(spec);
 
         Cipher cipher = Cipher.getInstance( "desede"  "/CBC/PKCS5Padding" );
         IvParameterSpec ips =  new  IvParameterSpec(keyiv);
         cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);
         byte [] bOut = cipher.doFinal(data);
 
         return  bOut;
     }
 
     /**
      * CBC解密
      * @param key 密钥
      * @param keyiv IV
      * @param data Base64编码的密文
      * @return 明文
      * @throws Exception
      */
     public  static  byte [] des3DecodeCBC( byte [] key,  byte [] keyiv,  byte [] data)
             throws  Exception {
 
         Key deskey =  null ;
         DESedeKeySpec spec =  new  DESedeKeySpec(key);
         SecretKeyFactory keyfactory = SecretKeyFactory.getInstance( "desede" );
         deskey = keyfactory.generateSecret(spec);
 
         Cipher cipher = Cipher.getInstance( "desede"  "/CBC/PKCS5Padding" );
         IvParameterSpec ips =  new  IvParameterSpec(keyiv);
 
         cipher.init(Cipher.DECRYPT_MODE, deskey, ips);
 
         byte [] bOut = cipher.doFinal(data);
 
         return  bOut;
 
     }
 
 
下面是运行结果


ECB模式:
rmWB4+r9Ug93WI0KAEuMig==
中国ABCabc123

CBC模式:
4aabWF8UFour/vNfnzJrjw==
中国ABCabc123

你可能感兴趣的:(java)