3DES加密

本文介紹了3DES加密特性,加密特色,3DES是對稱加密,用一個密鑰對內容進行加密,必須使用相同的密鑰進行解密, 密鑰必須配置,並且長度爲24位,不足24位,用0位進行補全,本文也順帶介紹了其它加密算法,最後使用java語句實現了3DES加解密php

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

實例下載算法

 

 

初識3DES數組

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

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

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

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

 

 

 

原理工具

使用 3 條 56 位的密鑰對數據進行三次加密。3DES(即 Triple DES)是 DES 向 AES 過渡的加密算法(NIST 將 3-DES 指定爲過渡的加密標準)。測試

其具體實現以下:設 Ek() 和 Dk() 表明 DES 算法的加密和解密過程,K 表明 DES 算法使用的密鑰,P 表明明文,C 表明密文,這樣:

3DES 加密過程爲:C = Ek3 ( Dk2 ( Ek1 ( P ) ) )

3DES 解密過程爲:P = Dk1 ( EK2 ( Dk3 ( C ) ) )

 

 

 

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

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

        SecretKey deskey = new SecretKeySpec(keyBytes, Algorithm);       keyBytes必須是24字節

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

        Cipher c1 = Cipher.getInstance(Algorithm);    

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

        c1.init(Cipher.ENCRYPT_MODE, deskey);    

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

        c1.doFinal(src);

 

24位解密串(必須是24位)

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

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

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

    解決方法有不少

      ①按密鑰固定長度從新定義字符串;

      ②先把字符串用Base64或者MD5加密,而後截取固定長度的字符轉成byte數組;

      ③字符串轉成Byte數組,針對該數組進行修改,若長度過長則只截取一部分,若長度不夠則補零

 

 

 

 

JAVA代碼實現

 

複製代碼

/**
 * SecretUtils {3DES加密解密的工具類 }
 * @author William
 * @date 2013-04-19
 */
public class SecretUtils {
  
    //定義加密算法,有DES、DESede(即3DES)、Blowfish
    private static final String Algorithm = "DESede";    
    private static final String PASSWORD_CRYPT_KEY = "2012PinganVitality075522628888ForShenZhenBelter075561869839";
     
     
    /**
     * 加密方法
     * @param src 源數據的字節數組
     * @return 
     */
    public static byte[] encryptMode(byte[] src) {
        try {
             SecretKey deskey = new SecretKeySpec(build3DesKey(PASSWORD_CRYPT_KEY), Algorithm);    //生成密鑰
             Cipher c1 = Cipher.getInstance(Algorithm);    //實例化負責加密/解密的Cipher工具類
             c1.init(Cipher.ENCRYPT_MODE, deskey);    //初始化爲加密模式
             return c1.doFinal(src);
         } catch (java.security.NoSuchAlgorithmException e1) {
             e1.printStackTrace();
         } catch (javax.crypto.NoSuchPaddingException e2) {
             e2.printStackTrace();
         } catch (java.lang.Exception e3) {
             e3.printStackTrace();
         }
         return null;
     }
     
     
    /**
     * 解密函數
     * @param src 密文的字節數組
     * @return
     */
    public static byte[] decryptMode(byte[] src) {      
        try {
            SecretKey deskey = new SecretKeySpec(build3DesKey(PASSWORD_CRYPT_KEY), Algorithm);
            Cipher c1 = Cipher.getInstance(Algorithm);
            c1.init(Cipher.DECRYPT_MODE, deskey);    //初始化爲解密模式
            return c1.doFinal(src);
        } catch (java.security.NoSuchAlgorithmException e1) {
            e1.printStackTrace();
        } catch (javax.crypto.NoSuchPaddingException e2) {
            e2.printStackTrace();
        } catch (java.lang.Exception e3) {
            e3.printStackTrace();
        }
        return null;
     }
     
     
    /*
     * 根據字符串生成密鑰字節數組 
     * @param keyStr 密鑰字符串
     * @return 
     * @throws UnsupportedEncodingException
     */
    public static byte[] build3DesKey(String keyStr) throws UnsupportedEncodingException{
        byte[] key = new byte[24];    //聲明一個24位的字節數組,默認裏面都是0
        byte[] temp = keyStr.getBytes("UTF-8");    //將字符串轉成字節數組
         
        /*
         * 執行數組拷貝
         * System.arraycopy(源數組,從源數組哪裏開始拷貝,目標數組,拷貝多少位)
         */
        if(key.length > temp.length){
            //若是temp不夠24位,則拷貝temp數組整個長度的內容到key數組中
            System.arraycopy(temp, 0, key, 0, temp.length);
        }else{
            //若是temp大於24位,則拷貝temp數組24個長度的內容到key數組中
            System.arraycopy(temp, 0, key, 0, key.length);
        }
        return key;
    } 
}

複製代碼

測試代碼

複製代碼

public class Main {
  
    /**
     * @param args
     */
    public static void main(String[] args) {
        String msg = "3DES加密解密案例";
        System.out.println("【加密前】:" + msg);
         
        //加密
        byte[] secretArr = SecretUtils.encryptMode(msg.getBytes());    
        System.out.println("【加密後】:" + new String(secretArr));
         
        //解密
        byte[] myMsgArr = SecretUtils.decryptMode(secretArr);  
        System.out.println("【解密後】:" + new String(myMsgArr));
    }
}

複製代碼

參考資料

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

 

 

 

【密碼學經常使用術語】

    明文:未加密的數據

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

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

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

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

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

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

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

相關文章
相關標籤/搜索