1. 程式人生 > >DES 加解密

DES 加解密

一、DES加解密工具類

package com.hans.common.util;

import java.io.*;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.util.Objects;

import javax.crypto.*;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;

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


public class DES {

    public static final String KEY = "ydiqfkea";

    /**
     * 加密函式
     *
     * @param data
     * 加密資料
     * @param key
     * 金鑰
     * @return 返回加密後的資料
     */
    public static byte[] encrypt(byte[] data, byte[] key) {
        try {
            // DES演算法要求有一個可信任的隨機數源
            SecureRandom sr = new SecureRandom();
            // 從原始金鑰資料建立DESKeySpec物件
            DESKeySpec dks = new DESKeySpec(key);
            // 建立一個密匙工廠,然後用它把DESKeySpec轉換成
            // 一個SecretKey物件
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            SecretKey secretKey = keyFactory.generateSecret(dks);
            // using DES in ECB mode
            Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
            // 用密匙初始化Cipher物件
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, sr);
            // 執行加密操作
            return cipher.doFinal(data);
        } catch (Exception e) {
            System.err.println("DES演算法,加密資料出錯!");
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 解密函式
     *
     * @param data
     * 解密資料
     * @param key
     * 金鑰
     * @return 返回解密後的資料
     */
    public static byte[] decrypt(byte[] data, byte[] key) {
        try {
// DES演算法要求有一個可信任的隨機數源
            SecureRandom sr = new SecureRandom();
// byte rawKeyData[] = /* 用某種方法獲取原始密匙資料 */;
// 從原始密匙資料建立一個DESKeySpec物件
            DESKeySpec dks = new DESKeySpec(key);
// 建立一個密匙工廠,然後用它把DESKeySpec物件轉換成
// 一個SecretKey物件
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            SecretKey secretKey = keyFactory.generateSecret(dks);
// using DES in ECB mode
            Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
// 用密匙初始化Cipher物件
            cipher.init(Cipher.DECRYPT_MODE, secretKey, sr);
// 正式執行解密操作
            return cipher.doFinal(data);
        } catch (Exception e) {
            System.err.println("DES演算法,解密出錯。");
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 加密函式
     *
     * @param data
     * 加密資料
     * @param key
     * 金鑰
     * @return 返回加密後的資料
     */
    public static byte[] CBCEncrypt(byte[] data, byte[] key, byte[] iv) {
        try {
// 從原始金鑰資料建立DESKeySpec物件
            DESKeySpec dks = new DESKeySpec(key);
// 建立一個密匙工廠,然後用它把DESKeySpec轉換成
// 一個SecretKey物件
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            SecretKey secretKey = keyFactory.generateSecret(dks);
// Cipher物件實際完成加密操作
            Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
// 若採用NoPadding模式,data長度必須是8的倍數
// Cipher cipher = Cipher.getInstance("DES/CBC/NoPadding");
// 用密匙初始化Cipher物件
            IvParameterSpec param = new IvParameterSpec(iv);
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, param);
// 執行加密操作
            return cipher.doFinal(data);
        } catch (Exception e) {
            System.err.println("DES演算法,加密資料出錯!");
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 解密函式
     *
     * @param data
     * 解密資料
     * @param key
     * 金鑰
     * @return 返回解密後的資料
     */
    public static byte[] CBCDecrypt(byte[] data, byte[] key, byte[] iv) {
        try {
// 從原始密匙資料建立一個DESKeySpec物件
            DESKeySpec dks = new DESKeySpec(key);
// 建立一個密匙工廠,然後用它把DESKeySpec物件轉換成
// 一個SecretKey物件
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            SecretKey secretKey = keyFactory.generateSecret(dks);
// using DES in CBC mode
            Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
// 若採用NoPadding模式,data長度必須是8的倍數
// Cipher cipher = Cipher.getInstance("DES/CBC/NoPadding");
// 用密匙初始化Cipher物件
            IvParameterSpec param = new IvParameterSpec(iv);
            cipher.init(Cipher.DECRYPT_MODE, secretKey, param);
// 正式執行解密操作
            return cipher.doFinal(data);
        } catch (Exception e) {
            System.err.println("DES演算法,解密出錯。");
            e.printStackTrace();
        }
        return null;
    }
    /**
     * sn 解密
     * @return
     */
    public static String decrypt(String sn,String key){
        String result = "";
        try {
            BASE64Decoder base64De = new BASE64Decoder();
            byte[] b = null;
            sn=sn.replaceAll("-", "/").replaceAll("_", "+");
            if("..".equals(sn.substring(sn.length() - 2, sn.length()))){
                sn = sn.substring(0, sn.length()-2) +"==";
            }else if(".".equals(sn.substring(sn.length() - 1, sn.length()))){
                sn = sn.substring(0, sn.length()-1) +"=";
            }
            b = base64De.decodeBuffer(sn);
            result = new String(Objects.requireNonNull(DES.decrypt(b, key.getBytes())));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }



	// 根據密碼解密檔案。
	public static void decryptFile(String file, String newFile, String key) {
		// DES演算法要求有一個可信任的隨機數源
		SecureRandom sr = new SecureRandom();
		// byte rawKeyData[] = /* 用某種方法獲取原始密匙資料 */;
		// 從原始密匙資料建立一個DESKeySpec物件
		DESKeySpec dks = null;
		InputStream in = null;
		CipherOutputStream cout = null;
		OutputStream out = null;
		try {
			dks = new DESKeySpec(key.getBytes("utf8"));
			// 建立一個密匙工廠,然後用它把DESKeySpec物件轉換成
			// 一個SecretKey物件
			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
			SecretKey secretKey = keyFactory.generateSecret(dks);
			// using DES in ECB mode
			Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
			// 用密匙初始化Cipher物件
			cipher.init(Cipher.DECRYPT_MODE, secretKey, sr);

			in = new FileInputStream(file);
			out = new FileOutputStream(newFile);
			cout = new CipherOutputStream(out, cipher);
			byte[] buffer = new byte[1024];
			int count = 0;
			while ((count = in.read(buffer)) > 0) {
				cout.write(buffer, 0, count);
			}
		} catch (InvalidKeyException | NoSuchAlgorithmException | InvalidKeySpecException | NoSuchPaddingException | IOException e) {
			e.printStackTrace();
		} finally {
			try {
				cout.close();
				out.close();
				in.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

	}


    /**
     *
     * @param bytes byte陣列
     * @return 字串
     */
	public static String getEncryptStr(byte[] bytes){
        BASE64Encoder base64Encoder = new BASE64Encoder();
        String encoderStr = base64Encoder.encode(Objects.requireNonNull(bytes));
        return encoderStr.replaceAll("/", "-").replaceAll("\\+", "_");
    }
}