Android: JAVA和C# 3DES加密解密

发布于 2022-10-15 05:25:33 字数 28844 浏览 16 评论 0

转:neil-zhao

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#代码

  1.   /// <summary>
  2.     /// DES3加密解密
  3.     /// </summary>
  4.     public class Des3
  5.     {
  6.         #region CBC模式**
  7.         /// <summary>
  8.         /// DES3 CBC模式加密
  9.         /// </summary>
  10.         /// <param name="key">密钥</param>
  11.         /// <param name="iv">IV</param>
  12.         /// <param name="data">明文的byte数组</param>
  13.         /// <returns>密文的byte数组</returns>
  14.         public static byte[] Des3EncodeCBC( byte[] key, byte[] iv, byte[] data )
  15.         {
  16.             //复制于MSDN
  17.             try
  18.             {
  19.                 // Create a MemoryStream.
  20.                 MemoryStream mStream = new MemoryStream();
  21.                 TripleDESCryptoServiceProvider tdsp = new TripleDESCryptoServiceProvider();
  22.                 tdsp.Mode = CipherMode.CBC;             //默认值
  23.                 tdsp.Padding = PaddingMode.PKCS7;       //默认值
  24.                 // Create a CryptoStream using the MemoryStream
  25.                 // and the passed key and initialization vector (IV).
  26.                 CryptoStream cStream = new CryptoStream( mStream,
  27.                     tdsp.CreateEncryptor( key, iv ),
  28.                     CryptoStreamMode.Write );
  29.                 // Write the byte array to the crypto stream and flush it.
  30.                 cStream.Write( data, 0, data.Length );
  31.                 cStream.FlushFinalBlock();
  32.                 // Get an array of bytes from the
  33.                 // MemoryStream that holds the
  34.                 // encrypted data.
  35.                 byte[] ret = mStream.ToArray();
  36.                 // Close the streams.
  37.                 cStream.Close();
  38.                 mStream.Close();
  39.                 // Return the encrypted buffer.
  40.                 return ret;
  41.             }
  42.             catch ( CryptographicException e )
  43.             {
  44.                 Console.WriteLine( "A Cryptographic error occurred: {0}", e.Message );
  45.                 return null;
  46.             }
  47.         }
  48.         /// <summary>
  49.         /// DES3 CBC模式解密
  50.         /// </summary>
  51.         /// <param name="key">密钥</param>
  52.         /// <param name="iv">IV</param>
  53.         /// <param name="data">密文的byte数组</param>
  54.         /// <returns>明文的byte数组</returns>
  55.         public static byte[] Des3DecodeCBC( byte[] key, byte[] iv, byte[] data )
  56.         {
  57.             try
  58.             {
  59.                 // Create a new MemoryStream using the passed
  60.                 // array of encrypted data.
  61.                 MemoryStream msDecrypt = new MemoryStream( data );
  62.                 TripleDESCryptoServiceProvider tdsp = new TripleDESCryptoServiceProvider();
  63.                 tdsp.Mode = CipherMode.CBC;
  64.                 tdsp.Padding = PaddingMode.PKCS7;
  65.                 // Create a CryptoStream using the MemoryStream
  66.                 // and the passed key and initialization vector (IV).
  67.                 CryptoStream csDecrypt = new CryptoStream( msDecrypt,
  68.                     tdsp.CreateDecryptor( key, iv ),
  69.                     CryptoStreamMode.Read );
  70.                 // Create buffer to hold the decrypted data.
  71.                 byte[] fromEncrypt = new byte[data.Length];
  72.                 // Read the decrypted data out of the crypto stream
  73.                 // and place it into the temporary buffer.
  74.                 csDecrypt.Read( fromEncrypt, 0, fromEncrypt.Length );
  75.                 //Convert the buffer into a string and return it.
  76.                 return fromEncrypt;
  77.             }
  78.             catch ( CryptographicException e )
  79.             {
  80.                 Console.WriteLine( "A Cryptographic error occurred: {0}", e.Message );
  81.                 return null;
  82.             }
  83.         }
  84.         #endregion
  85.         #region ECB模式
  86.         /// <summary>
  87.         /// DES3 ECB模式加密
  88.         /// </summary>
  89.         /// <param name="key">密钥</param>
  90.         /// <param name="iv">IV(当模式为ECB时,IV无用)</param>
  91.         /// <param name="str">明文的byte数组</param>
  92.         /// <returns>密文的byte数组</returns>
  93.         public static byte[] Des3EncodeECB( byte[] key, byte[] iv, byte[] data )
  94.         {
  95.             try
  96.             {
  97.                 // Create a MemoryStream.
  98.                 MemoryStream mStream = new MemoryStream();
  99.                 TripleDESCryptoServiceProvider tdsp = new TripleDESCryptoServiceProvider();
  100.                 tdsp.Mode = CipherMode.ECB;
  101.                 tdsp.Padding = PaddingMode.PKCS7;
  102.                 // Create a CryptoStream using the MemoryStream
  103.                 // and the passed key and initialization vector (IV).
  104.                 CryptoStream cStream = new CryptoStream( mStream,
  105.                     tdsp.CreateEncryptor( key, iv ),
  106.                     CryptoStreamMode.Write );
  107.                 // Write the byte array to the crypto stream and flush it.
  108.                 cStream.Write( data, 0, data.Length );
  109.                 cStream.FlushFinalBlock();
  110.                 // Get an array of bytes from the
  111.                 // MemoryStream that holds the
  112.                 // encrypted data.
  113.                 byte[] ret = mStream.ToArray();
  114.                 // Close the streams.
  115.                 cStream.Close();
  116.                 mStream.Close();
  117.                 // Return the encrypted buffer.
  118.                 return ret;
  119.             }
  120.             catch ( CryptographicException e )
  121.             {
  122.                 Console.WriteLine( "A Cryptographic error occurred: {0}", e.Message );
  123.                 return null;
  124.             }
  125.         }
  126.         /// <summary>
  127.         /// DES3 ECB模式解密
  128.         /// </summary>
  129.         /// <param name="key">密钥</param>
  130.         /// <param name="iv">IV(当模式为ECB时,IV无用)</param>
  131.         /// <param name="str">密文的byte数组</param>
  132.         /// <returns>明文的byte数组</returns>
  133.         public static byte[] Des3DecodeECB( byte[] key, byte[] iv, byte[] data )
  134.         {
  135.             try
  136.             {
  137.                 // Create a new MemoryStream using the passed
  138.                 // array of encrypted data.
  139.                 MemoryStream msDecrypt = new MemoryStream( data );
  140.                 TripleDESCryptoServiceProvider tdsp = new TripleDESCryptoServiceProvider();
  141.                 tdsp.Mode = CipherMode.ECB;
  142.                 tdsp.Padding = PaddingMode.PKCS7;
  143.                 // Create a CryptoStream using the MemoryStream
  144.                 // and the passed key and initialization vector (IV).
  145.                 CryptoStream csDecrypt = new CryptoStream( msDecrypt,
  146.                     tdsp.CreateDecryptor( key, iv ),
  147.                     CryptoStreamMode.Read );
  148.                 // Create buffer to hold the decrypted data.
  149.                 byte[] fromEncrypt = new byte[data.Length];
  150.                 // Read the decrypted data out of the crypto stream
  151.                 // and place it into the temporary buffer.
  152.                 csDecrypt.Read( fromEncrypt, 0, fromEncrypt.Length );
  153.                 //Convert the buffer into a string and return it.
  154.                 return fromEncrypt;
  155.             }
  156.             catch ( CryptographicException e )
  157.             {
  158.                 Console.WriteLine( "A Cryptographic error occurred: {0}", e.Message );
  159.                 return null;
  160.             }
  161.         }
  162.         #endregion
  163.         /// <summary>
  164.         /// 类测试
  165.         /// </summary>
  166.         public static void Test()
  167.         {
  168.             System.Text.Encoding utf8 = System.Text.Encoding.UTF8;
  169.             //key为abcdefghijklmnopqrstuvwx的Base64编码
  170.             byte[] key = Convert.FromBase64String( "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4" );
  171.             byte[] iv = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };      //当模式为ECB时,IV无用
  172.             byte[] data = utf8.GetBytes( "中国ABCabc123" );
  173.             System.Console.WriteLine( "ECB模式:" );
  174.             byte[] str1 = Des3.Des3EncodeECB( key, iv, data );
  175.             byte[] str2 = Des3.Des3DecodeECB( key, iv, str1 );
  176.             System.Console.WriteLine( Convert.ToBase64String( str1 ) );
  177.             System.Console.WriteLine( System.Text.Encoding.UTF8.GetString( str2 ) );
  178.             System.Console.WriteLine();
  179.             System.Console.WriteLine( "CBC模式:" );
  180.             byte[] str3 = Des3.Des3EncodeCBC( key, iv, data );
  181.             byte[] str4 = Des3.Des3DecodeCBC( key, iv, str3 );
  182.             System.Console.WriteLine( Convert.ToBase64String( str3 ) );
  183.             System.Console.WriteLine( utf8.GetString( str4 ) );
  184.             System.Console.WriteLine();
  185.         }
  186.     }

