如何使用 fernet 密码术修复解密功能

问题描述 投票:0回答:1

我正在尝试创建一个程序,该程序采用标题、注释和主密钥,然后使用 python 加密或解密该消息。但是,当我尝试使用 crypto_notes func 解密该消息时,它显示“解密失败。主密钥不正确”InvalidToken 错误。我该如何解决这个问题?

from tkinter import *
from tkinter import messagebox
import base64
import os
from cryptography.fernet import Fernet, InvalidToken
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC

window = Tk()
window.title("Secret Notes")
window.minsize(width=400, height=400)
window.config(padx=20, pady=20)

title_label = Label(text="Enter the Title")
title_label.config(fg="black", padx=10, pady=10)
title_label.pack()

title_entry = Entry(width=30)
title_entry.focus()
title_entry.pack()

secret_label = Label(text="Enter the Secret Message")
secret_label.config(fg="black", padx=10, pady=10)
secret_label.pack()

secret_text = Text(width=30, height=10)
secret_text.pack()

masterkey_label = Label(text="Enter the Key")
masterkey_label.config(fg="black", padx=10, pady=10)
masterkey_label.pack()

masterkey_entry = Entry(width=30, show="*")
masterkey_entry.pack()


desktop_path = os.path.join(os.path.join(os.environ['USERPROFILE']), 'Desktop')
title = title_entry.get()
secret = secret_text.get("1.0", "end-1c")
streaky = masterkey_entry.get()

def save_and_encrypt():
    title = title_entry.get()
    secret = secret_text.get("1.0", END)
    streaky = masterkey_entry.get()

    if len(title) == 0 or len(secret) == 0 or len(streaky) == 0:
        messagebox.showerror(title="Error", message="Please fill in all fields.")
    else:
        password = streaky.encode()
        salt = os.urandom(16)
        kdf = PBKDF2HMAC(
            algorithm=hashes.SHA256(),
            length=32,
            salt=salt,
            iterations=480000,
        )
        key = base64.urlsafe_b64encode(kdf.derive(password))
        f = Fernet(key)
        encrypted_text = secret.encode()
        token1 = f.encrypt(encrypted_text)


        with open(os.path.join(desktop_path, "encrypted_notes.txt"), "a") as file:
            file.write(f"Title: {title}\n")
            file.write(f"Encrypted Message: {token1}\n")
            file.write("\n")

            messagebox.showinfo(title="Completed", message="Your note has been saved and encrypted.")

def decrypt_notes():
    # Get the master key from the entry widget
    master_key = masterkey_entry.get()

    # Read the encrypted notes from the file
    with open(os.path.join(desktop_path, "encrypted_notes.txt"), "r") as file:
        lines = file.readlines()

    # Iterate through lines to find the encrypted message corresponding to the title
    encrypted_message = None
    for i in range(0, len(lines), 3):  # Assuming each note is 3 lines (title, encrypted message, blank line)
        title_line = lines[i]
        if title_line.strip() == f"Title: {title}":
            encrypted_message_line = lines[i + 1]
            encrypted_message = encrypted_message_line.split("Encrypted Message: ")[1].strip()
            break

    if encrypted_message is None:
        messagebox.showerror(title="Error", message="Note not found.")
        return

    # Decode the master key and decrypt the message
    try:
        password = master_key.encode()
        salt = os.urandom(16)
        kdf = PBKDF2HMAC(
            algorithm=hashes.SHA256(),
            length=32,
            salt=salt,
            iterations=480000,
        )
        key = base64.urlsafe_b64encode(kdf.derive(password))
        f = Fernet(key)
        decrypted_message = f.decrypt(encrypted_message.encode()).decode()

        # Show the decrypted message
        messagebox.showinfo(title="Decrypted Message", message=decrypted_message)

    except (InvalidToken, ValueError):
        messagebox.showerror(title="Error", message="Decryption failed. Incorrect master key.")


save_button = Button(text="Save & Encrypt",command=save_and_encrypt)
save_button.config(padx=1, pady=1)
save_button.pack(padx=(10, 0), pady=(10, 0))

decrypt_button = Button(text="Decrypt",command=decrypt_notes)
decrypt_button.config(padx=1, pady=1)
decrypt_button.pack(padx=(10, 0), pady=(10, 0))

window.mainloop()

不幸的是,我找不到解决方案

python tkinter encryption cryptography
1个回答
0
投票

有几个问题:

  • 使用不同的盐将创建不同的用于加密和解密的主密钥。使用相同的盐。
  • token1
    里面的
    save_and_encrypt()
    应该是字符串而不是字节
  • title
    应该读在里面
    decrypt_notes()

所需更改:

...

# don't need to get the values here as they are all empty strings
#title = title_entry.get()
#secret = secret_text.get("1.0", "end-1c")
#streaky = masterkey_entry.get()

# create the salt
salt = b'some.secret.salt'

def save_and_encrypt():
    ...
    else:
        ...
        #salt = os.urandom(16)  # don't generate random salt here
        ...
        token1 = f.encrypt(encrypted_text).decode() # make token1 a string, not bytes
        ...
    ...

def decrypt_notes():
    # read title here
    title = title_entry.get()
    ...

    try:
        ...
        #salt = os.urandom(16)   # don't generate random salt here
        ...

    ...
© www.soinside.com 2019 - 2024. All rights reserved.