读取Fernet密钥导致ValueError:Fernet密钥必须是32个URL安全的base64编码的字节 [英] Read Fernet Key Causes ValueError: Fernet key must be 32 url-safe base64-encoded bytes
问题描述
在此功能中,我试图从文件中读取Fernet密钥,或者如果文件中不包含密钥,则创建一个.从cryptography.fernet中的
In this function I am trying to read a Fernet key from a file, or create one if the file doesn't contain a key.
from cryptography.fernet import Fernet
import csv
with open("Keys.txt","rU") as csvfile:
reader=csv.reader(csvfile)
KeyFound=0
print(KeyFound)
for row in reader:
try:
print(row[0])
except IndexError:
continue
if len(row[0])>4:
print("KEY FOUND")
KeyFound=1
print(KeyFound)
Key=row[0]
print(Key)
print(KeyFound)
else:
pass
if KeyFound==0:
Key = Fernet.generate_key()
print(Key)
print("Created Key")
csvfile.close()
#Writing Key to textfile
with open("Keys.txt", "w+") as csvfile:
headers = ['key']
writer=csv.DictWriter(csvfile, fieldnames=headers)
writer.writeheader()
writer.writerow({'key': Key})
csvfile.close()
print(Key)
Ecy = Fernet(Key)
我在读取文件时遇到困难.读取文件后,密钥的读取方式为:
I am having difficulty reading the file. When the file is read the key is read in as:
b'nNjpIl9Ax2LRtm-p6ryCRZ8lRsL0DtuY0f9JeAe2wG0='
但是我收到此错误:
ValueError: Fernet key must be 32 url-safe base64-encoded bytes.
在这一行:
Ecy = Fernet(Key)
任何帮助将不胜感激.
推荐答案
这里的问题是密钥是如何写入文件的.
The problem here is how the key is being written to the file.
Fernet.generate_key()
返回一个 bytes
实例:
>>> key = Fernet.generate_key()
>>> key
b'ZmDfcTF7_60GrrY167zsiPd67pEvs0aGOv2oasOM1Pg='
密钥正按原样写入文件中
The key is being written to the file as is:
>>> with open('keys.csv', 'w+') as f:
... headers = ['key']
... writer = csv.DictWriter(f, fieldnames=headers)
... writer.writeheader()
... writer.writerow({'key': key})
...
49
>>>
如果我们查看文件,则可以看到内容不是我们期望的-表示已将python字节串写入文件的 b
:
If we look in the file, we can see the contents aren't what we expect - the b
that indicates a python bytestring has been written to the file:
$ cat keys.csv
key
b'ZmDfcTF7_60GrrY167zsiPd67pEvs0aGOv2oasOM1Pg='
csv.writer
在尚未为字符串的任何值上调用 str
.如果在 bytes
实例上调用 str
,则会得到字节实例的字符串化的 repr ,而不是 bytes
实例,这就是您想要的 * .
csv.writer
calls str
on any values that aren't already strings. If str
is called on a bytes
instance you get the stringified repr of the bytes instances rather than the decoded value of the bytes
instance, which is what you want*.
>>> str(key)
"b'ZmDfcTF7_60GrrY167zsiPd67pEvs0aGOv2oasOM1Pg='" # <- note the extra quotes...
>>> key.decode('utf-8')
'ZmDfcTF7_60GrrY167zsiPd67pEvs0aGOv2oasOM1Pg='
因此解决方案是在 csv.writer
之前调用 bytes
实例的 decode
方法收到.
So the solution is to call the bytes
instance's decode
method before csv.writer
receives it.
>>> with open('keys.csv', 'w+') as f:
... headers = ['key']
... writer = csv.DictWriter(f, fieldnames=headers)
... writer.writeheader()
... writer.writerow({'key': key.decode('utf-8')})
...
46
>>>
这为我们提供了所需的文件内容:
This gives us the file contents that we want:
$ cat keys.csv
key
ZmDfcTF7_60GrrY167zsiPd67pEvs0aGOv2oasOM1Pg=
其余代码按预期工作:
>>> with open('keys.csv') as f:
... reader = csv.reader(f)
... next(reader) # <- skip the header row
... for row in reader:
... csv_key = row[0]
... print(Fernet(csv_key))
...
['key'] # <- the headers are printed as a side effect of skipping
<cryptography.fernet.Fernet object at 0x7f3ad62fd4e0>
一个调试技巧.使用 print()
调试代码时,有时最好打印对象的 repr ,而不是在对象上调用 str
的结果(这是 print()
做).如果对象是字符串,则尤其如此.例如:
One debugging tip. When using print()
to debug your code, it's sometimes better to print an object's repr, rather than the result of calling str
on the object (which is what print()
does). This is especially the case if the object is a string. For example:
>>> bad_key = str(key)
>>> print(bad_key)
b'ZmDfcTF7_60GrrY167zsiPd67pEvs0aGOv2oasOM1Pg=' # <- Looks ok...
>>> print(repr(bad_key))
"b'ZmDfcTF7_60GrrY167zsiPd67pEvs0aGOv2oasOM1Pg='" # <- See the problem
>>>
>>> good_str = 'foo'
>>> bad_str = 'foo '
>>> print(bad_str)
foo # <- looks like good_str
>>> print(repr(bad_str))
'foo ' # <- see the trailing space
* 如果您使用 -b
标志调用Python- python -b myscript.py
-Python将发出 BytesWarning
他是您第一次尝试在 bytes
实例上调用 str
时.如果使用 -bb
标志,则会引发异常.
* If you call Python with the -b
flag - python -b myscript.py
- Python will emit a BytesWarning
he first time you try to call str
on a bytes
instance. If the -bb
flag is used, an exception will be raised.
这篇关于读取Fernet密钥导致ValueError:Fernet密钥必须是32个URL安全的base64编码的字节的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!