欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

实现文件加解密java工具类

程序员文章站 2024-03-14 14:47:04
...
package com.gblfy.ly.util;

import com.sun.crypto.provider.SunJCE;

import javax.crypto.*;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.io.*;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.util.Arrays;

/**
 * 文件加解密工具类
 * 算法:3des算法
 *
 * @author gblfy
 * @Date 2020/12/17 17:11
 */
public class DESedeUtils {

    /**
     * 3DES加密入口
     *
     * @param sFile 加密前明文文件
     * @param dFile 加密后密文文件
     * @param ivs   算法参数iv ,必须是8位
     * @param keys  3DES**key,大于等于24位
     */
    public static void encryptFile(String sFile, String dFile, String ivs, String keys) {

        // 用来安装SunJCE
        try {
            Cipher.getInstance("DESede/CBC/PKCS5Padding");
        } catch (Exception e) {

            System.err.println("Installing SunJCE provider.");
            Provider sunjce = new SunJCE();
            Security.addProvider(sunjce);
        }

        // 建立两个文件的I/O Stream
        DataInputStream sourceFile = null;
        DataOutputStream destFile = null;

        try {
            // 创建一个3DES**key
            System.out.print("reading key...");
            SecretKey key = readKey(keys);

            // 创建一个算法参数iv
            System.out.print("reading iv...");
            IvParameterSpec iv = readIv(ivs);

            // 实例化输入输出文件
            // source为明文文件,dest为密文文件
            sourceFile = new DataInputStream(new FileInputStream(sFile));
            destFile = new DataOutputStream(new FileOutputStream(dFile));

            // 调用加密方法encryptFile()
            System.out.println("File encrypting...");

            encryptFile(key, iv, sourceFile, destFile);
            System.out.println("加密完成 ok!");
        } catch (Exception e) {
            System.err.println(e);
            e.printStackTrace();
        } finally {
            try {
                sourceFile.close();
                destFile.close();
            } catch (IOException e) {
                System.err.println(e);
                e.printStackTrace();
            }

        }
    }

    /**
     * 3DES解密入口
     *
     * @param dFile 加密后密文文件
     * @param cFile 解密后明文文件
     * @param ivs   算法参数ivs,必须是8位
     * @param keys  3DES**key,大于等于24位
     * @return
     */
    public static boolean decryptFile(String dFile, String cFile, String ivs, String keys) {
        boolean tFlag = false;
        // 用来安装SunJCE
        try {
            Cipher.getInstance("DESede");
        } catch (Exception e) {

            System.err.println("Installing SunJCE provider.");
            Provider sunjce = new SunJCE();
            Security.addProvider(sunjce);
            System.out.println("File(" + dFile + ")安装SunJCE错误");
            return false;
        }
        File dsFile = new File(dFile);
        if (!dsFile.exists() || !dsFile.isFile()) {
            System.out.println("File(" + dFile + ")错误,文件不存在或者该路径不是文件。");
            return false;
        }
        // 建立两个文件的I/O Stream
        DataInputStream destFile = null;
        DataOutputStream convertFile = null;

        try {
            // 创建一个3DES**key
            System.out.print("reading key...");
            SecretKey key = readKey(keys);

            // 创建一个算法参数iv
            System.out.print("reading iv...");
            IvParameterSpec iv = readIv(ivs);

            // 实例化输入输出文件
            // dest为密文文件,convert为解密后文件
            destFile = new DataInputStream(new FileInputStream(dFile));
            convertFile = new DataOutputStream(new FileOutputStream(cFile));

            // 调用解密方法decryptFile()
            System.out.println("File(" + dFile + ") decrypting...");

            //3DES解密
            decryptFile(key, iv, destFile, convertFile);
            System.out.println("解密完成 ok!");
            tFlag = true;
        } catch (Exception e) {
            System.err.println(e);
            System.out.println("File(" + dFile + ") catch " + e);
            e.printStackTrace();
            tFlag = false;
        } finally {
            try {
                convertFile.close();
                destFile.close();
            } catch (IOException e) {
                System.err.println(e);
                System.out.println("File(" + dFile + ") finally IO异常:" + e);
                e.printStackTrace();
                tFlag = false;
            } catch (Exception e) {
                System.err.println(e);
                System.out.println("File(" + dFile + ") finally 异常:" + e);
                e.printStackTrace();
                tFlag = false;
            }

        }
        return tFlag;
    }

