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)

大家都在看

  • 关于提问

    A 和 B 对话如下: A: xx 产品,一个月一个版本,只包含一个小功能,培训销售的工作跟不上怎么办?培训工作跟不上,研发做的功能前端都不知道,那做了有什么用?为什么不规划成大版…

    Java 2023年6月16日
    084
  • AQS源码二探-JUC系列

    本文已在公众号上发布,感谢关注,期待和你交流。 AQS源码二探-JUC系列 共享模式 这个方法是共享模式下获取资源失败,执行入队和等待操作,等待的线程在被唤醒后也在这个方法中自旋执…

    Java 2023年6月13日
    059
  • SpringCloud服务间调用

    SpringCloud服务间的调用有两种方式:RestTemplate和FeignClient。不管是什么方式,他都是通过REST接口调用服务的http接口,参数和结果默认都是通过…

    Java 2023年5月30日
    058
  • MySQL二:SQL运行机制

    转载~ MySQL用了很久,但是一直也是工作的使用,对于MySQL的知识点都比较零散碎片,一直也没有整体梳理过,趁着最近不忙,梳理一下相关的知识点。 一、 MySQL的起源 MyS…

    Java 2023年6月8日
    065
  • Nginx 源码分析– 内存池(pool)的分析 二

    在上一篇中,以一张图(图1)介绍了nginx内存池管理函数的总体概况,并分析了底层支持函数和内存池(pool)管理所需要用到的一些数据结构。这里我们将来具体分析内存池管理功能函数。…

    Java 2023年6月15日
    074
  • springboot自动装配原理探究

    springboot自动装配原理探究 结论: SpringBoot启动会加载大量的自动配置类 我们看我们需要的功能有没有在SpringBoot默认写好的自动配置类当中; 我们再来看…

    Java 2023年6月9日
    066
  • Spring Cloud认知学习(三):声明式调用Feign的使用

    Feign 使用示例 1.导入依赖: 2.新建Feign Interface 3.创建服务消费者 4.测试 补充: 💡上一篇介绍微服务构建起来后,使用Ribbon来解决多个服务的负…

    Java 2023年5月30日
    077
  • Java基础-续1

    方法 概念 在JS中,我们把方法称之为函数。在java我们称之为方法。 方法就是一个黑匣子。我们不需要知道内部是如何执行的,只要按照要求调用,就能完成必要的功能。 方法申明的语法:…

    Java 2023年6月7日
    057
  • 使用Intellij IDEA搭建Ext JsMVC web项目

    由于自己从android开发转来学习web开发,最近在学习Jsp,之前接触过一点Extjs,所以用jsp来配合ext试试。 Ext JS介绍 extjs是一个javascript框…

    Java 2023年6月13日
    053
  • JAVAEE学习路线分享

    今天把我的教学经验分享给大家。适合大多数人的学习路线。注:目前作者已经转行做java培训。 首先是培养兴趣。先开始学习HTML知识。也就是做网页,从这里开始比较简单,就是几个标签单…

    Java 2023年6月9日
    088
  • 完整SpringBoot Cache整合redis缓存(二)

    缓存注解概念 名称 解释 Cache 缓存接口,定义缓存操作。实现有:RedisCache、EhCacheCache、ConcurrentMapCache等 CacheManage…

    Java 2023年6月7日
    070
  • 接下来或许是一年中跳槽的最佳时间

    一般来说,很多人都认为一年中最佳的跳槽时间是三、四月份,也就是我们常说的”金三银四”。 但我认为”金三银四”不一定是性价比最佳的时间…

    Java 2023年6月7日
    082
  • java基础

    一:java反射机制的原理java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法,这种动态获取节点信息以及动…

    Java 2023年6月5日
    072
  • 导入导出笔记-easyExcel初探(表格导入和模板化导出)

    前言 本文使用的EasyExcel Alibaba和EasyPoi Apache技术栈分析 EasyExcel Dependency EasyPoi Dependency 1、需求…

    Java 2023年6月5日
    065
  • 将shardingsphere版本从5.0.0-alpha升到5.1.0遇到的坑

    今天将shardingsphere版本改成5.1.0之后项目启动不了了,报错信息如下: org.springframework.beans.factory.BeanCreation…

    Java 2023年6月7日
    084
  • maven中profiles使用详解

    使用的场景 常常遇到一些项目中多环境切换的问题。比如在开发过程中用到开发环境,在测试中使用测试环境,在生产中用生产环境的情况。springboot中提供了 spring.profi…

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