首页 > 解决方案 > InvalidToken cryptography.fernet.InvalidToken

问题描述

尽管以前曾提出过类似类型的问题,但似乎没有答案对我有用。

我使用cryptography库来加密字符串,然后将该加密字符串保存在 MySQL 数据库中。然后我从数据库中获取了加密的字符串并尝试对其进行解密,但它显示以下错误。错误的原因是,storedfernet_key总是在每次运行 .py 文件时生成相同原始字符串的新加密字符串。例如:

如果我将“prakash”作为原始字符串给出,那么fernet_key将在每次运行程序时将其加密为不同的字符串。如何更改这一点,以便fernet_key只为每个唯一的原始字符串生成一个加密字符串?

Traceback (most recent call last):
  File "D:\Anaconda\envs\tensorflow\lib\site-packages\cryptography\fernet.py", line 102, in _get_unverified_token_data
    data = base64.urlsafe_b64decode(token)
  File "D:\Anaconda\envs\tensorflow\lib\base64.py", line 133, in urlsafe_b64decode
    return b64decode(s)

  File "D:\Anaconda\envs\tensorflow\lib\base64.py", line 87, in b64decode
    return binascii.a2b_base64(s)
binascii.Error: Invalid base64-encoded string: number of data characters (1) cannot be 1 more than a multiple of 4

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:/Users/Acer/OneDrive/Desktop/FYP/fyp/dummy.py", line 696, in <module>
    print(f.decrypt(bytes(passwdnw[0][0], "utf-8")))
  File "D:\Anaconda\envs\tensorflow\lib\site-packages\cryptography\fernet.py", line 75, in decrypt
    timestamp, data = Fernet._get_unverified_token_data(token)
  File "D:\Anaconda\envs\tensorflow\lib\site-packages\cryptography\fernet.py", line 104, in _get_unverified_token_data
    raise InvalidToken
cryptography.fernet.InvalidToken

为了运行下面的代码,你必须安装像这样的库mysql-connectorcryptography

我的代码:

from cryptography.fernet import Fernet
import base64, pickle
import mysql.connector as db

# This part of code is only used once for generating a specific key
# key is generated
fernet_key = Fernet.generate_key()
file = open("key.key", "wb")  # Open the file as wb to write bytes
file.write(fernet_key)  # The key is type bytes still
file.close()

file = open("key.key", "rb")  # Open the file as wb to read bytes
fernet_key = file.read()  # The key will be type bytes
file.close()

name = "Prakash"

f = Fernet(fernet_key)
encrypted = f.encrypt(name.encode())


try:
    conn = db.connect(host="localhost", user="root", password="")
    cur = conn.cursor()
    cur.execute("create database enc")
    cur.close()
    conn.commit()
    conn.close()
except:
    pass

conn = db.connect(host="localhost", user="root", password="", database="enc")
cur = conn.cursor()
cur.execute("create table if not exists encod(pwd varchar(50), encpass varchar(250))")
cur.close()
conn.commit()
conn.close()


conn = db.connect(host="localhost", user="root", password="", database="enc")
cur = conn.cursor()
cur.execute("insert into encod(pwd, encpass) values(%s,%s)", (name, encrypted))
cur.close()
conn.commit()
conn.close()


conn = db.connect(host="localhost", user="root", password="", database="enc")
cur = conn.cursor()
cur.execute("select encpass from encod")
passwdnw = cur.fetchall()
cur.close()
conn.commit()
conn.close()

print(name)
print(encrypted)
print(passwdnw[0][0])

输出:

Prakash
b'gAAAAABgZTs_Oyt5Ea5pboOKF2QRF8MRdhbFx5O9QidYcZu_D8zmOQK0ESwGYErfYXm9Cc7z9x_wk8uHYkr99C92agXfGQq1gA=='
b'gAAAAABgZTnhucw-49tuPVKfA-R6J-as3XEiDbASOb1wS3z4XCOlUlY8TGfnXZjDCwO8yEghqVH4w9CEqBenBJiwtXx3zUuJZA=='

如您所见,同一字符串有两种不同的加密形式,第一个在每次运行时都会更改,而第二个保持不变,因为它是从数据库中获取的。

标签: pythonmysqlencryptioncryptography

解决方案


推荐阅读