gpt4 book ai didi

python - 如何在不使用 key 的情况下验证 Fernet token ?

转载 作者:行者123 更新时间:2023-12-01 00:45:48 28 4
gpt4 key购买 nike

我正在使用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”无效?

谢谢!

最佳答案

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

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

HMAC,即 token 的最后一部分,是根据初始部分(版本 ‖ 时间戳 ‖ IV ‖ 密文)使用签名 key 计算得出的(其中是 key 的前半部分),如规范中所述。

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

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

因此,您可以采取以下措施来“减少垃圾邮件”:

from base64 import urlsafe_b64decode
from struct import unpack
from datetime import datetime, timedelta

bin_token = urlsafe_b64decode(c) # <-- c is the Fernet token you received
version, timestamp = unpack('>BQ', bin_token[:9])

tok_age = datetime.now() - datetime.fromtimestamp(timestamp)
max_age = timedelta(7) # 7 days

if version != 0x80:
print 'Invalid token version!'

if tok_age > max_age:
print 'Token expired!'
elif tok_age < timedelta(0):
print 'Token timestamp in the future! Invalid token!'
<小时/>

奖励:正如我所说,如果您至少没有签名 key (即 key 的前半部分),则无法验证 token 的有效性。因此,以下内容当然不适用于您的场景,但我们假设您拥有签名 key 。在这种情况下,除了您仍然应该执行的上述检查之外,您还可以执行以下操作来验证 token 的有效性:

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!'

关于python - 如何在不使用 key 的情况下验证 Fernet token ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56997981/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com