JAVA和C# 3DES加密解密

李路平發表於2014-10-15

最近 一個專案.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

 

文章來自:http://blog.csdn.net/sdfkfkd/article/details/6004847  感謝作者的分享。

相關文章