不過如果有人能提供其他情況, 我是可以試著去解看看.
情境: 在 .Net 中, 利用 DESCryptoServiceProvider 進行加密. 加密的 Mode 為 ECB, Padding 為 None, Zeros 與 PKCS7.
Java 用到的 import 如下:
1 2 3 4 5 | import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESKeySpec; import org.apache.commons.codec.binary.Base64; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | //建立一個Mode=ECB, Padding=None, Key為12345678的DESCryptoServiceProvider DESCryptoServiceProvider objDESCryptoServiceProvider = new DESCryptoServiceProvider(); //Key的長度要64bits -> 8bytes;用ASCII編碼將Key轉為byte[] objDESCryptoServiceProvider.Key = Encoding.ASCII.GetBytes( "12345678" ); objDESCryptoServiceProvider.Mode = CipherMode.ECB; objDESCryptoServiceProvider.Padding = PaddingMode.None; //用UTF-8編碼, 將字串轉為byte[] byte [] bysData = Encoding.UTF8.GetBytes( "我是一個PaddingMode.None的測試字串!" ); //因為PaddingMode.None的關係, byte[]的長度要是8的倍數 byte [] bysFixSizeData = new byte [( int )Math.Ceiling(bysData.Length / 8.0) * 8]; //將資料複製到長度為8的倍數的byte[] Array.Copy(bysData, bysFixSizeData, bysData.Length); //進行加密 byte [] bysEncrypted = objDESCryptoServiceProvider.CreateEncryptor() .TransformFinalBlock(bysFixSizeData, 0, bysFixSizeData.Length); //將byte[]轉為Base64的字串 Console.WriteLine(Convert.ToBase64String(bysEncrypted)); //輸出: xnygZZ+WkN4pmDVDjBJ41o9LePFibMJkfvLkf9phS9mW2tbtS6JcMSiwX2N1KbGp |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | try { //解密的Key String strKey = "12345678" ; //已加密的Base64字串 String strEncrypted = "xnygZZ+WkN4pmDVDjBJ41o9LePFibMJkfvLkf9phS9mW2tbtS6JcMSiwX2N1KbGp" ; //先將Base64字串轉碼為byte[] Base64 objBase64 = new Base64(); byte [] bysDecoded = objBase64.decode(strEncrypted.getBytes()); //建立解密所需的Key. 因為加密時的key是用ASCII轉換, 所以這邊也用ASCII做 DESKeySpec objDesKeySpec = new DESKeySpec(strKey.getBytes( "ASCII" )); SecretKeyFactory objKeyFactory = SecretKeyFactory.getInstance( "DES" ); SecretKey objSecretKey = objKeyFactory.generateSecret(objDesKeySpec); //設定一個DES/ECB/NoPadding的Cipher //ECB對應到.Net的CipherMode.ECB //NoPadding對應到.Net的PaddingMode.None Cipher objCipher = Cipher.getInstance( "DES/ECB/NoPadding" ); //設定為解密模式, 並設定解密的key objCipher.init(Cipher.DECRYPT_MODE, objSecretKey); //輸出解密後的字串. 因為加密是用UTF-8將字串轉為byte[], 所以這邊要用UTF-8轉回去 //注意後面會多一些空字元. 因為加密前有因為資料長度的關係補上一些空的bytes //這邊用String的trim()將這些空字元刪掉 String strDecrypted = new String(objCipher.doFinal(bysDecoded), "utf-8" ).trim(); System.out.println( "[" + strDecrypted + "]" ); //輸出:[我是一個PaddingMode.None的測試字串!] } catch (Exception e) { e.printStackTrace(System.out); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | //建立一個Mode=ECB, Padding=None, Key為12345678的DESCryptoServiceProvider DESCryptoServiceProvider objDESCryptoServiceProvider = new DESCryptoServiceProvider(); //Key的長度要64bits -> 8bytes objDESCryptoServiceProvider.Key = Encoding.ASCII.GetBytes( "12345678" ); objDESCryptoServiceProvider.Mode = CipherMode.ECB; objDESCryptoServiceProvider.Padding = PaddingMode.Zeros; //用UTF-8編碼, 將字串轉為byte[] //因為PaddingMode.Zeros的關係, 不用像上一個Sample一樣, 另外弄一個byte[]去將資料補到8的倍數 byte [] bysData = Encoding.UTF8.GetBytes( "我是一個PaddingMode.Zeros的測試字串!" ); //進行加密 byte [] bysEncrypted = objDESCryptoServiceProvider.CreateEncryptor() .TransformFinalBlock(bysData, 0, bysData.Length); //將byte[]轉為Base64的字串 Console.WriteLine(Convert.ToBase64String(bysEncrypted)); //輸出: xnygZZ+WkN4pmDVDjBJ41o9LePFibMJkYe6Sq5Y3mpq2JD91DLtxC/66itziI0rD |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | try { //解密的Key String strKey = "12345678" ; //已加密的Base64字串 String strEncrypted = "xnygZZ+WkN4pmDVDjBJ41o9LePFibMJkfvLkf9phS9mW2tbtS6JcMSiwX2N1KbGp" ; //先將Base64字串轉碼為byte[] Base64 objBase64 = new Base64(); byte [] bysDecoded = objBase64.decode(strEncrypted.getBytes()); //建立解密所需的Key. 因為加密時的key是用ASCII轉換, 所以這邊也用ASCII做 DESKeySpec objDesKeySpec = new DESKeySpec(strKey.getBytes( "ASCII" )); SecretKeyFactory objKeyFactory = SecretKeyFactory.getInstance( "DES" ); SecretKey objSecretKey = objKeyFactory.generateSecret(objDesKeySpec); //設定一個DES/ECB/NoPadding的Cipher //ECB對應到.Net的CipherMode.ECB //NoPadding對應到.Net的PaddingMode.None Cipher objCipher = Cipher.getInstance( "DES/ECB/NoPadding" ); //設定為解密模式, 並設定解密的key objCipher.init(Cipher.DECRYPT_MODE, objSecretKey); //輸出解密後的字串. 因為加密是用UTF-8將字串轉為byte[], 所以這邊要用UTF-8轉回去 //注意後面會多一些空字元. 因為加密前有因為資料長度的關係補上一些空的bytes //這邊用String的trim()將這些空字元刪掉 String strDecrypted = new String(objCipher.doFinal(bysDecoded), "utf-8" ).trim(); System.out.println( "[" + strDecrypted + "]" ); //輸出:[我是一個PaddingMode.None的測試字串!] } catch (Exception e) { e.printStackTrace(System.out); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | //建立一個Mode=ECB, Padding=None, Key為12345678的DESCryptoServiceProvider DESCryptoServiceProvider objDESCryptoServiceProvider = new DESCryptoServiceProvider(); //Key的長度要64bits -> 8bytes objDESCryptoServiceProvider.Key = Encoding.ASCII.GetBytes( "12345678" ); objDESCryptoServiceProvider.Mode = CipherMode.ECB; objDESCryptoServiceProvider.Padding = PaddingMode.PKCS7; //用UTF-8編碼, 將字串轉為byte[] //這邊也不用另外做補資料的動作 byte [] bysData = Encoding.UTF8.GetBytes( "我是一個PaddingMode.PKCS7的測試字串!" ); //進行加密 byte [] bysEncrypted = objDESCryptoServiceProvider.CreateEncryptor() .TransformFinalBlock(bysData, 0, bysData.Length); //將byte[]轉為Base64的字串 Console.WriteLine(Convert.ToBase64String(bysEncrypted)); //輸出: xnygZZ+WkN4pmDVDjBJ41o9LePFibMJkt86hRLUM4/m2JD91DLtxC5+8Tqc7iB2f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | try { //解密的Key String strKey = "12345678" ; //已加密的Base64字串 String strEncrypted = "xnygZZ+WkN4pmDVDjBJ41o9LePFibMJkt86hRLUM4/m2JD91DLtxC5+8Tqc7iB2f" ; //先將Base64字串轉碼為byte[] Base64 objBase64 = new Base64(); byte [] bysDecoded = objBase64.decode(strEncrypted.getBytes()); //建立解密所需的Key. 因為加密時的key是用ASCII轉換, 所以這邊也用ASCII做 DESKeySpec objDesKeySpec = new DESKeySpec(strKey.getBytes( "ASCII" )); SecretKeyFactory objKeyFactory = SecretKeyFactory.getInstance( "DES" ); SecretKey objSecretKey = objKeyFactory.generateSecret(objDesKeySpec); //設定一個DES/ECB/PKCS5Padding的Cipher //ECB對應到.Net的CipherMode.ECB //用PKCS5Padding對應到.Net的PaddingMode.PKCS7 Cipher objCipher = Cipher.getInstance( "DES/ECB/PKCS5Padding" ); //設定為解密模式, 並設定解密的key objCipher.init(Cipher.DECRYPT_MODE, objSecretKey); //輸出解密後的字串. 因為加密時指定PaddingMode.PKCS7, 所以可以不用處理空字元 //不過若想保險點, 也是可以用trim()去處理過一遍 String strDecrypted = new String(objCipher.doFinal(bysDecoded), "utf-8" ).trim(); System.out.println( "[" + strDecrypted + "]" ); //輸出:[我是一個PaddingMode.PKCS7的測試字串!] } catch (Exception e) { e.printStackTrace(System.out); } |
也許以後有用到其他的, 就再補上.
沒有留言:
張貼留言