Cipher + hutool 附件加密存储

本文介绍了一种使用Java实现的文件加解密方法,利用hutool工具包和javax.crypto包进行文件流操作,实现文件的加密存储和解密读取。通过具体代码示例,展示了如何使用DES算法进行文件的加密和解密过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

附件加密存储

使用 javax.crypto.CipherInputStream javax.crypto.CipherOutputStream 对文件加解密。

对文件流的操作主要使用 hutool 工具包,引入依赖

        <!-- hutool 工具包 -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
        </dependency>

直接贴代码:

public class FileEncryption {
    //密钥
    public final static String sKey = "AD67EA2F3BE6E5ADD368DFE03120BXZ8PCCfPDL40GJFQ4GL";

    private static  FileEncryption fileEncryption = new FileEncryption();

    private FileEncryption(){}

    public static FileEncryption getInstance(){
        return fileEncryption;
    }
    
    /**
     * 文件加密
     *
     * @param sourcePath 原始文件路径
     * @param targetPath 加密后的存储路径
     */
    public void encryptFile(String sourcePath, String targetPath) {
        try {
            CipherInputStream cipherInputStream = getCipherInputStream(new FileInputStream(sourcePath));
            FileUtil.writeFromStream(cipherInputStream, targetPath);
            IoUtil.close(cipherInputStream);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        }
    }

    /**
     * 解密文件
     * @param sourcePath 待解密的文件路径
     * @param targetPath 解密后的文件路径
     */
    public void decryptFile(String sourcePath, String targetPath) {
        try {
            byte[] bytes = IoUtil.readBytes(new FileInputStream(sourcePath));
            ByteArrayInputStream byteArrayInputStream = IoUtil.toStream(bytes);

            byte[] bytK1 = getKeyByStr(sKey);
            Cipher cipher = getCipher(bytK1, Cipher.DECRYPT_MODE);


            OutputStream out = new FileOutputStream(targetPath);
            CipherOutputStream cipherOutputStream = new CipherOutputStream(out, cipher);
            IoUtil.copy(byteArrayInputStream, cipherOutputStream);

            IoUtil.close(byteArrayInputStream);
            IoUtil.close(out);
            IoUtil.close(cipherOutputStream);

        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        }

    }

    /**
     * 文件加密流
     * @param bytes 字节数组
     * @return javax.crypto.CipherInputStream
     * @throws InvalidKeySpecException 加密
     * @throws NoSuchPaddingException 解密报错
     * @throws NoSuchAlgorithmException 加密报错
     * @throws InvalidKeyException 验证Key异常
     */
    public CipherInputStream getCipherInputStream(byte[] bytes) throws InvalidKeySpecException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException {
        ByteArrayInputStream byteArrayInputStream = IoUtil.toStream(bytes);
        CipherInputStream cipherInputStream = this.getCipherInputStream(byteArrayInputStream);
        return cipherInputStream;
    }

    /**
     * 文件加密流
     * @param inputStream 文件输入流
     * @return javax.crypto.CipherInputStream
     * @throws InvalidKeySpecException 加密
     * @throws NoSuchPaddingException 解密报错
     * @throws NoSuchAlgorithmException 加密报错
     * @throws InvalidKeyException 验证Key异常
     */
    public CipherInputStream getCipherInputStream(InputStream inputStream) throws InvalidKeySpecException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException {
        byte[] bytK1 = getKeyByStr(sKey);

        Cipher cipher = getCipher(bytK1, Cipher.ENCRYPT_MODE);
        CipherInputStream cipherInputStream = new CipherInputStream(inputStream, cipher);

        IoUtil.close(inputStream);
        return cipherInputStream;
    }

