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文件的解密内容了:




}
}


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM