无影无踪的青蛙 2024-11-17 18:00 采纳率: 100%
浏览 6
已结题

新文件格式定义与解密失败报错

from cryptography.fernet import Fernet
import os
import tkinter as tk
from tkinter import filedialog, messagebox

# 生成密钥
def generate_key():
    return Fernet.generate_key()

# 加密函数
def encrypt(key, plaintext):
    f = Fernet(key)
    encrypted = f.encrypt(plaintext.encode('utf-8'))
    return encrypted

# 解密函数
def decrypt(key, encrypted):
    f = Fernet(key)
    decrypted = f.decrypt(encrypted)
    return decrypted.decode('utf-8')

# 写入 .opika 文件
def write_opika_file(filename, key, content):
    encrypted_content = encrypt(key, content)
    with open(filename, 'wb') as file:
        file.write(b'OPIKA0001')  # 文件头
        file.write(key + b'\n')  # 写入密钥(用于解密)
        file.write(encrypted_content)  # 写入加密内容

# 读取 .opika 文件
def read_opika_file(filename):
    with open(filename, 'rb') as file:
        header = file.read(10)  # 读取文件头
        if header != b'OPIKA0001':
            raise ValueError(f'Invalid file format. 读取到: {header}')
        
        key = file.readline().strip()  # 读取密钥并去掉换行符
        encrypted_content = file.read()  # 读取加密内容
        return key, decrypt(key, encrypted_content)

# 主函数
def main():
    # 创建主窗口
    root = tk.Tk()
    root.withdraw()  # 隐藏主窗口

    # 输入明文
    content = input("请输入需要加密的文本: ")

    # 选择文件保存路径
    output_file = filedialog.asksaveasfilename(defaultextension=".opika", filetypes=[("OPIKA files", "*.opika"), ("All files", "*.*")])
    
    if output_file:
        key = generate_key()  # 生成密钥
        write_opika_file(output_file, key, content)
        messagebox.showinfo("成功", f"文件已保存为 {output_file}。")

        # 打开并读取文件以解密内容
        key, decrypted_content = read_opika_file(output_file)
        print("解密后的内容:", decrypted_content)
    else:
        print("未选择文件,操作取消。")

if __name__ == '__main__':
    main()


这段有什么问题啊, 报错了:

Traceback (most recent call last):
  File "/Users/opika/opika file.py", line 63, in <module>
    main()
  File "/Users/opika/opika file.py", line 57, in main
    key, decrypted_content = read_opika_file(output_file)
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/opika/opika file.py", line 34, in read_opika_file
    assert header == b'OPIKA0001', 'Invalid file format.'
           ^^^^^^^^^^^^^^^^^^^^^^
AssertionError: Invalid file format.

Mac系统, 无虚拟环境, VSCode

  • 写回答

1条回答 默认 最新

  • 关注

    以下回复参考:皆我百晓生券券喵儿等免费微信小程序作答:

    从报错信息来看,问题出现在 read_opika_file 函数中的断言语句。你在读取文件头后进行了比较操作,但是似乎没有正确地处理文件读取和密钥读取的逻辑。具体来说,你在读取密钥时使用了 file.readline().strip(),这可能会读取到密钥前的换行符或其他字符,导致密钥不正确。另外,文件头读取的长度也可能不正确。以下是修改后的代码:

    # ... 其他代码保持不变 ...
    
    # 读取 .opika 文件
    def read_opika_file(filename):
        with open(filename, 'rb') as file:
            header = file.read(8)  # 修改文件头读取长度
            if header != b'OPIKA001':  # 确保与定义的文件头匹配
                raise ValueError(f'Invalid file format. 读取到: {header}')
            
            key_line = file.readline().strip()  # 读取密钥行并去掉换行符
            key = key_line.decode('utf-8')  # 将字节转换为字符串以解密密钥
            encrypted_content = file.read()  # 读取加密内容
            return key, decrypt(key, encrypted_content)  # 返回密钥和解密后的内容
    
    # ... 其他代码保持不变 ...
    

    注意以下几点修改:

    1. 文件头读取长度修改为 8(假设你的文件头固定为 b'OPIKA0001' 这样的字符串)。确保与你在写入文件时使用的格式匹配。
    2. 在读取密钥行后,使用 decode('utf-8') 将字节转换为字符串以用于解密密钥。这确保你使用的密钥是字符串类型,而不是字节类型。
    3. 在使用断言之前,确保文件头的格式和预期匹配。如果不匹配,引发一个明确的错误消息。由于断言主要用于开发和调试,在实际应用中可能需要使用更友好的错误处理机制来告知用户。这里我直接使用了 ValueError 异常来报告问题。
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 12月2日
  • 已采纳回答 11月24日
  • 创建了问题 11月17日