JAVA和C# 3DES加密解密

时间:2023-03-09 19:24:10
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, , 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, , 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, , 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, , 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[] { , , , , , , , }; //当模式为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代码

01.import java.security.Key;
02.import javax.crypto.Cipher;
03.import javax.crypto.SecretKeyFactory;
04.import javax.crypto.spec.DESedeKeySpec;
05.import javax.crypto.spec.IvParameterSpec;
06.import sun.misc.BASE64Decoder;
07.import sun.misc.BASE64Encoder;
08.public class Des3 {
09. 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. }

下面是运行结果

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

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

文章来自:http://blog.****.net/sdfkfkd/article/details/6004847  感谢作者的分享。