Java通过流对文件加密

Posted 多读书,少说话

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java通过流对文件加密相关的知识,希望对你有一定的参考价值。

加密目标文件

代码如下:

不建议进行二次加密,若二次加密必须要二次解密

package com.xgt.util;
import java.io.*;
public class VideoEncodeUtil {

    public static void main(String[] args) throws Exception {
        encrypt("D:\\\\py交易\\\\11.mp4","fuckyourself");
        decrypt("D:\\\\py交易\\\\11.mp4","D:\\\\py交易\\\\22.mp4",4);
        System.out.println(readFileLastByte("D:\\\\py交易\\\\11.mp4",12));
    }
    /**
     * 文件file进行加密
     * @param fileUrl 文件路径
     * @param key 密码
     * @throws Exception
     */
    public static void encrypt(String fileUrl, String key) throws Exception {
        File file = new File(fileUrl);
        String path = file.getPath();
        if(!file.exists()){
            return;
        }
        int index = path.lastIndexOf("\\\\");
        String destFile = path.substring(0, index)+"\\\\"+"abc";
        File dest = new File(destFile);
        //获取待加密文件的输入流
        InputStream in = new FileInputStream(fileUrl);
        //创建中转文件输出流
        OutputStream out = new FileOutputStream(destFile);
        //待加密文件的流
        byte[] buffer = new byte[1024];
        int r;
        //加密之后的文件的流
        byte[] buffer2=new byte[1024];
        while (( r= in.read(buffer)) > 0) {
            for(int i=0;i<r;i++)
            {
                byte b=buffer[i];
                //buffer2[i]=b==255?0:++b;
                //每个字节加2加密
                b+=2;
                buffer2[i] = b;

            }
            out.write(buffer2, 0, r);
            out.flush();
        }
        in.close();
        out.close();
        file.delete();
        dest.renameTo(new File(fileUrl));
        appendMethodA(fileUrl, key);
        System.out.println("加密成功");
    }
    /**
     *
     * @param fileName
     * @param content 密钥
     */
    public static void appendMethodA(String fileName, String content) {
        try {
            // 打开一个随机访问文件流,按读写方式
            RandomAccessFile randomFile = new RandomAccessFile(fileName, "rw");
            // 文件长度,字节数
            long fileLength = randomFile.length();
            //将写文件指针移到文件尾。
            randomFile.seek(fileLength);
            randomFile.writeBytes(content);
            randomFile.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 解密
     * @param fileUrl 源文件
     * @param tempUrl 临时文件
     * @param keyLength 密码长度
     * @return
     * @throws Exception
     */
    public static String decrypt(String fileUrl, String tempUrl, int keyLength) throws Exception{
        File file = new File(fileUrl);
        if (!file.exists()) {
            return null;
        }
        File dest = new File(tempUrl);
        if (!dest.getParentFile().exists()) {
            dest.getParentFile().mkdirs();
        }
        //获取待解密的文件输入流
        InputStream is = new FileInputStream(fileUrl);
        //创建目标文件输出流,用来生成解密后的文件
        OutputStream out = new FileOutputStream(tempUrl);
        byte[] buffer = new byte[1024];
        byte[] buffer2=new byte[1024];
        byte bMax=(byte)255;
        long size = file.length() - keyLength;
        int mod = (int) (size%1024);
        int div = (int) (size>>10);
        int count = mod==0?div:(div+1);
        int k = 1, r;
        while ((k <= count && ( r = is.read(buffer)) > 0)) {
            if(mod != 0 && k==count) {
                r = mod;
            }
            for(int i = 0;i < r;i++)
            {
                byte b=buffer[i];
                //buffer2[i]=b==0?bMax:--b;
                //每个字节减2解码
                b-=2;
                buffer2[i] = b;

            }
            out.write(buffer2, 0, r);
            k++;
        }
        out.close();
        is.close();
        return tempUrl;
    }
    /**
     * 判断文件是否加密
     * @param fileName
     * @return
     *
     * 加密成功返回key
     * 加密失败返回非key的字符串
     */
    public static String readFileLastByte(String fileName, int keyLength) {
        File file = new File(fileName);
        if(!file.exists())return "没有文件";
        StringBuffer str = new StringBuffer();
        try {
            // 打开一个随机访问文件流,按读写方式
            RandomAccessFile randomFile = new RandomAccessFile(fileName, "rw");
            // 文件长度,字节数
            long fileLength = randomFile.length();
            //将写文件指针移到文件尾。
            for(int i = keyLength ; i>=1 ; i--){
                randomFile.seek(fileLength-i);
                str.append((char)randomFile.read());
            }
            randomFile.close();
            return str.toString();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "异常";
    }
}

加密和解密接口

    /**
     * 加密视频
     * @param fileName
     */
    public void encryptVideo(String fileName){
        try {
            File file = new File(fileUrl);
            FileToolUtil.judeDirExists(file);
            /**
             * 加密不可进行多次
             * 判断是否有加密,加密过无需在加密
            */
            if(!VideoEncodeUtil.readFileLastByte(fileUrl+"\\\\"+fileName,key.length()).equals(key)) {
                VideoEncodeUtil.encrypt(fileUrl + "\\\\" + fileName, key);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 解密视频
     * @param fileName
     */
    public String decryptVideo(String fileName) throws Exception {

            File file = new File(SystemConstant.VIDEO_TEMP_PATH);
            FileToolUtil.judeDirExists(file);
            return VideoEncodeUtil.decrypt(SAFETY_EDU_LOCAL_PATH +  fileName,
                    SystemConstant.VIDEO_TEMP_PATH +  fileName,
                    SystemConstant.VIDEO_ENCRYPT_DECRYPT_KEY.length());
    }

 

播放加密视频方法(播放解密后的流):

    /**
     * 播放加密MP4
     * @param response
     * @throws IOException
     */
    @RequestMapping("/playMp4")
    @ResponseBody
    public void playMp4(HttpServletResponse response,String fileName) throws Exception {

        // TODO 测试联调结束后需删除
        fileName = "edu/video/6689AC1A506133C13FDA593135E2D923.mp4";
        String tempFilePath = SystemConstant.VIDEO_TEMP_PATH +  fileName;
        try {

            tempFilePath = videoMaterialService.decryptVideo(fileName);
            // 解密过后的临时文件路径

            FileInputStream inputStream = new FileInputStream(tempFilePath);
            byte[] data = FileToolUtil.inputStreamToByte(inputStream);
            String diskfilename = "final.mp4";
            response.setContentType("video/mp4");
            response.setHeader("Content-Disposition", "attachment; filename=\\"" + diskfilename + "\\"" );
            System.out.println("data.length " + data.length);
            response.setContentLength(data.length);
            response.setHeader("Content-Range", "" + Integer.valueOf(data.length-1));
            response.setHeader("Accept-Ranges", "bytes");
            response.setHeader("Etag", "W/\\"9767057-1323779115364\\"");
            OutputStream os = response.getOutputStream();

            os.write(data);
            //先声明的流后关掉!
            os.flush();
            os.close();
            inputStream.close();

        }catch (Exception e){
            logger.error("....", e);
        }finally {
            VideoMaterialService.deleteVideoFile(tempFilePath);
        }

    }

 

前端代码展示

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title></title>

</head>

<body>


    <video src="http://127.0.0.1:8004/rest/video/playMp4?fileName=11.mp4" controls="controls">
        your browser does not support the video tag
    </video>





</body>

</html>

 

以上是关于Java通过流对文件加密的主要内容,如果未能解决你的问题,请参考以下文章

java中 使用输入+输出流对对象序列化

Java代码如何清空TXT文档

Java 加密和解密 PDF

Java 加密和解密 PDF

java地址栏加密

创建片段而不从 java 代码实例化它