C#和Java的3DES算法

1 篇文章 0 订阅
1 篇文章 0 订阅
最近 一个项目.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#代码
C# code
 
     ///  <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代码

   
   
Java code
      
      
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
      
      
 
      
      
总结: ECB模式下,java不需要iv,.net的iv需要,但是不影响结果
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值