Files
HaiNaOSLenovo/py/encryption_video.py
tongtongstudio c5980c419a version:
bugfixes:
update:增加python加密
2026-02-06 18:32:02 +08:00

182 lines
6.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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()