3DES加密算法


 

在日常設計及開發中,為確保數據傳輸和數據存儲的安全,可通過特定的算法,將數據明文加密成復雜的密文。目前主流加密手段大致可分為單向加密和雙向加密。

 

單向加密:通過對數據進行摘要計算生成密文,密文不可逆推還原。算法代表:Base64,MD5,SHA;

 

雙向加密:與單向加密相反,可以把密文逆推還原成明文,雙向加密又分為對稱加密和非對稱加密。

對稱加密:指數據使用者必須擁有相同的密鑰才可以進行加密解密,就像彼此約定的一串暗號。算法代表:DES,3DES,AES,IDEA,RC4,RC5;

非對稱加密:相對對稱加密而言,無需擁有同一組密鑰,非對稱加密是一種“信息公開的密鑰交換協議”。非對稱加密需要公開密鑰和私有密鑰兩組密鑰,公開密鑰和私有密鑰是配對起來的,也就是說使用公開密鑰進行數據加密,只有對應的私有密鑰才能解密。這兩個密鑰是數學相關,用某用戶密鑰加密后的密文,只能使用該用戶的加密密鑰才能解密。如果知道了其中一個,並不能計算出另外一個。因此如果公開了一對密鑰中的一個,並不會危害到另外一個密鑰性質。這里把公開的密鑰為公鑰,不公開的密鑰為私鑰。算法代表:RSA,DSA。

 

======================================================

3DES算法

3DES是三重數據加密,且可以逆推的一種算法方案。但由於3DES的算法是公開的,所以算法本身沒有密鑰可言,主要依靠唯一密鑰來確保數據加解密的安全。到目前為止,仍沒有人能破解3DES。

 

【3DES加密類】

package com.mes.util;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

@SuppressWarnings({ "restriction" })
public class ThreeDES {
    private static final String IV = "1234567-";
    public static final String KEY = "uatspdbcccgame2014061800";

    /**
     * DESCBC加密
     *
     * @param src
     *            數據源
     * @param key
     *            密鑰,長度必須是8的倍數
     * @return 返回加密后的數據
     * @throws Exception
     */
    public String encryptDESCBC(final String src, final String key) throws Exception {

        // --生成key,同時制定是des還是DESede,兩者的key長度要求不同
        final DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));
        final SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        final SecretKey secretKey = keyFactory.generateSecret(desKeySpec);

        // --加密向量
        final IvParameterSpec iv = new IvParameterSpec(IV.getBytes("UTF-8"));

        // --通過Chipher執行加密得到的是一個byte的數組,Cipher.getInstance("DES")就是采用ECB模式,cipher.init(Cipher.ENCRYPT_MODE,
        // secretKey)就可以了.
        final Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
        final byte[] b = cipher.doFinal(src.getBytes("UTF-8"));

        // --通過base64,將加密數組轉換成字符串
        final BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(b);
    }

    /**
     * DESCBC解密
     *
     * @param src
     *            數據源
     * @param key
     *            密鑰,長度必須是8的倍數
     * @return 返回解密后的原始數據
     * @throws Exception
     */
    public String decryptDESCBC(final String src, final String key) throws Exception {
        // --通過base64,將字符串轉成byte數組
        final BASE64Decoder decoder = new BASE64Decoder();
        final byte[] bytesrc = decoder.decodeBuffer(src);

        // --解密的key
        final DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));
        final SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        final SecretKey secretKey = keyFactory.generateSecret(desKeySpec);

        // --向量
        final IvParameterSpec iv = new IvParameterSpec(IV.getBytes("UTF-8"));

        // --Chipher對象解密Cipher.getInstance("DES")就是采用ECB模式,cipher.init(Cipher.DECRYPT_MODE,
        // secretKey)就可以了.
        final Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
        final byte[] retByte = cipher.doFinal(bytesrc);

        return new String(retByte);

    }

    // 3DESECB加密,key必須是長度大於等於 3*8 = 24 位哈
    public String encryptThreeDESECB(final String src, final String key) throws Exception {
        final DESedeKeySpec dks = new DESedeKeySpec(key.getBytes("UTF-8"));
        final SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
        final SecretKey securekey = keyFactory.generateSecret(dks);

        final Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, securekey);
        final byte[] b = cipher.doFinal(src.getBytes());

        final BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(b).replaceAll("\r", "").replaceAll("\n", "");

    }

    // 3DESECB解密,key必須是長度大於等於 3*8 = 24 位哈
    public String decryptThreeDESECB(final String src, final String key) throws Exception {
        // --通過base64,將字符串轉成byte數組
        final BASE64Decoder decoder = new BASE64Decoder();
        final byte[] bytesrc = decoder.decodeBuffer(src);
        // --解密的key
        final DESedeKeySpec dks = new DESedeKeySpec(key.getBytes("UTF-8"));
        final SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
        final SecretKey securekey = keyFactory.generateSecret(dks);

        // --Chipher對象解密
        final Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, securekey);
        final byte[] retByte = cipher.doFinal(bytesrc);

        return new String(retByte);
    }

}

 

【測試類】

package test;

import java.net.URLEncoder;

import com.mes.util.ThreeDES;

public class ThreeDES_TEST {
    public static void main(String[] args) throws Exception {
        final String key = "cf410f84904a44cc8a7f48fc4134e8f9";
        // 加密流程
        String telePhone = "15629551180";
        ThreeDES threeDES = new ThreeDES();
        String telePhone_encrypt = "";
        telePhone_encrypt = threeDES.encryptThreeDESECB(URLEncoder.encode(telePhone, "UTF-8"), key);
        System.out.println(telePhone_encrypt);// nWRVeJuoCrs8a+Ajn/3S8g==

        // 解密流程
        String tele_decrypt = threeDES.decryptThreeDESECB(telePhone_encrypt, key);
        System.out.println("模擬代碼解密:" + tele_decrypt);
    }

}

 

【測試結果】

Bu7KzIWrplmh4nVj0d2Htg==
模擬代碼解密:15629551180

 

附件:生產3des密鑰的方法請參考:http://www.cnblogs.com/shindo/p/5995849.html

 

注意:

3DES密鑰的長度必須是8的倍數,可取24位或32位;

加密結果的byte數組轉換為字符串,一般采用兩種方式:Base64處理或十六進制處理。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM