JAVA基礎◆淺談3DES加密解密

JAVA基礎◆淺談3DES加密解密

淺談3DES加密解密 php

 

(注:本文不深刻探討3DES的加密原理,只着重說明在Java中使用3DES加密解密以及常見問題) html

 

 

 

從數據安全談起 java


 

    當你使用網銀時,是否擔憂你的銀行卡會被盜用? 算法

    當你和朋友用QQ進行聊天時,是否擔憂你的隱私會被泄露? 數組

    做爲開發者,編寫安全的代碼比編寫優雅的代碼更重要,由於安全是一切應用之根本!爲了確保數據不被侵犯,數據加密/解密技術運用而生。    ——摘錄自《Java加密解密的藝術》 安全

 

    因此爲了確保數據傳輸和數據存儲的安全,咱們能夠經過特定的算法,將數據明文加密成複雜的密文。 併發

    衆多的加密手段大體能夠分爲單項加密和雙向加密。單項加密指經過對數據進行摘要計算生成密文,密文不可逆推還原,好比有Base6四、MD五、SHA等;雙向加密則相反,指能夠把密文逆推還原成明文,其中雙向加密又分爲對稱加密和非對稱加密。對稱加密是指數據使用者必須擁有一樣的密鑰才能夠進行加密解密,就像你們共同約定了一組暗號同樣,對稱加密的手段有DES、3DES、AES、IDEA、RC四、RC5等;而非對稱加密相對於對稱加密而言,無需擁有同一組密鑰,它是一種「信息公開的密鑰交換協議」。非對稱加密須要公開密鑰和私有密鑰兩組密鑰,公開密鑰和私有密鑰是配對起來的,也就是說使用公開密鑰進行數據加密,只有對應的私有密鑰才能進行解密。此類的加密手段有RSA、DSA等。 函數

                                                                                            

【密碼學經常使用術語】 工具

    明文:未加密的數據 測試

    密文:明文通過加密後的數據

    加密:將明文轉換爲密文的過程

    解密:將密文轉換爲明文的過程    

    加密算法:將明文轉換爲密文的轉換算法        

    解密算法:將密文轉換爲明文的轉換算法

    加密密鑰:用於加密算法進行加密操做的密鑰

    解密密鑰:用於解密算法進行解密操做的密鑰

    

 

 

初識3DES


    3DES,也稱爲3DESede或TripleDES,是三重數據加密,且能夠逆推的一種算法方案。

    1975年美國IBM公司成功研究併發布了DES加密算法,但DES密碼長度容易被暴力破解,經過對DES算法進行改進,針對每一個數據塊進行三次DES加密,也就是3DES加密算法。

    但因爲3DES的算法是公開的,因此算法自己沒什麼祕密可言,主要依靠惟一密鑰來確保數據加密解密的安全。

    有人可能會問,那3DES到底安不安全呢?!目前爲止,尚未人能破解3DES,因此你要是能破解它,都足以震驚整個信息安全界了……

 

【Java使用3DES加密解密的流程】

    ①傳入共同約定的密鑰(keyBytes)以及算法(Algorithm),來構建SecretKey密鑰對象

        SecretKey deskey = new SecretKeySpec(keyBytesAlgorithm);    

    ②根據算法實例化Cipher對象。它負責加密/解密

        Cipher c1 = Cipher.getInstance(Algorithm);    

    ③傳入加密/解密模式以及SecretKey密鑰對象,實例化Cipher對象

        c1.init(Cipher.ENCRYPT_MODE, deskey);    

    ④傳入字節數組,調用Cipher.doFinal()方法,實現加密/解密,並返回一個byte字節數組

        c1.doFinal(src);

 

 

 

3DES案例


 

—SecretUtils.java(3DES加密解密的工具類)—

複製代碼

 1 package my3des; 
