bugfixes:
update:增加python加密
This commit is contained in:
2026-02-06 18:32:02 +08:00
parent d5ba38e04e
commit c5980c419a

182
py/encryption_video.py Normal file
View File

@@ -0,0 +1,182 @@
import tkinter as tk
from tkinter import filedialog, messagebox, ttk
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from Crypto.Random import get_random_bytes
import os
import base64
class VideoEncryptorGUI:
def __init__(self, master):
self.master = master
master.title("视频加密工具")
master.geometry("500x400")
self.input_file_path = None
# 创建GUI组件
self.label_title = tk.Label(master, text="视频文件加密工具", font=("Arial", 14, "bold"))
self.label_title.pack(pady=10)
self.btn_select = tk.Button(master, text="选择视频文件", command=self.select_file, width=20, height=2)
self.btn_select.pack(pady=5)
self.label_file = tk.Label(master, text="未选择文件", wraplength=400)
self.label_file.pack(pady=5)
# Key输入
self.label_key = tk.Label(master, text="AES密钥 (Base64编码或16/24/32字节字符串):")
self.label_key.pack(pady=(10,0))
self.entry_key = tk.Entry(master, width=50, show="*")
self.entry_key.pack(pady=5)
# IV输入
self.label_iv = tk.Label(master, text="初始化向量IV (Base64编码或16字节字符串):")
self.label_iv.pack(pady=(10,0))
self.entry_iv = tk.Entry(master, width=50)
self.entry_iv.pack(pady=5)
# 生成随机Key和IV按钮
self.btn_generate = tk.Button(master, text="生成随机密钥和IV", command=self.generate_key_iv, width=20)
self.btn_generate.pack(pady=5)
# 加密按钮
self.btn_encrypt = tk.Button(master, text="加密文件", command=self.encrypt_video, width=20, height=2, bg="#4CAF50", fg="white")
self.btn_encrypt.pack(pady=10)
self.status_label = tk.Label(master, text="", fg="blue")
self.status_label.pack(pady=5)
# 说明文本
help_text = "说明:输出文件将与输入文件同目录,扩展名为.hnv"
self.label_help = tk.Label(master, text=help_text, fg="gray", font=("Arial", 9))
self.label_help.pack(pady=10)
def select_file(self):
"""选择要加密的文件"""
file_path = filedialog.askopenfilename(
title="选择视频文件",
filetypes=[("视频文件", "*.mp4 *.avi *.mov *.mkv"), ("所有文件", "*.*")]
)
if file_path:
self.input_file_path = file_path
self.label_file.config(text=file_path)
self.status_label.config(text="文件已选择,请设置密钥")
def generate_key_iv(self):
"""生成随机的密钥和IV"""
# 生成随机密钥32字节AES-256和IV16字节
key = get_random_bytes(32)
iv = get_random_bytes(16)
# 转换为Base64编码字符串显示在输入框中
key_b64 = base64.b64encode(key).decode('utf-8')
iv_b64 = base64.b64encode(iv).decode('utf-8')
self.entry_key.delete(0, tk.END)
self.entry_key.insert(0, key_b64)
self.entry_iv.delete(0, tk.END)
self.entry_iv.insert(0, iv_b64)
self.status_label.config(text="已生成随机密钥和IV请妥善保存")
def encrypt_video(self):
"""加密视频文件"""
if not self.input_file_path:
messagebox.showerror("错误", "请先选择要加密的文件")
return
key_str = self.entry_key.get().strip()
iv_str = self.entry_iv.get().strip()
if not key_str or not iv_str:
messagebox.showerror("错误", "请输入密钥和IV")
return
try:
# 处理密钥尝试Base64解码否则使用字符串编码
try:
key = base64.b64decode(key_str)
except:
key = key_str.encode('utf-8')
# 处理IV尝试Base64解码否则使用字符串编码
try:
iv = base64.b64decode(iv_str)
except:
iv = iv_str.encode('utf-8')
# 确保密钥长度为16、24或32字节
if len(key) not in [16, 24, 32]:
if len(key) < 16:
key = key.ljust(16, b'\0')
elif len(key) < 24:
key = key.ljust(24, b'\0')
elif len(key) < 32:
key = key.ljust(32, b'\0')
else:
key = key[:32]
# 确保IV长度为16字节
if len(iv) != 16:
if len(iv) < 16:
iv = iv.ljust(16, b'\0')
else:
iv = iv[:16]
# 生成输出文件路径
file_dir = os.path.dirname(self.input_file_path)
file_name = os.path.basename(self.input_file_path)
file_base = os.path.splitext(file_name)[0]
output_file = os.path.join(file_dir, f"{file_base}.hnv")
# 执行加密
self.do_encryption(self.input_file_path, output_file, key, iv)
self.status_label.config(text=f"加密成功!输出文件: {output_file}")
messagebox.showinfo("成功", f"文件加密完成!\n输出文件: {output_file}")
except Exception as e:
messagebox.showerror("加密错误", f"加密过程中发生错误: {str(e)}")
def do_encryption(self, input_path, output_path, key, iv):
"""
执行加密操作
使用AES/CBC/PKCS5Padding模式与Java代码保持一致
"""
# 读取输入文件
with open(input_path, 'rb') as f_in:
plaintext = f_in.read()
# 创建密码器
cipher = AES.new(key, AES.MODE_CBC, iv)
# 应用PKCS5填充并加密
padded_data = pad(plaintext, AES.block_size)
ciphertext = cipher.encrypt(padded_data)
# 写入输出文件
with open(output_path, 'wb') as f_out:
f_out.write(ciphertext)
def main():
# 检查所需库是否已安装
try:
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from Crypto.Random import get_random_bytes
except ImportError:
print("正在安装所需库...")
import subprocess
import sys
subprocess.check_call([sys.executable, "-m", "pip", "install", "pycryptodome"])
print("库安装完成,请重新运行程序")
return
# 创建主窗口
root = tk.Tk()
app = VideoEncryptorGUI(root)
root.mainloop()
if __name__ == "__main__":
main()