简单视频加密与授权

来源:互联网 发布:淘宝发布网络推广类目 编辑:程序博客网 时间:2024/04/30 20:26

原创文章,转载请注明原始链接,谢谢!

应同学邀请参加信息安全大赛,负责作品的"离线空间"模块,简单来说,离线空间就是要求加密视频只能在指定机器播放,并且只能播放规定次数。

思维导图如下


运行环境:JDK1.8, WIN8


一、加密视频EncVideo部分由以下几个模块组成:

1、Mac.java 

负责获取本地Mac

//获取本机MAC地址//提供一个方法 String getMac()//返回本机Mac地址package org.tree.enc;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;public class Mac {public String getMac() throws IOException{String MacAddress = null;BufferedReader br = null;Process pro = null;try{pro = Runtime.getRuntime().exec("ipconfig /all");br = new BufferedReader(new InputStreamReader(pro.getInputStream()));int index = -1;String line = null;while((line = br.readLine()) != null){String t = "物理地址";String que = new String(t.getBytes("GBK"));if(((index = line.indexOf(que)) != -1) || ((index = line.toLowerCase().indexOf("physical address")) != -1)){index = line.indexOf(":");MacAddress = line.substring(index + 1).trim();break;}}}catch(Exception e){e.printStackTrace();}finally{br.close();}return MacAddress;}}


2、MD5.java 

负责将Mac进行MD5加密

//对MAC地址进行MD5加密,生成32位字符串//提供一个方法String getMD5()//返回经过MD5加密后的MACpackage org.tree.enc;import java.security.MessageDigest;public class MD5 {public String getMD5(){String RawMessage = null;String MD5Message = null;try{RawMessage = new Mac().getMac();;MessageDigest md = MessageDigest.getInstance("MD5");md.update(RawMessage.getBytes());byte[] b = md.digest();StringBuffer temp = new StringBuffer("");for(int i = 0 ; i < b.length; i++){int tep = b[i];if(tep < 0){tep += 256;}if(tep < 16){temp.append("0");}temp.append(Integer.toHexString(tep));}MD5Message = temp.toString();}catch(Exception e){e.printStackTrace();}return MD5Message;}}


3、EncVideo.java 

负责对视频进行加密

//加密视频,在视频末尾添加MAC的MD5,生成Result.k文件//提供一个方法 void encVideo(String InPath, String OutPath)//InPath:需要加密的文件路径 OutPath:输出文件路径package org.tree.enc;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;public class EncVideo {public void encVideo(String InPath, String OutPath) throws IOException{FileInputStream in  = null;FileOutputStream out = null;try{in = new FileInputStream(InPath);out = new FileOutputStream(new File(OutPath+"\\Result.k"));byte[] b = new byte[1024];int temp = 0;while((temp = in.read(b)) != -1){out.write(b);}out.write(new MD5().getMD5().getBytes());}catch(Exception e){e.printStackTrace();}finally{if(in != null){in.close();}if(out != null){out.close();}}}}


4、UI.java

负责GUI部分

