java實現文件加解密方案


0、前序

上傳加密:客戶端上傳文件,后台加密,將加密后的文件存儲到文件服務器
下載解密:客戶端請求文件,后台從文件服務器獲取密文,解密返回客戶端
 
注:對文件服務器上存儲的文件需要做防篡改校驗
 
效果預覽:原文件,密文件,解密文件

1、客戶端(html)

<form action="http://192.168.2.170:8080/api/v1/test/file/encryption" method="post" enctype="multipart/form-data">
    <p><input type="file" name="file"></p>
    <p><input type="text" name="clintMD5" value="e926b155ebf5f192bd71dbcec7dcb171"></p>
    <p><input type="submit" value="submit"></p>
</form>

2、客戶端上傳、請求文件

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、思路(復盤)

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM