java实现文件加解密方案

0、前序

上传加密:客户端上传文件,后台加密,将加密后的文件存储到文件服务器

下载解密:客户端请求文件,后台从文件服务器获取密文,解密返回客户端

注:对文件服务器上存储的文件需要做防篡改校验

效果预览:原文件,密文件,解密文件

java实现文件加解密方案

1、客户端(html)

2、客户端上传、请求文件

java实现文件加解密方案

3、服务端(源码)

package com.huang.mydemo.encryption;

import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;

@RestController
@RequestMapping(value = "api/v1/test")
public class FileUploadEncryptionController {
    //加密解密秘钥,不能超过一个字节,也就是8位(生产环境可针对每个文件随机生成秘钥,确保每个文件的秘钥都不一样)
    private static final int secretKey = 99;     //0x99 十六进制0-99,10进制0-255随机产生【异或】秘钥
    private static int dataByte = 0; //文件字节内容

    /**
     * 文件加密
     * @param file   上传的文件
     * @param request
     * @return
     */
    @PostMapping("file/encryption")
    public String encryption(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
        try {
            //0、先检查文件是否被篡改:此操作
            String srcMd5 = DigestUtils.md5Hex(file.getInputStream());
            System.out.println("源文件MD5:"+srcMd5);

            String clintMD5 = request.getParameter("clintMD5");
            System.out.println("clintMD5:"+clintMD5);

            if(!clintMD5.equals(srcMd5))  return "上传文件被篡改";

            //2、创建加密文件:临时文件
            File encFile = new File("F:\\Users\\admin\\Desktop\\enc_file.png");
            if(!encFile.exists()){
                encFile.createNewFile();//创建临时文件
            }

            //3、加密文件
            InputStream fis = file.getInputStream();
            OutputStream fos = new FileOutputStream(encFile);

            System.out.println("-------加密开始------");
            while ((dataByte = fis.read()) > -1) {
                fos.write(dataByte^secretKey);
            }

            fis.close();
            fos.flush();
            fos.close();
            System.out.println("-------加密完成------");

            //4、生成加密文件的MD5,防止文件服务器篡改
            String encMd5 = DigestUtils.md5Hex(new FileInputStream(encFile));
            System.out.println("密文件MD5:"+encMd5);

            //TODO 5、存储加密文件

            //TODO 6、删除临时文件:encFile

            return "ok";
        } catch (Exception e) {
            return e.getMessage();
        }
    }