package org.tree.enc;import java.awt.BorderLayout;import java.io.File;import javax.swing.JButton;import javax.swing.JDialog;import javax.swing.JFileChooser;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JPanel;public class UI {private String InPath = null;private String OutPath = null;public UI(){JFrame f = new JFrame("加密视频");f.setSize(200, 150);f.setResizable(false);JPanel p1 = new JPanel();JPanel p2 = new JPanel();JPanel p3 = new JPanel();JFileChooser fc1 = new JFileChooser();JButton b1 = new JButton("选择加密文件");JFileChooser fc2 = new JFileChooser();JButton b2 = new JButton("选择保存位置");JButton b3 = new JButton("加密");p1.add(b1);p2.add(b2);p3.add(b3);f.add(p1, BorderLayout.NORTH);f.add(p2, BorderLayout.CENTER);f.add(p3, BorderLayout.SOUTH);f.setVisible(true);b1.addActionListener(event -> {fc1.setDialogTitle("请选择需要加密的文件");fc1.showOpenDialog(b1);});b2.addActionListener(event -> {fc2.setDialogTitle("请选择要保存的位置");fc2.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);fc2.showSaveDialog(b2);});fc1.addPropertyChangeListener(event -> {if(event.getPropertyName() == JFileChooser.SELECTED_FILE_CHANGED_PROPERTY){File file = (File)event.getNewValue();InPath = file.getPath();}});fc2.addPropertyChangeListener(event -> {if(event.getPropertyName() == JFileChooser.SELECTED_FILE_CHANGED_PROPERTY){File file = (File)event.getNewValue();OutPath = file.getPath();}});b3.addActionListener(event -> {try{if(InPath == null){JDialog d = new JDialog(f, "您没有选择需要加密的文件!", true);JLabel la = new JLabel("请选择需要加密的文件!", JLabel.CENTER);d.add(la, BorderLayout.CENTER);d.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);d.setSize(300, 100);d.setVisible(true);}else if(OutPath == null){JDialog d = new JDialog(f, "您没有选择保存的位置!", true);JLabel la = new JLabel("请选择需要保存的位置!", JLabel.CENTER);d.add(la, BorderLayout.CENTER);d.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);d.setSize(300, 100);d.setVisible(true);}else{new EncVideo().encVideo(InPath, OutPath);JDialog d = new JDialog(f, "加密完毕!", false);JLabel la = new JLabel("加密完毕!", JLabel.CENTER);d.add(la, BorderLayout.CENTER);d.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);d.setSize(300, 100);d.setVisible(true);}}catch(Exception e){e.printStackTrace();}});f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}public static void main(String[] args){new UI();}}

运行效果(以test.mp4为例):

1、程序主界面


2、程序运行结果




二、解密视频DecVideo由以下几个模块组成:

1、Mac.java

获取MAC 同上

2、MD5.java

对MAC进行MD5加密 同上

3、DecVideo.java

负责对提取视频中的MD5

//提取视频中MAC//提供一个方法 String getMacMD5(String path)//返回视频中的MAC path:要打开的加密文件的路径package org.tree.pla;import java.io.RandomAccessFile;public class DecVideo {public String getMacMD5(String path){String VideoMD5 = null;try(RandomAccessFile raf = new RandomAccessFile(path, "r")){long len = raf.length();raf.seek(len-32);byte[] b = new byte[32];raf.read(b);VideoMD5 = new String(b);}catch(Exception e){e.printStackTrace();}return VideoMD5;}}
4、PlayVideo.java

负责调用本地播放器播放视频

//播放视频//提供两个方法 boolean CompareMD5(String path)//比较视频中的MAC与本地MAC//void Player(Sting path)//播放视频//提供一个类变量 int count 用来标识剩余授权次数package org.tree.pla;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.RandomAccessFile;public class PlayVideo {public static int count = 10;public boolean CompareMD5(String path){String VideoMD5 = new DecVideo().getMacMD5(path);String LocalMD5 = new MD5().getMD5();if(VideoMD5.equals(LocalMD5)){return true;}else{return false;}}public void Player(String path){if(new PlayVideo().CompareMD5(path)){try{FileInputStream in = new FileInputStream(path);FileOutputStream out = new FileOutputStream("C:\\tmp\\isctmp.avi");byte[] tmpb = new byte[1024];int index = 0;while((index = in.read(tmpb)) != -1){out.write(tmpb);}in.close();out.close();File f = new File("C:\\Users\\Public\\Documents\\IscInfo.ini");if(f.exists()){RandomAccessFile raf = new RandomAccessFile(f, "rw");byte[] b = new byte[4];raf.read(b);String result = new String(b);int num = Integer.parseInt(result.trim());if(num != 0 && num <= 10){raf.setLength(0);num--;PlayVideo.count = num;String numtmp = num + "";raf.write(numtmp.getBytes());Process pro = Runtime.getRuntime().exec("C:\\Program Files\\Windows Media Player\\wmplayer.exe " + "C:\\tmp\\isctmp.avi");}else{File inf = new File(path);inf.delete();}raf.close();}else{PlayVideo.count = 10;FileOutputStream out1 = new FileOutputStream(f.getPath());out1.write("10".getBytes());Process pro = Runtime.getRuntime().exec("C:\\Program Files\\Windows Media Player\\wmplayer.exe " + "C:\\tmp\\isctmp.avi");out1.close();}}catch(Exception e){e.printStackTrace();}}else{System.out.println("你不能播放这个视频");}}}
6、UI.java

