DES加密+CBC模式+Base64防丟失防亂碼

一、 DesCbcComponent

import javax.crypto.*;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

/**
 * @author kesa
 */
public class DesCbcComponent {

    private SecretKey key;

    public SecretKey getKey() {
        return key;
    }

    public DesCbcComponent(String key) {
        setKey(key);
    }

    /**
     * 設置密鑰:長度64位,8字節
     *
     * @param key 用戶輸入:如果超過8字節,則丟棄多餘的字節;少於8字節則補0;
     */
    private void setKey(String key) {
        byte[] bytes = new byte[8];
        byte[] userInput = key.getBytes();
        for (int i = 0;i<8 && i < userInput.length; i++) {
            bytes[i] = userInput[i];
        }
        try {
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            DESKeySpec keySpec = new DESKeySpec(bytes);
            this.key = keyFactory.generateSecret(keySpec);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * DES 加密
     */
    public String enCrypt(String plainText) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, InvalidAlgorithmParameterException {
        Cipher desCipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
        final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
        desCipher.init(Cipher.ENCRYPT_MODE, this.key,iv);
        byte[] bytes = desCipher.doFinal(plainText.getBytes());
        return encodeTo64(bytes);
    }

    /**
     * DES解密
     */
    public String deCrypt(String base64Str) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, InvalidAlgorithmParameterException {
        byte[] cipherText = decodeFrom64(base64Str);
        Cipher desCipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
        final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
        desCipher.init(Cipher.DECRYPT_MODE, this.key,iv);
        byte[] textDecrypted = desCipher.doFinal(cipherText);
        return new String(textDecrypted);
    }

    /**
     * base64碼錶6個bit位對應一個字符;碼錶中沒用等號(“=”);
     * 3個字節 會轉換位4個base64字符 不足的用等號(“=”)填充;
     * 字節數不是3的倍數,即byte位不是6的倍數是,byte位用0補齊成6的倍數;
     *
     * 如果 轉換後末尾有一個等號(“=”),則說明原字節數組後面補了兩個0
     * 如果 轉換後末尾有兩個等號(“==”),則說明原字節數組後面補了四個0
     *
     * @param src GBK碼錶可能無法正常映射的字節數組
     * @return Base64能夠解析的字節數組
     */
    private static String encodeTo64(byte[] src){
        Base64.Encoder encoder = Base64.getEncoder();
        return new String(encoder.encode(src));
    }

    /**
     * @param from 字符串:長度必須是4的倍數,否則會拋運行時異常
     * @return 對應GBK的字節數組
     */
    private static byte[] decodeFrom64(String from){
        Base64.Decoder decoder = Base64.getDecoder();
        return decoder.decode(from);
    }
}

二、DesCbcComponentTest

/**
 * @author kesa
 */
public class DesCbcComponentTest {

    public static void main(String[] args) throws IllegalBlockSizeException, InvalidKeyException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException {
        DesCbcComponent desComponent = new DesCbcComponent("kesa");
        
        String plainText="don't stop!!!";
        String base64Cipher = desComponent.enCrypt(plainText);
        System.out.println("base64密文 : "+base64Cipher);

        String plainText2 = desComponent.deCrypt(base64Cipher);
        System.out.println("GBK原文 : " + plainText2);
    }
}
--------------------------------------------------------------------------------------------------------
console:

base64密文 : b6I8AlbDPeEA3ZFdx/4kdw==
GBK原文 : don't stop!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章