如何在不使用密钥的情况下验证Fernet令牌?

2024-09-25 10:34:47 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用cryptography.fernet库加密一些小文本,当我在服务器上接收到这些文本时,我想在进行RPC解密之前验证它是否是有效的密码文本,这样服务器就可以返回数据无效。有没有一些便宜的方法来避免垃圾邮件?在

例如,如果这是我的密码:

>>> k = Fernet.generate_key()
>>> f = Fernet(k)
>>> c = f.encrypt("misingnoglic@gmail.com")
>>> c
'gAAAAABdCC4Z8fqgRu7fCv2e7cvPm46rMwTVmSJK6guR5vrnvjaCICXKI1cI-_qr3Cs_z602a4tS-sMYm_smSOzgwOJ8biVQDqlyyyt-iLcxQNCOmjBywwM='

有没有便宜的方法来验证以gAAAA开头的字符串是有效的吗?或者字符串“abcde”无效?在

谢谢!在


Tags: 数据方法key字符串文本服务器密码垃圾邮件
1条回答
网友
1楼 · 发布于 2024-09-25 10:34:47

好吧,看看the Fernet specification。Fernet令牌(这就是您所说的字符串的调用方式)的结构如下(其中表示连接):

token = urlsafe_b64encode(Version ‖ Timestamp ‖ IV ‖ Ciphertext ‖ HMAC)

HMAC是令牌的最后一部分,它使用签名密钥从初始部分(Version ‖ Timestamp ‖ IV ‖ Ciphertext计算而来(这是密钥的前半部分),如规范所述。在

问题是您没有密钥,因此您唯一能做的就是在从Base64解码后检查令牌的初始字段:

  • Version应该是0x80,这意味着版本1(同样如规范中所述)。在
  • Timestamp是与令牌相关联的时间戳:您可以检查此数字是否在特定范围内,以丢弃任何过期或格式错误的令牌。在

所以,你可以做些什么来“减少垃圾邮件”:

^{pr2}$

好处:正如我所说,如果您至少没有签名密钥(密钥的前半部分),则无法验证令牌的有效性。所以下面的内容当然不适用于您的场景,但是假设您有签名密钥。在这种情况下,除了您仍应执行的上述检查之外,您还可以执行以下操作来验证令牌的有效性:

from base64 import urlsafe_b64decode
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.hmac import HMAC
from cryptography.hazmat.backends import default_backend

bin_data = urlsafe_b64decode(c)

# Assuming you have this:
signing_key = "???" # should be urlsafe_b64decode(k)[:16]

client_data = bin_data[:-32]
client_hmac = bin_data[-32:]

print 'Client HMAC:', client_hmac.encode('hex')

real_hmac = HMAC(signing_key, hashes.SHA256(), default_backend())
real_hmac.update(client_data)
real_hmac = real_hmac.finalize()

print 'Real HMAC  :', real_hmac.encode('hex')

if client_hmac == real_hmac:
    print 'Token seems valid!'
else:
    print 'Token does NOT seem valid!'

相关问题 更多 >