博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
AES对上传文件解密并加密的实现(JAVA实现)
阅读量:4681 次
发布时间:2019-06-09

本文共 6847 字,大约阅读时间需要 22 分钟。

接到一个奇怪的业务:

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

 

   感谢这位博主的文章,给我提供了非常大的帮助!

 

直接上代码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 枚举类:
@Getterpublic 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;    }}
 

 

文件上传测试:

    

文件解密

 

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

 

后台打断点调试:

 

 

 

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

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

你可能感兴趣的文章
instanceof和typeof的细节
查看>>
android Canvas drawText 文字居中
查看>>
函数嵌套
查看>>
旋转编码器
查看>>
线程同步(互斥锁与信号量的作用与区别)
查看>>
【MyBatis】MyBatis之如何配置
查看>>
redi应用-延时队列
查看>>
性能测试数据收集工具nmon
查看>>
二分查找
查看>>
继承介绍以及单继承
查看>>
leetcode笔记:Sqrt(x)
查看>>
程序员的简历一
查看>>
全排列 -- next_permutation()
查看>>
JavaScript的DOM操作(1)
查看>>
Panorama控件和Pivot控件【WP7学习札记之十四】
查看>>
C#控制台打印简单【倒三角形】的图形
查看>>
记: 一次惊心动魄的解决 服务器 无解问题的心路历程
查看>>
超级迷宫站立会议2015/5/15
查看>>
92. Reverse Linked List II
查看>>
磁盘结构原理
查看>>