Java通过流对文件加密
Posted 多读书,少说话
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java通过流对文件加密相关的知识,希望对你有一定的参考价值。
加密目标文件
代码如下:
不建议进行二次加密,若二次加密必须要二次解密
package com.xgt.util; import java.io.*; public class VideoEncodeUtil { public static void main(String[] args) throws Exception { encrypt("D:\\\\py交易\\\\11.mp4","fuckyourself"); decrypt("D:\\\\py交易\\\\11.mp4","D:\\\\py交易\\\\22.mp4",4); System.out.println(readFileLastByte("D:\\\\py交易\\\\11.mp4",12)); } /** * 文件file进行加密 * @param fileUrl 文件路径 * @param key 密码 * @throws Exception */ public static void encrypt(String fileUrl, String key) throws Exception { File file = new File(fileUrl); String path = file.getPath(); if(!file.exists()){ return; } int index = path.lastIndexOf("\\\\"); String destFile = path.substring(0, index)+"\\\\"+"abc"; File dest = new File(destFile); //获取待加密文件的输入流 InputStream in = new FileInputStream(fileUrl); //创建中转文件输出流 OutputStream out = new FileOutputStream(destFile); //待加密文件的流 byte[] buffer = new byte[1024]; int r; //加密之后的文件的流 byte[] buffer2=new byte[1024]; while (( r= in.read(buffer)) > 0) { for(int i=0;i<r;i++) { byte b=buffer[i]; //buffer2[i]=b==255?0:++b; //每个字节加2加密 b+=2; buffer2[i] = b; } out.write(buffer2, 0, r); out.flush(); } in.close(); out.close(); file.delete(); dest.renameTo(new File(fileUrl)); appendMethodA(fileUrl, key); System.out.println("加密成功"); } /** * * @param fileName * @param content 密钥 */ public static void appendMethodA(String fileName, String content) { try { // 打开一个随机访问文件流,按读写方式 RandomAccessFile randomFile = new RandomAccessFile(fileName, "rw"); // 文件长度,字节数 long fileLength = randomFile.length(); //将写文件指针移到文件尾。 randomFile.seek(fileLength); randomFile.writeBytes(content); randomFile.close(); } catch (IOException e) { e.printStackTrace(); } } /** * 解密 * @param fileUrl 源文件 * @param tempUrl 临时文件 * @param keyLength 密码长度 * @return * @throws Exception */ public static String decrypt(String fileUrl, String tempUrl, int keyLength) throws Exception{ File file = new File(fileUrl); if (!file.exists()) { return null; } File dest = new File(tempUrl); if (!dest.getParentFile().exists()) { dest.getParentFile().mkdirs(); } //获取待解密的文件输入流 InputStream is = new FileInputStream(fileUrl); //创建目标文件输出流,用来生成解密后的文件 OutputStream out = new FileOutputStream(tempUrl); byte[] buffer = new byte[1024]; byte[] buffer2=new byte[1024]; byte bMax=(byte)255; long size = file.length() - keyLength; int mod = (int) (size%1024); int div = (int) (size>>10); int count = mod==0?div:(div+1); int k = 1, r; while ((k <= count && ( r = is.read(buffer)) > 0)) { if(mod != 0 && k==count) { r = mod; } for(int i = 0;i < r;i++) { byte b=buffer[i]; //buffer2[i]=b==0?bMax:--b; //每个字节减2解码 b-=2; buffer2[i] = b; } out.write(buffer2, 0, r); k++; } out.close(); is.close(); return tempUrl; } /** * 判断文件是否加密 * @param fileName * @return * * 加密成功返回key * 加密失败返回非key的字符串 */ public static String readFileLastByte(String fileName, int keyLength) { File file = new File(fileName); if(!file.exists())return "没有文件"; StringBuffer str = new StringBuffer(); try { // 打开一个随机访问文件流,按读写方式 RandomAccessFile randomFile = new RandomAccessFile(fileName, "rw"); // 文件长度,字节数 long fileLength = randomFile.length(); //将写文件指针移到文件尾。 for(int i = keyLength ; i>=1 ; i--){ randomFile.seek(fileLength-i); str.append((char)randomFile.read()); } randomFile.close(); return str.toString(); } catch (IOException e) { e.printStackTrace(); } return "异常"; } }
加密和解密接口
/** * 加密视频 * @param fileName */ public void encryptVideo(String fileName){ try { File file = new File(fileUrl); FileToolUtil.judeDirExists(file); /** * 加密不可进行多次 * 判断是否有加密,加密过无需在加密 */ if(!VideoEncodeUtil.readFileLastByte(fileUrl+"\\\\"+fileName,key.length()).equals(key)) { VideoEncodeUtil.encrypt(fileUrl + "\\\\" + fileName, key); } } catch (Exception e) { e.printStackTrace(); } } /** * 解密视频 * @param fileName */ public String decryptVideo(String fileName) throws Exception { File file = new File(SystemConstant.VIDEO_TEMP_PATH); FileToolUtil.judeDirExists(file); return VideoEncodeUtil.decrypt(SAFETY_EDU_LOCAL_PATH + fileName, SystemConstant.VIDEO_TEMP_PATH + fileName, SystemConstant.VIDEO_ENCRYPT_DECRYPT_KEY.length()); }
播放加密视频方法(播放解密后的流):
/** * 播放加密MP4 * @param response * @throws IOException */ @RequestMapping("/playMp4") @ResponseBody public void playMp4(HttpServletResponse response,String fileName) throws Exception { // TODO 测试联调结束后需删除 fileName = "edu/video/6689AC1A506133C13FDA593135E2D923.mp4"; String tempFilePath = SystemConstant.VIDEO_TEMP_PATH + fileName; try { tempFilePath = videoMaterialService.decryptVideo(fileName); // 解密过后的临时文件路径 FileInputStream inputStream = new FileInputStream(tempFilePath); byte[] data = FileToolUtil.inputStreamToByte(inputStream); String diskfilename = "final.mp4"; response.setContentType("video/mp4"); response.setHeader("Content-Disposition", "attachment; filename=\\"" + diskfilename + "\\"" ); System.out.println("data.length " + data.length); response.setContentLength(data.length); response.setHeader("Content-Range", "" + Integer.valueOf(data.length-1)); response.setHeader("Accept-Ranges", "bytes"); response.setHeader("Etag", "W/\\"9767057-1323779115364\\""); OutputStream os = response.getOutputStream(); os.write(data); //先声明的流后关掉! os.flush(); os.close(); inputStream.close(); }catch (Exception e){ logger.error("....", e); }finally { VideoMaterialService.deleteVideoFile(tempFilePath); } }
前端代码展示
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <video src="http://127.0.0.1:8004/rest/video/playMp4?fileName=11.mp4" controls="controls"> your browser does not support the video tag </video> </body> </html>
以上是关于Java通过流对文件加密的主要内容,如果未能解决你的问题,请参考以下文章