    /**
     * 创建一个3DES**key
     *
     * @param keys 回一个**,大于等于24位
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     * @throws InvalidKeySpecException
     */
    private static SecretKey readKey(String keys) throws NoSuchAlgorithmException, InvalidKeyException, InvalidKeySpecException {
        // String keys = "[email protected]#fis8080fis80";
        byte[] rawkey = keys.getBytes();

        // 将原字节转换为如下的一个**
        DESedeKeySpec keyspec = new DESedeKeySpec(rawkey);
        SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("DESede");
        SecretKey key = keyfactory.generateSecret(keyspec);

        return key;
    }

    /**
     * 创建一个算法参数iv
     *
     * @param ivs 算法参数:ivs,必须是8位
     * @return
     */
    private static IvParameterSpec readIv(String ivs) {
        // String ivs = "12kf#fis";
        byte[] ivBuffer = ivs.getBytes();

        IvParameterSpec iv = new IvParameterSpec(ivBuffer);
        return iv;
    }

    /**
     * 3DES加密
     * 使用指定3DES**对来自输入流的字节加密,并将其写至输出流。这个方法使用CipherOutputStream来完成加密
     *
     * @param key DES**key,大于等于24位
     * @param in
     * @param out
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     * @throws NoSuchPaddingException
     * @throws IOException
     */
    private static void encryptFile(SecretKey key, IvParameterSpec iv, InputStream in, OutputStream out)
            throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, IOException, InvalidAlgorithmParameterException {
        // 创建并初始化加密引擎
        Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, key, iv);
        // cipher.init(Cipher.ENCRYPT_MODE, key);
        // 创建一个特殊的输出流来完成这个工作
        CipherOutputStream cos = new CipherOutputStream(out, cipher);
        // 从输入流读取,并写至加密输出流
        byte[] buffer = new byte[2048];
        int bytesRead;
        while ((bytesRead = in.read(buffer)) != -1) {
            cos.write(buffer, 0, bytesRead);
        }
        cos.close();
        // 为了保证另外的安全性,不要在内存中留有任何明文
        Arrays.fill(buffer, (byte) 0);
    }


    /**
     * 3DES解密
     *
     * @param key   3DES加密key,大于等于24位
     * @param iv    算法参数 ,必须是8位
     * @param in
     * @param out
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     * @throws IOException
     * @throws IllegalBlockSizeException
     * @throws NoSuchPaddingException
     * @throws BadPaddingException
     * @throws InvalidAlgorithmParameterException
     */
    private static void decryptFile(SecretKey key, IvParameterSpec iv, InputStream in, OutputStream out)
            throws NoSuchAlgorithmException, InvalidKeyException, IOException, IllegalBlockSizeException, NoSuchPaddingException, BadPaddingException, InvalidAlgorithmParameterException {
        // 创建并初始化解密引擎
        Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, key, iv);
        // 读字节,解密,并输出
        int tBlockSize = cipher.getBlockSize();
        byte[] buffer = new byte[tBlockSize];
        int bytesRead;
        while ((bytesRead = in.read(buffer)) != -1) {
            out.write(cipher.update(buffer, 0, bytesRead));
        }
        // 把最后一组字节写出
        out.write(cipher.doFinal());
        out.flush();
    }

    public static void main(String[] args) {
        // 测试
        DESedeUtils des = new DESedeUtils();

        //明文路径(包含文件名称)
        String sFile = "D:\\222\\ods.crm_new_pol_prb.20201117.i.dat.gz";
        //生成密文路径(包含文件名称)
        String dFile = "D:\\222\\1\\ods.crm_new_pol_prb.20201117.i.dat.gz";
        //生成解密文件(包含文件名称)
        String cFile = "D:\\222\\2\\ods.crm_new_pol_prb.20201117.i.dat.gz";

        //算法参数 ivs,必须是8位
        String ivs = "gblfycom";
        //3DES**key 大于等于24位
        String keys = "[email protected]#fis8080fis80";

        //对sFile明文文件进行加密,生成加密文件dFile
        des.encryptFile(sFile, dFile, ivs, keys);
        //对dFile加密文件进行解密,生成明文文件cFile
        des.decryptFile(dFile, cFile, ivs, keys);
    }
}
相关标签: Java 加解密