概述
原创文章,转载请注明原始链接,谢谢!
应同学邀请参加信息安全大赛,负责作品的"离线空间"模块,简单来说,离线空间就是要求加密视频只能在指定机器播放,并且只能播放规定次数。
思维导图如下
运行环境: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加密后的MAC
package 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
最后
以上就是辛勤老虎为你收集整理的简单视频加密与授权的全部内容,希望文章能够帮你解决简单视频加密与授权所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复