-1

这似乎是一个奇怪的问题,但我有一个想法,我想制作一个需要通过登录的 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 - 但是我将如何写入源代码?

(我的问题的可选解决方案是回答如何安全地保存密码,而不会创建太多会吓到最终用户的晦涩文件)

4

3 回答 3

4

AFAIK 在代码成为可执行文件后无法修改代码,您可以简单地将密码作为哈希值存储在一个文件中(方法 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 文档复制的示例:

# 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)

如您所见,哈希和验证非常简单,您可以根据需要配置各种参数。


存储哈希的方法有很多种,各有利弊,因此您必须仔细考虑它们。

  1. 一个简单的文件。
    • 您可以使用相同的文件来存储程序的其他设置
    • 如果有人将您的程序安装到C:\Program Files\您的程序中,则可能无权在其中存储文件(但您可以使用一些标准目录,如 %APPDATA%)
    • 您可以隐藏文件(但如果有人复制该程序很有可能会丢失)
  2. Windows 注册表。您可以使用标准的 python winreg模块。
    • 对用户隐藏
    • 没有额外的文件
    • 仅在窗户上
    • 不可移植(如果您将程序复制到另一台计算机,密码将丢失)
  3. 将其附加到可执行文件。这是一种可能性,但它不适用于您的情况,因为您无法修改正在运行的可执行文件。这意味着您将需要另一个程序来更改您的主程序,这将是另一个文件。因此,它与使用第一个选项的文件数量相同,但工作量更大。

另一个需要注意的是,如果有人(不小心)删除了您保存的密码,您可能会拥有主密码备用密码。但是您应该考虑一下,因为知道主密码的人可以删除旧密码并进入您的程序。

于 2013-09-18T15:32:11.640 回答
3

正如您已经注意到的那样,在代码中存储数据比它解决的问题更多。存储“隐藏”配置的方法是在 Windows 下使用_winreg(或winreg在 py3 中),以及在 Linux 和其他 POSIX 系统下ConfigParser使用文件。~/.config/myapp.ini但是,大多数人也在%APPDATA%Windows下使用.INI文件,这已经足够隐藏了。

如果您编写一个抽象出差异的包装类,您的应用程序代码可以将其统一用作小型键/值存储。这个秘籍和kilnconfig中或多或少是现成的解决方案。

然后,当涉及到密码时,请使用py-bcrypt安全地保存它们。

于 2013-09-17T20:59:31.817 回答
1

永远永远永远不要存储密码!!!这只是不安全!请改用以下方法:

  1. 创建一个文件“passwords.pwd”(windows 将无法识别文件类型 - 适合虚拟用户)
  2. 不要存储密码,而是密码的哈希函数(您可以使用例如passlib或执行您自己的方法):

    import hashlib
    password = "12345" #take user input here
    hashed_password = hashlib.sha512(password).hexdigest()
    print hashed_password
    

    每当您必须验证密码时,只需进行上述计算并将结果与​​存储的哈希值进行比较。

于 2013-09-19T19:03:00.730 回答