原文地址:http://www.cnblogs.com/liluping860122/p/4026015.html
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#代码
01./// <summary>
02./// DES3加密解密
03./// </summary>
04.public class Des3
05.{
06. #region CBC模式**
07. /// <summary>
08. /// DES3 CBC模式加密
09. /// </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代码
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