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!!!

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