Android: 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

 

另外,android下要使用3DES可考虑将BASE64Encoder替换成Base64

代码如下:

 

     public   static   void  main(String[] args)  throws  Exception {

        
byte [] key = Base64.decode( " YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4 " .getBytes(),Base64.DEFAULT);
        
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  String(Base64.encode(str3,  Base64.DEFAULT), " UTF-8 " ));
        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  String(Base64.encode(str5,  Base64.DEFAULT), " UTF-8 " ));
        System.out.println(
new  String(str6,  " UTF-8 " ));
    }

 


 

你可能感兴趣的:(android)