当前位置: 首页 > news >正文

AES对上传文件解密并加密的实现(JAVA实现)

接到一个奇怪的业务:

先使用公钥对已经加密过的上传文件进行解密,再使用另一个密钥对解密好的文件进行加密,然后保存到内网:

 

https://blog.csdn.net/ylcacsdn/article/details/73866091   感谢这位博主的文章,给我提供了非常大的帮助!

 

直接上代码Demo:

Controller 类:

 

@RestController
@RequestMapping("/file")
@Slf4j
/**
 * 笔录文件保存类
 */
public class FileController {

    @Autowired
    private ProjectUrl projectUrl;

    /**
     * 文件公钥解密后加密保存
     * @param file 文件本体
     * @return
     */
    @PostMapping("/decryptFile")
    public ResultVO decryptFile(@RequestParam("file") MultipartFile file) {
        if (file.isEmpty()) {
            log.error("【保存失败!文件出错,file={}】", file);
            return ResultVoUtil.error(ResultEnum.FILE_ERROR);
        }

        // 文件名加上文件后缀名
        String originalName = file.getOriginalFilename();
        String suffixName = originalName.substring(originalName.lastIndexOf("."));

        String filename = UUID.randomUUID()+ String.valueOf(new Random().nextInt(1000)) + suffixName;

        // 解密文件后保存
        UpLoadFileUtil.saveAndEditFile(file, projectUrl.getFilePath(), filename, AESTypeEnum.DECRYPT.getCode());
        return ResultVoUtil.success();
    }
}

 

 

 


UpLoadFileUtil 对文件加密的工具类:
public class UpLoadFileUtil {

    /**
     * 
     * @param file      上传源文件
     * @param filePath  保存路径
     * @param fileName  保存文件名
     * @param type      密文类型
     */
    public static void saveAndEditFile(MultipartFile file, String filePath, String fileName, Integer type) {

        // 公共密钥
        String cKey = "123";
        // 开始加密文件

        // 临时解密文件
        File tempFile = new File(filePath + "_" + fileName);
        // 再加密的目标文件
        File goalFile = new File(filePath + fileName);

        if (!tempFile.getParentFile().exists()) {
            tempFile.getParentFile().mkdirs();
        }
        if (tempFile.isFile() && tempFile.exists()) {
            tempFile.delete();
        }
        if (type == AESTypeEnum.ENCRYPT.getCode()) {
            // 文件加密
            tempFile = AESUtil.encryptFile(file, tempFile, cKey);
        }else if (type == AESTypeEnum.DECRYPT.getCode()) {
            // 文件解密
            tempFile = AESUtil.decryptFile(file, tempFile, cKey);

            // 使用密钥2加密
            String sKey2 = "456";
            goalFile = AESUtil.encryptFile(tempFile, goalFile, sKey2);
            if (tempFile.exists()) tempFile.delete();

        }else if (type == AESTypeEnum.NONE.getCode()) {
            try {
                file.transferTo(tempFile);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }


}

 

 
 
AESTypeEnum 枚举类:

@Getter
public enum  AESTypeEnum {
    ENCRYPT(0, "AES加密"),
    DECRYPT(1, "AES解密"),
    NONE(2, "不加密")
    ;

    private Integer code;
    private String msg;

    AESTypeEnum(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }
}
 
 

 

AESUtil 类:(用于AES流的初始化的工具类)

public class AESUtil {

    // AES 加密初始化
    public static Cipher initAESCipher(String sKey, int cipherMode) {
        // 创建Key gen
        KeyGenerator generator = null;
        Cipher cipher = null;

        try {
            generator = KeyGenerator.getInstance("AES");
            generator.init(128, new SecureRandom(sKey.getBytes()));

            SecretKey secretKey = generator.generateKey();
            byte[] codeFormat = secretKey.getEncoded();

            SecretKeySpec keySpec = new SecretKeySpec(codeFormat, "AES");
            cipher = Cipher.getInstance("AES");

            // 初始化
            cipher.init(cipherMode, keySpec);

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        }
        return cipher;
    }

    /**
     * 文件格式化
     * @param sourceFile1 上传文件
     * @param sourceFile2 本地文件
     * @param encrypFile  加密后的文件
     * @param sKey        密钥
     * @param type        加密类型
     * @return
     */
    public static File enOrDeFile(MultipartFile sourceFile1, File sourceFile2, File encrypFile, String sKey, int type) {
        InputStream inputStream = null;
        OutputStream outputStream = null;

        try {
            if (sourceFile1 != null) inputStream = sourceFile1.getInputStream();
            if (sourceFile2 != null) inputStream = new FileInputStream(sourceFile2);
            outputStream = new FileOutputStream(encrypFile);
            Cipher cipher = initAESCipher(sKey, type);

            CipherInputStream cipherInputStream = null;
            CipherOutputStream cipherOutputStream = null;
            if (Cipher.ENCRYPT_MODE == type) {
                // 创建加密流
                cipherInputStream = new CipherInputStream(inputStream, cipher);
            }else if (Cipher.DECRYPT_MODE == type) {
                // 创建解密流
                cipherOutputStream = new CipherOutputStream(outputStream, cipher);
            }

            byte [] cache = new byte[1024];

            int isread = 0;
            if (Cipher.ENCRYPT_MODE == type) {
                // 加密流写入文件
                while ((isread = cipherInputStream.read(cache, 0, cache.length)) != -1) {

                    outputStream.write(cache, 0, isread);
                }
            }else if (Cipher.DECRYPT_MODE == type) {
                // 解密流开始写入文件
                while ((isread = inputStream.read(cache, 0, cache.length)) != -1) {

                    cipherOutputStream.write(cache, 0, isread);
                }
            }

            if (cipherInputStream != null) cipherInputStream.close();
            if (cipherOutputStream != null) cipherOutputStream.close();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (inputStream != null) inputStream.close();
                if (outputStream != null) outputStream.close();

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return encrypFile;
    }


    // 文件加密
    public static File encryptFile(MultipartFile sourceFile, File encrypFile, String sKey) {
        File file = enOrDeFile(sourceFile, null, encrypFile,sKey, Cipher.ENCRYPT_MODE);
        return file;
    }

    /**
     * 文件解密
     * @param sourceFile http通讯文件
     * @param encrypFile 目标文件
     * @param sKey  密钥
     * @return
     */
    public static File decryptFile(MultipartFile sourceFile, File encrypFile, String sKey) {
        File file = enOrDeFile(sourceFile, null, encrypFile,sKey, Cipher.DECRYPT_MODE);
        return file;
    }

    /**
     * 加密文件
     * @param sourceFile 源文件
     * @param encrypFile 目标文件
     * @param sKey  密钥
     * @return
     */
    public static File encryptFile(File sourceFile, File encrypFile, String sKey) {
        File file = enOrDeFile(null, sourceFile, encrypFile, sKey, Cipher.ENCRYPT_MODE);
        return file;
    }

}
 
 

 

文件上传测试:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no">
    <title></title>

</head>
<body>
<div class="content">
    <h3>文件解密</h3>
    <input id="fileupload" type="file" name="file" data-url="/file/decryptFile">
</div>

<script type="text/javascript" src="/js/jquery-1.8.3.min.js"></script>
<script type="text/javascript" src="/js/jquery.ui.widget.js"></script>
<script type="text/javascript" src="/js/jquery.iframe-transport.js"></script>
<script type="text/javascript" src="/js/jquery.fileupload.js"></script>
<script>
    $(function(){

    })

    $('#fileupload').fileupload({
        dataType: 'json',
        url: "/file/decryptFile",//文件的后台接受地址
        //设置进度条
        progressall: function (e, data) {
            var progress = parseInt(data.loaded / data.total * 100);
            $('#progress .bar').css(
                    'width',
                    progress + '%'
            );
        },
        //上传完成之后的操作,显示在img里面
        done: function (e, data){
            $("#uploadimg").attr({src: data.result.pic_url});
            $("#uploadimg").css({width: "400px", height: "400px"});
        }
    });

</script>
</body>
</html>

 

现在开始上传一份使用公钥“123”加密过的文件:

 

后台打断点调试:

 

 

 

可以看到,tempFile文件的解密内容了:




}
}

转载于:https://www.cnblogs.com/libera11/p/8638838.html

相关文章:

  • Utilities之EXPIMP小结
  • HPU 1166: 阶乘问题(一)
  • Utilities之EXPIMP小结-续1
  • [原创]Zabbix3.4_API的python示例
  • VC程序异常中断的原因
  • POJ 2331 Water pipe IDA*
  • 软件问题
  • POJ 3460 Booksort IDA*
  • SpringCloud系列八:自定义Ribbon配置
  • 结构之法算法之道blog最新博文集锦第6期CHM文件0积分下载
  • BZOJ4318: OSU!
  • MSBuild使用初步
  • python库--pandas--写入文本文件
  • WPF程序编译(从命令行到Visual Studio)
  • Hibernate学习(1)- 初识
  • Android 架构优化~MVP 架构改造
  • Android开发 - 掌握ConstraintLayout(四)创建基本约束
  • CSS实用技巧
  • Java,console输出实时的转向GUI textbox
  • PHP变量
  • Python打包系统简单入门
  • Python学习之路13-记分
  • SpriteKit 技巧之添加背景图片
  • Storybook 5.0正式发布:有史以来变化最大的版本\n
  • Vue实战(四)登录/注册页的实现
  • windows-nginx-https-本地配置
  • 复习Javascript专题(四):js中的深浅拷贝
  • 后端_MYSQL
  • 解决jsp引用其他项目时出现的 cannot be resolved to a type错误
  • 浏览器缓存机制分析
  • 模仿 Go Sort 排序接口实现的自定义排序
  • 通过来模仿稀土掘金个人页面的布局来学习使用CoordinatorLayout
  • 与 ConTeXt MkIV 官方文档的接驳
  • 怎么将电脑中的声音录制成WAV格式
  • 找一份好的前端工作,起点很重要
  • 《天龙八部3D》Unity技术方案揭秘
  • 阿里云服务器如何修改远程端口?
  • 哈罗单车融资几十亿元,蚂蚁金服与春华资本加持 ...
  • ​520就是要宠粉,你的心头书我买单
  • #NOIP 2014# day.2 T2 寻找道路
  • (Redis使用系列) SpringBoot 中对应2.0.x版本的Redis配置 一
  • (草履虫都可以看懂的)PyQt子窗口向主窗口传递参数,主窗口接收子窗口信号、参数。
  • (附源码)ssm学生管理系统 毕业设计 141543
  • (附源码)计算机毕业设计SSM智慧停车系统
  • (三)模仿学习-Action数据的模仿
  • (十八)devops持续集成开发——使用docker安装部署jenkins流水线服务
  • (实战)静默dbca安装创建数据库 --参数说明+举例
  • (译)计算距离、方位和更多经纬度之间的点
  • (转)c++ std::pair 与 std::make
  • (转)Windows2003安全设置/维护
  • (转)原始图像数据和PDF中的图像数据
  • *2 echo、printf、mkdir命令的应用
  • *上位机的定义
  • .NET Project Open Day(2011.11.13)
  • .NET 编写一个可以异步等待循环中任何一个部分的 Awaiter