    /**
     * 获取文件的解密输入流
     * @param sourcePath 原加密文件路径
     * @return java.io.ByteArrayInputStream
     */
    public InputStream getDecodeInputStream(String sourcePath) {
        try {
            String targetPath = getTempPath(sourcePath);
            //解密
            decryptFile(sourcePath, targetPath);
            File targetFile = new File(targetPath);
            FileInputStream fileInputStream = new FileInputStream(targetFile);
            byte[] readBytes = IoUtil.readBytes(fileInputStream);
            IoUtil.close(fileInputStream);
            //关闭后才能删除临时文件 fileInputStream
            delFile(targetPath);
            ByteArrayInputStream arrayInputStream = IoUtil.toStream(readBytes);
            return arrayInputStream;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 删除文件
     * @param targetPath 需要删除的文件路径
     */
    private void delFile(String targetPath){
        File targetFile = new File(targetPath);
        if (targetFile.exists()) {
            boolean del = FileUtil.del(targetFile);
            System.out.println("删除临时文件:" + del);
        }
    }

    /**
     * 获取解密临时文件路径
     * @param path 加密文件路径
     * @return 解密临时文件路径
     */
    private String getTempPath(String path) {
        int lastIndexOf = path.lastIndexOf('.');
        String file_path = path.substring(0, lastIndexOf);
        //拼接解密后的临时存储文件
        String targetPath = file_path + UUID.randomUUID().toString().replaceAll("-","") + ".temp";
        return targetPath;
    }

    //region Des
    /**
     * 得到密码类
     *
     * @param bytKey
     * @param i      ENCRYPT_MODE = 1 DECRYPT_MODE = 2
     * @return
     * @throws InvalidKeyException
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     * @throws NoSuchPaddingException
     */
    public Cipher getCipher(byte[] bytKey, int i) throws InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException {
        DESKeySpec desKS = new DESKeySpec(bytKey);
        SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
        SecretKey sk = skf.generateSecret(desKS);
        Cipher cipher = Cipher.getInstance("DES");
        cipher.init(i, sk);
        return cipher;
    }

    public static byte[] getKeyByStr(String str) {
        byte[] bRet = new byte[str.length() / 2];

        for (int i = 0; i < str.length() / 2; ++i) {
            Integer itg = new Integer(16 * getChrInt(str.charAt(2 * i)) + getChrInt(str.charAt(2 * i + 1)));
            bRet[i] = itg.byteValue();
        }

        return bRet;
    }

    public static int getChrInt(char chr) {
        int iRet = 0;
        if (chr == "0".charAt(0)) {
            iRet = 0;
        }

        if (chr == "1".charAt(0)) {
            iRet = 1;
        }

        if (chr == "2".charAt(0)) {
            iRet = 2;
        }

        if (chr == "3".charAt(0)) {
            iRet = 3;
        }

        if (chr == "4".charAt(0)) {
            iRet = 4;
        }

        if (chr == "5".charAt(0)) {
            iRet = 5;
        }

        if (chr == "6".charAt(0)) {
            iRet = 6;
        }

        if (chr == "7".charAt(0)) {
            iRet = 7;
        }

        if (chr == "8".charAt(0)) {
            iRet = 8;
        }

        if (chr == "9".charAt(0)) {
            iRet = 9;
        }

        if (chr == "A".charAt(0)) {
            iRet = 10;
        }

        if (chr == "B".charAt(0)) {
            iRet = 11;
        }

        if (chr == "C".charAt(0)) {
            iRet = 12;
        }

        if (chr == "D".charAt(0)) {
            iRet = 13;
        }

        if (chr == "E".charAt(0)) {
            iRet = 14;
        }

        if (chr == "F".charAt(0)) {
            iRet = 15;
        }

        return iRet;
    }
    //endregion

    public static void main(String[] args) {
        String sp = "E:\\文件加解密\\原始文件.docx";//原始文件
        String dp = "E:\\文件加解密\\加密文件.docx";//加密后文件
        String dp2 = "E:\\文件加解密\\解密文件.docx";//解密后文件

        FileEncryption fileEncrypter = new FileEncryption();
        //文件加密
        fileEncrypter.encryptFile(sp,dp);
        //文件解密
        fileEncrypter.decryptFile(dp,dp2);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值