2   3 import java.io.UnsupportedEncodingException; 4   5 import javax.crypto.Cipher; 6 import javax.crypto.SecretKey; 7 import javax.crypto.spec.SecretKeySpec; 8   9  10 /**11  * SecretUtils {3DES加密解密的工具類 }12  * @author William13  * @date 2013-04-1914  */15 public class SecretUtils {16  17     //定義加密算法,有DES、DESede(即3DES)、Blowfish18     private static final String Algorithm = "DESede";    
19     private static final String PASSWORD_CRYPT_KEY = "2012PinganVitality075522628888ForShenZhenBelter075561869839";20     21     22     /**23      * 加密方法24      * @param src 源數據的字節數組25      * @return 26      */27     public static byte[] encryptMode(byte[] src) {28         try {29              SecretKey deskey = new SecretKeySpec(build3DesKey(PASSWORD_CRYPT_KEY), Algorithm);    //生成密鑰30              Cipher c1 = Cipher.getInstance(Algorithm);    //實例化負責加密/解密的Cipher工具類31              c1.init(Cipher.ENCRYPT_MODE, deskey);    //初始化爲加密模式32              return c1.doFinal(src);33          } catch (java.security.NoSuchAlgorithmException e1) {34              e1.printStackTrace();35          } catch (javax.crypto.NoSuchPaddingException e2) {36              e2.printStackTrace();37          } catch (java.lang.Exception e3) {38              e3.printStackTrace();39          }40          return null;41      }42     43     44     /**45      * 解密函數46      * @param src 密文的字節數組47      * @return48      */49     public static byte[] decryptMode(byte[] src) {      
50         try {51             SecretKey deskey = new SecretKeySpec(build3DesKey(PASSWORD_CRYPT_KEY), Algorithm);52             Cipher c1 = Cipher.getInstance(Algorithm);53             c1.init(Cipher.DECRYPT_MODE, deskey);    //初始化爲解密模式54             return c1.doFinal(src);55         } catch (java.security.NoSuchAlgorithmException e1) {56             e1.printStackTrace();57         } catch (javax.crypto.NoSuchPaddingException e2) {58             e2.printStackTrace();59         } catch (java.lang.Exception e3) {60             e3.printStackTrace();61         }62         return null;63      }64     65     66     /*67      * 根據字符串生成密鑰字節數組 
68      * @param keyStr 密鑰字符串69      * @return 
70      * @throws UnsupportedEncodingException71      */72     public static byte[] build3DesKey(String keyStr) throws UnsupportedEncodingException{73         byte[] key = new byte[24];    //聲明一個24位的字節數組,默認裏面都是074         byte[] temp = keyStr.getBytes("UTF-8");    //將字符串轉成字節數組75         76         /*77          * 執行數組拷貝78          * System.arraycopy(源數組,從源數組哪裏開始拷貝,目標數組,拷貝多少位)79          */80         if(key.length > temp.length){81             //若是temp不夠24位,則拷貝temp數組整個長度的內容到key數組中82             System.arraycopy(temp, 0, key, 0, temp.length);83         }else{84             //若是temp大於24位,則拷貝temp數組24個長度的內容到key數組中85             System.arraycopy(temp, 0, key, 0, key.length);86         }87         return key;88     } 
89 }

複製代碼

 

—Main.java(測試類)—

複製代碼

 1 package my3des; 2   3 public class Main { 4   5     /** 6      * @param args 7      */ 8     public static void main(String[] args) { 9         String msg = "3DES加密解密案例";10         System.out.println("【加密前】:" + msg);11         12         //加密13         byte[] secretArr = SecretUtils.encryptMode(msg.getBytes());    
14         System.out.println("【加密後】:" + new String(secretArr));15         16         //解密17         byte[] myMsgArr = SecretUtils.decryptMode(secretArr);  
18         System.out.println("【解密後】:" + new String(myMsgArr));19     }20 }

複製代碼

 

 

 

補充說明


· 3DES的密鑰必須是24位的byte數組

    隨便拿一個String.getBytes()是不行的,會報以下錯誤

        java.security.InvalidKeyException: Invalid key length: 59 bytes

    解決方法有不少,①按密鑰固定長度從新定義字符串;②先把字符串用Base64或者MD5加密,而後截取固定長度的字符轉成byte數組;③字符串轉成Byte數組,針對該數組進行修改,若長度過長則只截取一部分,若長度不夠則補零

 

· 加密結果的編碼方式要一致

    從byte數組轉成字符串,通常有兩種方式,base64處理和十六進制處理。

    

· 參考資料

    3DES在線測試工具:http://www.seacha.com/tools/3des.php

 

http://www.cnblogs.com/lianghuilin/archive/2013/04/15/3DES.html

相關文章
相關標籤/搜索