这可能看起来像一个奇怪的问题,但我有这个想法,我想制作一个需要传递登录的python脚本。用户应该能够在程序开头输入所需的传递,然后代码会将其写入实际的源代码中(因此不会生成额外的文件)。
我知道通过做这样的事情可以做到这一点
with open('test.py','a') as f:
f.write('\nprint "hello world"')
运行此脚本3次将生成以下代码
with open('test.py','a') as f:
f.write('\nprint "hello world"')
print "hello world"
print "hello world"
print "hello world"
但我想让我的python脚本适用于没有安装python的每台Windows机器。所以我必须使用PyInstaller - 但那我怎么能写入源代码?
(我的问题的可选解决方案将是如何安全地保存然后密码而不会创建太多令人害怕最终用户的模糊文件的答案)
答案 0 :(得分:4)
AFAIK在可执行文件之后无法修改代码,但只需将密码存储为hash 即可在一个文件中存储(方法A)或更好地使用特殊模块(方法B)。 您绝不应将密码以纯文本形式存储在任何地方(即使不在可执行文件中)
方法A(如果不能使用其他库,则仅使用此方法)
代码可能如下所示:
# To create the password file (e.g. change password)
import hashlib
with open('password', 'wb') as f:
p = 'new password'
f.write(hashlib.sha512(p.encode('utf-8')).digest()) # hash and save password
# To check the password
import hashlib
with open('password', 'rb') as f:
p_in = # your method to read get the password from the user
p = hashlib.sha512(p_in.encode('utf-8')).digest() # create hash
if p == f.read(): # verify hash (password)
# right password
else:
# wrong password
文件的内容是哈希的二进制形式 需要注意的一件重要事情是,您应该使用安全散列函数(查看上面链接的文章)或者更好地使用方法B.
方法B(你应该使用它)
这是一种更安全,更简单的版本(如user9876所指出的),它使用了库passlib来实现这些目的。
这是从passlib documentation:
# import the context under an app-specific name (so it can easily be replaced later)
from passlib.apps import custom_app_context as pwd_context
# encrypting a password...
hash = pwd_context.encrypt("somepass")
# verifying a password...
ok = pwd_context.verify("somepass", hash)
正如您所看到的,哈希和验证非常简单,您可以根据需要配置各种参数。
有很多方法可以存储哈希,这些方法都有优点和缺点,所以你必须仔细考虑它们。
C:\Program Files\
,您的程序可能无法在那里存储文件(但您可以使用某些标准目录,如%APPDATA%)另一个需要注意的是,如果有人(意外)删除了您保存的密码,您可以拥有主密码或后备密码。但是你应该考虑一下,因为知道主密码的人可以删除旧密码并进入你的程序。
答案 1 :(得分:3)
正如您已经注意到的,在代码中存储数据比解决的问题更多。存储“隐藏”配置的方法是在Windows下使用_winreg
(或py3中的winreg
,并在Linux和其他POSIX系统下使用ConfigParser
作为~/.config/myapp.ini
文件。但是,大多数人在Windows下使用%APPDATA%
中的.INI文件,这已经足够隐藏了。
如果你编写一个抽象差异的包装类,你的应用程序代码可以统一使用它作为一个小键/值存储。或多或少的现成解决方案是in this recipe和kilnconfig。
然后说到密码,请使用py-bcrypt安全地保留密码。
答案 2 :(得分:1)
永远不要存储密码!这只是不安全! 请改用以下方法:
不要存储密码,而是存储密码的哈希函数(您可以使用passlib或自己的方法):
import hashlib
password = "12345" #take user input here
hashed_password = hashlib.sha512(password).hexdigest()
print hashed_password
每当您必须验证密码时,只需执行上述计算并将结果与标记的哈希值进行比较。