复制代码接着是Java代码

  1. import java.security.Key;
  2. import javax.crypto.Cipher;
  3. import javax.crypto.SecretKeyFactory;
  4. import javax.crypto.spec.DESedeKeySpec;
  5. import javax.crypto.spec.IvParameterSpec;
  6. import sun.misc.BASE64Decoder;
  7. import sun.misc.BASE64Encoder;
  8. public class Des3 {
  9.     public static void main(String[] args) throws Exception {
  10.         byte[] key=new BASE64Decoder().decodeBuffer("YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4");
  11.         byte[] keyiv = { 1, 2, 3, 4, 5, 6, 7, 8 };
  12.         byte[] data="中国ABCabc123".getBytes("UTF-8");
  13.         
  14.         System.out.println("ECB加密解密");
  15.         byte[] str3 = des3EncodeECB(key,data );
  16.         byte[] str4 = ees3DecodeECB(key, str3);
  17.         System.out.println(new BASE64Encoder().encode(str3));
  18.         System.out.println(new String(str4, "UTF-8"));
  19.         System.out.println();
  20.         System.out.println("CBC加密解密");
  21.         byte[] str5 = des3EncodeCBC(key, keyiv, data);
  22.         byte[] str6 = des3DecodeCBC(key, keyiv, str5);
  23.         System.out.println(new BASE64Encoder().encode(str5));
  24.         System.out.println(new String(str6, "UTF-8"));
  25.     }
  26.     /**
  27.      * ECB加密,不要IV
  28.      * @param key 密钥
  29.      * @param data 明文
  30.      * @return Base64编码的密文
  31.      * @throws Exception
  32.      */
  33.     public static byte[] des3EncodeECB(byte[] key, byte[] data)
  34.             throws Exception {
  35.         Key deskey = null;
  36.         DESedeKeySpec spec = new DESedeKeySpec(key);
  37.         SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
  38.         deskey = keyfactory.generateSecret(spec);
  39.         Cipher cipher = Cipher.getInstance("desede" + "/ECB/PKCS5Padding");
  40.         cipher.init(Cipher.ENCRYPT_MODE, deskey);
  41.         byte[] bOut = cipher.doFinal(data);
  42.         return bOut;
  43.     }
  44.     /**
  45.      * ECB解密,不要IV
  46.      * @param key 密钥
  47.      * @param data Base64编码的密文
  48.      * @return 明文
  49.      * @throws Exception
  50.      */
  51.     public static byte[] ees3DecodeECB(byte[] key, byte[] data)
  52.             throws Exception {
  53.         Key deskey = null;
  54.         DESedeKeySpec spec = new DESedeKeySpec(key);
  55.         SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
  56.         deskey = keyfactory.generateSecret(spec);
  57.         Cipher cipher = Cipher.getInstance("desede" + "/ECB/PKCS5Padding");
  58.         cipher.init(Cipher.DECRYPT_MODE, deskey);
  59.         byte[] bOut = cipher.doFinal(data);
  60.         return bOut;
  61.     }
  62.     /**
  63.      * CBC加密
  64.      * @param key 密钥
  65.      * @param keyiv IV
  66.      * @param data 明文
  67.      * @return Base64编码的密文
  68.      * @throws Exception
  69.      */
  70.     public static byte[] des3EncodeCBC(byte[] key, byte[] keyiv, byte[] data)
  71.             throws Exception {
  72.         Key deskey = null;
  73.         DESedeKeySpec spec = new DESedeKeySpec(key);
  74.         SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
  75.         deskey = keyfactory.generateSecret(spec);
  76.         Cipher cipher = Cipher.getInstance("desede" + "/CBC/PKCS5Padding");
  77.         IvParameterSpec ips = new IvParameterSpec(keyiv);
  78.         cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);
  79.         byte[] bOut = cipher.doFinal(data);
  80.         return bOut;
  81.     }
  82.     /**
  83.      * CBC解密
  84.      * @param key 密钥
  85.      * @param keyiv IV
  86.      * @param data Base64编码的密文
  87.      * @return 明文
  88.      * @throws Exception
  89.      */
  90.     public static byte[] des3DecodeCBC(byte[] key, byte[] keyiv, byte[] data)
  91.             throws Exception {
  92.         Key deskey = null;
  93.         DESedeKeySpec spec = new DESedeKeySpec(key);
  94.         SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
  95.         deskey = keyfactory.generateSecret(spec);
  96.         Cipher cipher = Cipher.getInstance("desede" + "/CBC/PKCS5Padding");
  97.         IvParameterSpec ips = new IvParameterSpec(keyiv);
  98.         cipher.init(Cipher.DECRYPT_MODE, deskey, ips);
  99.         byte[] bOut = cipher.doFinal(data);
  100.         return bOut;
  101.     }
  102. }

复制代码下面是运行结果

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

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

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

代码如下:

  1.     public static void main(String[] args) throws Exception {
  2.         byte[] key=Base64.decode("YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4".getBytes(),Base64.DEFAULT);
  3.         byte[] keyiv = { 1, 2, 3, 4, 5, 6, 7, 8 };
  4.         byte[] data="中国ABCabc123".getBytes("UTF-8");
  5.         
  6.         System.out.println("ECB加密解密");
  7.         byte[] str3 = des3EncodeECB(key,data );
  8.         byte[] str4 = ees3DecodeECB(key, str3);
  9.         System.out.println(new String(Base64.encode(str3,  Base64.DEFAULT),"UTF-8"));
  10.         System.out.println(new String(str4, "UTF-8"));
  11.         System.out.println();
  12.         System.out.println("CBC加密解密");
  13.         byte[] str5 = des3EncodeCBC(key, keyiv, data);
  14.         byte[] str6 = des3DecodeCBC(key, keyiv, str5);
  15.         System.out.println(new String(Base64.encode(str5,  Base64.DEFAULT),"UTF-8"));
  16.         System.out.println(new String(str6, "UTF-8"));
  17.     }

复制代码

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文