在此功能中,我试图从文件中读取Fernet密钥,如果文件不包含密钥,则创建一个。
if ((twitterUrl ? twitterUrl.length : 0) +
(facebookUrl ? facebookUrl.length : 0) +
(linkedInUrl ? linkedInUrl.length : 0) > 0) {
我在读取文件时遇到困难。读取文件后,密钥的读取方式为:
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)
但是我收到此错误:
b'nNjpIl9Ax2LRtm-p6ryCRZ8lRsL0DtuY0f9JeAe2wG0='
在这一行:
ValueError: Fernet key must be 32 url-safe base64-encoded bytes.
任何帮助将不胜感激。
答案 0 :(得分:2)
这里的问题是密钥是如何写入文件的。
Fernet.generate_key()
返回一个bytes
实例:
>>> key = Fernet.generate_key()
>>> key
b'ZmDfcTF7_60GrrY167zsiPd67pEvs0aGOv2oasOM1Pg='
密钥正按原样写入文件中
>>> with open('keys.csv', 'w+') as f:
... headers = ['key']
... writer = csv.DictWriter(f, fieldnames=headers)
... writer.writeheader()
... writer.writerow({'key': key})
...
49
>>>
如果我们查看文件,则可以看到内容与预期不符-表示已将python字节串写入文件的b
:
$ cat keys.csv
key
b'ZmDfcTF7_60GrrY167zsiPd67pEvs0aGOv2oasOM1Pg='
csv.writer
对尚未为字符串的任何值调用str
。如果在str
实例上调用bytes
,则会得到字节实例的字符串化的 repr ,而不是bytes
实例的解码值想要。
>>> str(key)
"b'ZmDfcTF7_60GrrY167zsiPd67pEvs0aGOv2oasOM1Pg='" # <- note the extra quotes...
>>> key.decode('utf-8')
'ZmDfcTF7_60GrrY167zsiPd67pEvs0aGOv2oasOM1Pg='
因此解决方案是在bytes
之前调用decode
实例的csv.writer
方法
收到。
>>> 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
>>>
这为我们提供了所需的文件内容:
$ 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()
会这样做) 。如果对象是字符串,则尤其如此。例如:
>>> 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