【问题标题】:Fixing Invalid signature when decrypting fernet token修复解密 fernet 令牌时的无效签名
【发布时间】:2019-04-27 23:31:23
【问题描述】:

我对 pyhton 和密码学模块比较陌生,所以我正在尝试学习加密和解密的基础知识。 当我加密文件并在同一个程序上解密时,一切正常,但如果我尝试只在预加密文件上运行解密代码(我当然使用相同的密钥),我会收到 InvalidSignature 错误,然后通过 InvalidToken。

现在,我假设由于某种原因密钥不匹配,但它们确实是相同的。 然后我认为由于某种原因我将字符串而不是字节传递给函数,或者存在某种可能会改变加密消息的转换错误。但是加密解密代码有效,所以我不明白为什么只解密应该面临错误。 最后,我查看了解密函数的源代码,并试图弄清楚时间戳是否与我得到的错误有关,但由于我没有太多经验,所以我无法得到任何相关信息. 这是加密-解密代码:给定用户密码,它会加密并打印一个文件,该文件可以立即解密。

import base64
import os
from cryptography.fernet import Fernet
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC

print("Insert password: ")
password_str = input()
password = password_str.encode()
salt = os.urandom(16)

kdf = PBKDF2HMAC(algorithm=hashes.SHA256(), length=32, salt=salt, 
iterations=100000, backend=default_backend())

key = base64.urlsafe_b64encode(kdf.derive(password))
f = Fernet(key)

message = "A really secret message. Not for prying eyes.".encode()
token = f.encrypt(message)

file = open("text_encrypted.txt", "wb")
file.write(token)
file.close()

file = open("text_encrypted.txt", "rb")
data = file.read()
file.close()

token = f.decrypt(data)

file = open("text_decrypted.txt", "wb")
file.write(token)
file.close()

现在,它工作得很好,我得到了包含加密和解密消息的两个文件。 如果我删除:

message = "A really secret message. Not for prying eyes.".encode()
token = f.encrypt(message)

file = open("text_encrypted.txt", "wb")
file.write(token)
file.close()

部分,我应该只剩下一个解密代码,它应该适用于以前生成的加密文件,应该用相同的密码解密。

我显然遗漏了一些可能微不足道的东西,因为它会引发无效签名和无效令牌。 感谢您的帮助

【问题讨论】:

    标签: python cryptography


    【解决方案1】:

    您使用的加密密钥是 PBKDF2 的结果。为了让 PBKDF2 返回相同的加密密钥,它必须获得完全相同的参数。这包括盐,在您的示例中,盐是每次随机生成的。

    您需要将生成的盐与加密文件一起存储,以便以后能够解密。

    【讨论】:

    • 你说的很对,我没注意随机生成器。我很傻,因为这是我知道的事情,但出于某种原因,我开始考虑更多奇特的问题。无论如何,在寻找不匹配的密钥时,我走在了正确的轨道上,但是我(错误地)排除了该选项对于其他任何人:基本上 urandom 没有“种子”,因此每次都会生成不同的盐。另一方面,带有种子的随机函数在调用时总是产生相同的伪随机数集,因此它应该产生相同的盐。谢谢安德鲁!
    • @MarcoR 明确一点:使用 urandom 是正确的方法,盐需要由 CSPRNG 生成。种子 PRNG 几乎肯定不是加密安全的。您应该存储和重复使用您生成的盐,它可以是数据库中的明文或附加到加密文件。
    • 对于我想到的应用程序,加盐不是那么相关,所以我什至可以避免它,但感谢您的评论,我同意种子随机数给代码带来的熵更少。我将按照您的建议存储盐,以便了解有关密码学模块的更多信息
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-16
    • 2021-06-21
    • 1970-01-01
    • 2019-08-11
    • 2021-08-10
    • 2017-05-30
    • 2017-10-15
    相关资源
    最近更新 更多