    /**
     * 解密文件
     * @param response
     */
    @GetMapping("file/decryption")
    public void decryption(HttpServletResponse response) {
        File f = null;
        try {
            //TODO 1、从文件服务器获取加密文件(这里直接取上面加密后的临时文件,生产环境从oss或其他文件服务器获取)
            File encFile = new File("F:\\Users\\admin\\Desktop\\enc_file.png");
            //加密文件的MD5值,检查文件是否被篡改
            String encMd5 = DigestUtils.md5Hex(new FileInputStream(encFile));
            System.out.println("密文件MD5:"+encMd5);

            //TODO 2、encMd5与存储时的密码MD5进行比对(略),检查文件是否被篡改

            //3、创建解密文件:临时文件
            File decFile = new File("F:\\Users\\admin\\Desktop\\dec_file.jpeg");

            if(!decFile.exists()){
                decFile.createNewFile();//创建临时文件
            }

            //4、解密
            InputStream fis  = new FileInputStream(encFile);
            OutputStream fos = new FileOutputStream(decFile);

            System.out.println("--------------解密开始--------------");
            while ((dataByte = fis.read()) > -1) {
                fos.write(dataByte^secretKey);
            }
            fis.close();
            fos.close();
            fos.flush();

            System.out.println("--------------解密完成--------------");

            //TODO 5、响应数据添加MD5,防止响应文件数据被篡改

            //6、返回解密后的文件
            InputStream stream = new FileInputStream(decFile);
            ServletOutputStream out = response.getOutputStream();

            byte buff[] = new byte[1024];
            int length = 0;

            while ((length = stream.read(buff)) > 0) {
                out.write(buff,0,length);
            }
            stream.close();
            out.close();
            out.flush();

            //TODO 7、删除临时文件:decFile

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

4、思路(复盘)

java实现文件加解密方案

Original: https://www.cnblogs.com/unruly/p/15992273.html
Author: 福尔摩狼
Title: java实现文件加解密方案

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/579632/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 使用系统参数表,提升系统的灵活性

    1、使用系统参数表的好处 ​ Spring Boot项目中常有一些相对稳定的参数设置项,其作用范围是系统级的或模块级的,这些参数称为系统参数。这些变量以参数形式进行配置,从而提高变…

    Java 2023年6月14日
    094
  • List集合

    一、什么是集合? 顾名思义集合就相当于一个容器,容器就可以存储,只不过在java中存储的是对象,而对象本身是在堆内存中的,所以集合中存放的是一个个对象的引用。 二、集合和数组的区别…

    Java 2023年6月9日
    074
  • Gentoo用上虚拟机中的战斗机KVM

    ====== Gentoo用上虚拟机中的战斗机KVM ======Created 星期四 22 十月 2009 By Z.Y.F@msn.com 一,准备工作: egrep &#8…

    Java 2023年5月30日
    077
  • JAVA Builder模式构建MAP/LIST的示例

    我们在构建一个MAP时,要不停的调用put,有时候看着觉得很麻烦,刚好,看了下builder模式,觉得这思路不错,于是乎,照着用builder模式写了一个构建MAP的示例,代码如下…

    Java 2023年5月29日
    0101
  • nuxt将数据储存到cookic,并添加至title

    1.执行命令 npm i –save cookie-universal-nuxt 2.在nuxt.config.js中添加 ‘cookie-universal-nuxt…

    Java 2023年6月14日
    079
  • Java后端开发——美团(牛客)

    Java的基本数据类型,各自的字节数 ​ 老生常谈,不多说了. 类型 字节数 byte 1字节 short 2字节 int 4字节 long 8字节 float 4字节 doubl…

    Java 2023年6月7日
    063
  • Spring Boot + Spring Cloud 实现权限管理系统 后端篇(二十三):配置中心(Config、Bus)

    在线演示 演示地址:http://139.196.87.48:9002/kitty 用户名:admin 密码:admin 技术背景 如今微服务架构盛行,在分布式系统中,项目日益庞大…

    Java 2023年5月30日
    093
  • Spring IOCAOPBean

    Spring是一个轻量级的控制反转IOC和面向切面编程AOP的框架 Spring 自带 IoC(Inverse of Control:控制反转) 和 AOP(Aspect-Orie…

    Java 2023年6月5日
    087
  • NO8 电动汽车的创意构想

    (本文为ppt,可以在文件中看到对应ppt文件) 大哉乾元 2016/7/19 作者原创转载请注明出处 电动汽车的构想 李海波 Zte_lhb@126.com 起因 — 上周去超市…

    Java 2023年6月8日
    081
  • 订单系统学习

    概述 本文主要讲述了在传统电商企业中,订单系统应承载的角色,就订单系统所包含的主要功能模块梳理了设计思路,并对订单系统未来的发展做了一些思考。 1、订单系统在企业中的角色 在搭建企…

    Java 2023年5月29日
    082
  • Java String的intern()注意事项(分JDK1.6及JDK1.7)

    注意:上面所说的是指JDK1.7 运行时常量池在堆中!!! Original: https://www.cnblogs.com/mrhgw/p/14510797.htmlAutho…

    Java 2023年5月29日
    097
  • Spring Cloud Gateway 路由谓词工厂

    Spring Cloud Gateway 包含许多内置的Route Predicate Factories。所有这些谓词都匹配HTTP请求的不同属性。多个 Route Predic…

    Java 2023年5月30日
    085
  • Java基础 awt Frame 点击叉后,在控制台输出提示信息并关闭程序

    JDK :OpenJDK-11 OS :CentOS 7.6.1810 IDE :Eclipse 2019‑03 typesetting :Markdown code packag…

    Java 2023年5月29日
    058
  • SpringBoot读取.yml配置文件最常见的两种方式-源码及其在nacos的应用

    一、前言 我们在开发中会经常遇到一些可能会变的值,比如数据库的密码,一些关键链接的配置等等。 都需要我们写在配置文件中,这样可以把这些配置文件放到nacos上进行管理,修改naco…

    Java 2023年6月15日
    079
  • Android 自定义通用的loadingview

    介绍 好久没有写博客啦,最近在接近新年了,年前的工作都要收尾,所以特别忙,周末抽空写了个通用的加载view,写篇博客分享出来。 功能 1、显示加载视图,加载失败的时候显示加载失败视…

    Java 2023年6月13日
    078
  • 设计模式学习笔记(十七)中介者模式及其应用场景

    中介者(Mediator)模式指定义了一个单独的中介对象,来封装一组对象之间的交互。即将这组对象之间的交互委派给中介对象,从而来避免对象之间的直接交互。比如我们各种设备之间的通信,…

    Java 2023年6月6日
    087
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球