负责GUI,验证授权信息

package org.tree.pla;import java.awt.BorderLayout;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;import java.io.File;import javax.swing.JButton;import javax.swing.JDialog;import javax.swing.JFileChooser;import javax.swing.JFrame;import javax.swing.JLabel;public class UI {private String path = null;public UI(){JFrame f = new JFrame("播放加密视频");f.setSize(250, 100);f.setResizable(false);JButton b1 = new JButton("选择加密文件");JButton b2 = new JButton("播放");JFileChooser fc = new JFileChooser();f.add(b1, BorderLayout.CENTER);f.add(b2, BorderLayout.SOUTH);f.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);f.setVisible(true);b1.addActionListener(event -> {fc.setDialogTitle("请选择需要打开的文件");fc.showOpenDialog(b1);});b2.addActionListener(event -> {if(path == null){JDialog d = new JDialog(f, "您没有选择打开的文件!", true);JLabel la = new JLabel("请选择需要打开的文件!", JLabel.CENTER);d.add(la, BorderLayout.CENTER);d.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);d.setSize(300, 100);d.setVisible(true);}if(new PlayVideo().CompareMD5(path)){if(PlayVideo.count <= 0){JDialog d = new JDialog(f, "权限不足", true);JLabel la = new JLabel("您的剩余授权次数不足!", JLabel.CENTER);d.add(la, BorderLayout.CENTER);d.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);d.setSize(300, 100);d.setVisible(true);File file = new File(path);file.delete();}else{new PlayVideo().Player(path);JDialog d = new JDialog(f, "剩余使用次数");JLabel la = new JLabel("剩余使用次数为: " + PlayVideo.count, JLabel.CENTER);d.add(la, BorderLayout.CENTER);d.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);d.setSize(300, 100);d.setVisible(true);}}else{JDialog d = new JDialog(f, "权限不足", true);JLabel la = new JLabel("您没有别授权打开此文件!", JLabel.CENTER);d.add(la, BorderLayout.CENTER);d.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);d.setSize(300, 100);d.setVisible(true);File file = new File(path);file.delete();}});fc.addPropertyChangeListener(event -> {if(event.getPropertyName() == JFileChooser.SELECTED_FILE_CHANGED_PROPERTY){File file = (File)event.getNewValue();path = file.getPath();}});f.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {try{File file = new File("C:\\tmp\\isctmp.avi");file.delete();}catch(Exception ex){ex.printStackTrace();}System.exit(0);}});}public static void main(String[] args){new UI();}}

程序运行结果:

1、程序主界面


2、程序运行界面



小结

简单的视频加密,不过现在的加密非常的脆弱,比如将.k改名为.avi等视频格式就可以正常播放,修改授权信息内容就可以无限次播放,将隐式转换成视频格式的文件复制一份也可以正常播放。要对抗这种方式的攻击就需要用到其他加密方法,这就不在本文讨论范围了QAQ(其实我会说我也不懂吗。。。我只负责这个模块,听说还有左右手识别,吧唧吧唧的什么的加密方法Orz)

PS.忽略我写的渣的JAVA代码。。新手...IO方面各种流乱用 还有GUI那写的更不能看了QAQ


0 0
原创粉丝点击