0

编程语言:Python

我有三个文件,一个是生成密钥,第二个是加密,另一个是解密..第一个和第二个文件工作..但解密文件不起作用

生成密钥文件:

from cryptography.fernet import Fernet

def generate_key():
    """
    Generates a key and save it into a file
    """
    key = Fernet.generate_key()
    with open("secret.key", "wb") as key_file:
        key_file.write(key)

generate_key()

加密文件 -

from cryptography.fernet import Fernet

def load_key():
    return open("secret.key", "rb").read()

def encrypt_message(message):
    key = load_key()
    encoded_message = message.encode()
    f = Fernet(key)
    encrypted_message = f.encrypt(encoded_message)
    
    print(encrypted_message)

    EncryptedTextWriteFile = open("encrypt.txt", "r+")
    EncryptedTextWriteFile.write(str(encrypted_message))

notEncryptedFile = open("text.txt", "r")
notEncryptedText = notEncryptedFile.read()

if __name__ == "__main__":
    encrypt_message(notEncryptedText)

notEncryptedFile.close()

解密文件 -

from cryptography.fernet import Fernet

def load_key():
    return open("secret.key", "rb").read()

def decrypt_message(encrypted_message):
    key = load_key()
    f = Fernet(key)
    decrypted_message = f.decrypt(encrypted_message)
    shit = decrypted_message.decode()

    print(shit)

    DencryptedTextWriteFile = open("decrypt.txt", "r+")
    DencryptedTextWriteFile.write(shit)

EncryptedFile = open("decrypt.txt", "r")
EncryptedText = EncryptedFile.read()

if __name__ == "__main__":
    decrypt_message(EncryptedText)

我试过的字符串 - (这个测试在 text.txt 中)

hirusha

我得到的错误:

Traceback (most recent call last):
  File "d:/development/Python/Everything/Releases/0.2/Build 02/_Releases/Encoder and Decoder/decrypt.py", line 27, in <module>
    decrypt_message(EncryptedText)
  File "d:/development/Python/Everything/Releases/0.2/Build 02/_Releases/Encoder and Decoder/decrypt.py", line 15, in decrypt_message
    decrypted_message = f.decrypt(encrypted_message)
  File "C:\Users\hirusha\AppData\Local\Programs\Python\Python38\lib\site-packages\cryptography\fernet.py", line 75, in decrypt
    timestamp, data = Fernet._get_unverified_token_data(token)
  File "C:\Users\hirusha\AppData\Local\Programs\Python\Python38\lib\site-packages\cryptography\fernet.py", line 100, in _get_unverified_token_data
    utils._check_bytes("token", token)
  File "C:\Users\hirusha\AppData\Local\Programs\Python\Python38\lib\site-packages\cryptography\utils.py", line 29, in _check_bytes
    raise TypeError("{} must be bytes".format(name))
TypeError: token must be byte
4

2 回答 2

1

问题是当您打开文件decrypt.txt 并读取文件时,它会被转换为字符串。但是 .decrypt 函数只接受字节输入。

我认为这应该可以解决您的问题:

生成一个密钥并将其存储在 key.key 文件中:

from cryptography.fernet import Fernet
def write_key():
    """
    Generates a key and save it into a file
    """
    key = Fernet.generate_key()
    with open("key.key", "wb") as key_file:
        key_file.write(key)
write_key()

加密文件并将其存储在 enc_text.txt 文件中:

from cryptography.fernet import Fernet
with open("key.key","rb") as f:
    key=f.read()
f = Fernet(key)

with open('text.txt', 'rb') as original_file:
    original = original_file.read()

encrypted = f.encrypt(original)

with open ('enc_text.txt', 'wb') as encrypted_file:
    encrypted_file.write(encrypted)

解密 enc_text.txt 文件并将输出写入 decrypt.txt

from cryptography.fernet import Fernet
with open("key.key","rb") as f:
    key=f.read()
f = Fernet(key)

with open('enc_text.txt', 'rb') as encrypted_file:
    encrypted = encrypted_file.read()

decrypted = f.decrypt(encrypted)

with open('decrypt.txt', 'wb') as decrypted_file:
    decrypted_file.write(decrypted)
于 2021-05-11T08:14:01.440 回答
0

Sujay 的答案是在我写这篇文章时发布的。这是正确的,但我仍然想发布这个,也许可以更深入地了解这意味着什么。

bytes大多数(如果不是全部)加密工具都适用于str. 这既是因为如今加密二进制(非字符串)数据更为普遍,而且因为加密算法适用于数字,并且bytesrange(0, 256).

在解密程序中,您将在这一行中加载密文:

EncryptedFile = open("decrypt.txt", "r")

将此与您加载加密密钥的方式进行对比:

def load_key():
    return open("secret.key", "rb").read()

不同之处在于 mode 参数open:如果b字符串中有 a ,则表示它以二进制模式运行,bytes而不是str. 这是一个例子:

>>> text = open('test.txt', 'r').read()
>>> text
'Hello World!\n'
>>> binary = open('test.txt', 'rb').read()
>>> binary
b'Hello World!\n'
>>> type(text)
<class 'str'>
>>> type(binary)
<class 'bytes'>

这种区别很重要,因为它str代表字符序列,并且可以以截然不同的方式将它们编码为二进制。您选择哪些将影响加密算法中的 1 和 0,从而影响结果。

尽管也在文本模式下读取明文文件,但加密程序工作的原因是因为这一行:

encoded_message = message.encode()

str.encode将字符串转换为bytes使用提供的编码,如果未指定,则使用默认编码(通常为 UTF-8)。bytes.decode在解密程序中看到的方法相反:它转换bytesstr.

>>> text = '稲妻の腕を借らん草枕'
>>> text.encode()
b'\xe7\xa8\xb2\xe5\xa6\xbb\xe3\x81\xae\xe8\x85\x95\xe3\x82\x92\xe5\x80\x9f\xe3\x82\x89\xe3\x82\x93\xe8\x8d\x89\xe6\x9e\x95'
>>> text.encode('utf-16')
b'\xff\xfe2z\xbbYn0U\x81\x920\x1fP\x890\x930I\x83\x95g'
>>> u16_data = text.encode('utf-16')
>>> u16_data.decode('utf-16')
'稲妻の腕を借らん草枕'
>>> u16_data.decode()  # this is why specifying the encoding is important
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte
于 2021-05-11T08:21:25.893 回答