简单视频加密【Version2】

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

小结

通过上面的方法,一定程度上提高了安全性

在Java中实现RSA(Rivest-Shamir-Adleman)加密算法通常涉及生成密钥对、加密数据和解密数据等步骤。这里不是一个完整的视频教程,但我可以为你概述一个简单的流程,并提供一些学习资源。 1. **安装依赖**:首先需要添加Bouncy Castle库,它是一个开源的Java实现,包含了RSA加密所需的工具。你可以通过Maven或Gradle将其作为依赖引入项目。 ```xml <!-- Maven --> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcpkix-jdk15on</artifactId> <version>1.68</version> </dependency> // Gradle implementation 'org.bouncycastle:bcpkix-jdk15on:1.68' ``` 2. **生成密钥对**:使用`java.security.KeyPairGenerator`创建RSA密钥对(公钥和私钥)。 3. **编码与解码**:使用`Cipher`类的`RSA`模式进行加解密操作。例如,将明文转换为`BigInteger`,然后用公钥加密,私钥解密。 4. **示例代码片段**: ```java import javax.crypto.Cipher; import org.bouncycastle.jce.provider.BouncyCastleProvider; public class RSAExample { static { Security.addProvider(new BouncyCastleProvider()); } public static void main(String[] args) throws Exception { KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA", "BC"); keyGen.initialize(2048); // 选择合适的密钥长度 KeyPair keyPair = keyGen.generateKeyPair(); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC"); // 加密 cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic()); byte[] encryptedData = cipher.doFinal("Hello, RSA!".getBytes()); // 解密 cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate()); String decryptedData = new String(cipher.doFinal(encryptedData)); System.out.println(decryptedData); } } ``` **相关问题--:** 1. Java中如何安全地存储和获取RSA私钥? 2. RSA加密有什么优点和缺点? 3. 如何验证接收到的RSA消息是否被篡改过?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值