IscInfo.ini文件非常容易被修改,所以想出了一个解决办法
在将.k文件转化为.avi格式时,文件流是打开的,此时我们可以修改.k文件尾部的授权次数信息,每次打开视频前检测剩余几次授权,这样就不需要IscInfo.ini这个文件了
加密部分
1、MAC.java不变,获取本地MAC地址
2、MD5.java 略微修改,使之可以加密所有传入的字符串,比如授权次数
//对MAC地址进行MD5加密,生成32位字符串
//提供一个方法String getMD5()
//返回经过MD5加密后的MAC
package org.tree.enc;
import java.security.MessageDigest;
public class MD5 {
//能够加密所有传入的字符串
public String getMD5(String mac){
String RawMessage = null;
String MD5Message = null;
try{
RawMessage = mac;
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添加进视频尾部后,再加入授权次数,使后64位都是加密信息
//加密视频,在视频末尾添加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(new Mac().getMac()).getBytes());
//在尾部添加进授权信息
out.write(new MD5().getMD5("10").getBytes());
}
catch(Exception e){
e.printStackTrace();
}
finally{
if(in != null){
in.close();
}
if(out != null){
out.close();
}
}
}
}
4、UI.java GUI部分不变
解密部分:
1、MAC.java
同加密部分
2、MD5.java
同加密部分 使之加密所有字符串
3、DecVideo.java
不仅提取出视频尾部MAC,也提取出授权次数
//提取视频中MAC
//提供一个方法 String getMacMD5(String path)
//返回视频中的MAC path:要打开的加密文件的路径
//返回视频尾部的授权次数
package org.tree.pla;
import java.io.RandomAccessFile;
public class DecVideo {
//提取视频内Mac信息
public String getMacMD5(String path){
String VideoMD5 = null;
try(RandomAccessFile raf = new RandomAccessFile(path, "r")){
long len = raf.length();
raf.seek(len-64);
byte[] b = new byte[32];
raf.read(b);
VideoMD5 = new String(b);
}
catch(Exception e){
e.printStackTrace();
}
return VideoMD5;
}
//提取视频内授权次数信息
public String getVideoCount(String path){
String VideoCount = null;
try(RandomAccessFile raf = new RandomAccessFile(path, "r")){
long len = raf.length();
raf.seek(len-32);
byte[] b = new byte[32];
raf.read(b);
VideoCount = new String (b);
}
catch(Exception e){
e.printStackTrace();
}
return VideoCount;
}
}
4、PlayVideo.java
不仅比较MAC, 还要比较剩余授权次数,且如果满足播放条件 ,剩余授权次数-1重新写入视频尾部
//播放视频
//提供两个方法 boolean CompareMD5(String path)
//比较视频中的MAC与本地MAC
//void Player(Sting path)
//播放视频
//提供一个类变量 int count 用来标识剩余授权次数
package org.tree.pla;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.RandomAccessFile;
import java.util.ArrayList;
public class PlayVideo {
//存储MD5加密后的0-10数字用于比较剩余授权次数
public static ArrayList<String> ComList = new ArrayList<>();
public static void init(){
for(int i = 0 ; i <= 10 ; i ++){
ComList.add(new MD5().getMD5(i+""));
}
}
//比较视频中MAC与本地MAC
public boolean CompareMacMD5(String path){
String VideoMD5 = new DecVideo().getMacMD5(path);
String localMD5 = null;
try{
localMD5 = new MD5().getMD5(new Mac().getMac());
}
catch(Exception e){
e.printStackTrace();
}
if(VideoMD5.equals(localMD5)){
return true;
}
else{
return false;
}
}
//获取剩余授权次数
public int CompareCountMD5(String path){
String VideoCount = new DecVideo().getVideoCount(path);
return ComList.indexOf(VideoCount);
}
public void Player(String path){
if(new PlayVideo().CompareMacMD5(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();
int count = new PlayVideo().CompareCountMD5(path);
//如果剩余授权次数>0 播放且次数-1重新写入视频尾部
if(count > 0){
RandomAccessFile raf = new RandomAccessFile(path, "rw");
long len = raf.length();
raf.seek(len-32);
String result = count - 1 + "";
result = new MD5().getMD5(result);
raf.write(result.getBytes());
Process pro = Runtime.getRuntime().exec("C:\\Program Files\\Windows Media Player\\wmplayer.exe " + "C:\\tmp\\isctmp.avi");
raf.close();
}
}
catch(Exception e){
e.printStackTrace();
}
}
}
}
5、UI.java
基本不变 负责GUI
小结
通过上面的方法,一定程度上提高了安全性