Python将值存储为二进制代码

时间:2013-09-02 08:43:29

标签: python windows pyinstaller

这可能看起来像一个奇怪的问题,但我有这个想法,我想制作一个需要传递登录的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 - 但那我怎么能写入源代码?

(我的问题的可选解决方案将是如何安全地保存然后密码而不会创建太多令人害怕最终用户的模糊文件的答案)

3 个答案:

答案 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)

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


有很多方法可以存储哈希,这些方法都有优点和缺点,所以你必须仔细考虑它们。

  1. 一个简单的文件。
    • 您可以使用同一文件存储您的其他设置
    • 如果有人将您的程序安装到C:\Program Files\,您的程序可能无法在那里存储文件(但您可以使用某些标准目录,如%APPDATA%)
    • 你可以隐藏文件(但如果有人复制该程序,那么很有可能它会丢失)
  2. Windows注册表。您可以使用标准的python winreg模块。
    • 隐藏于用户
    • 没有额外的文件
    • 仅限于Windows
    • 不可移植(如果您将程序复制到另一台计算机,密码将会丢失)
  3. Append it to the executable。这是一种可能性,但在您的情况下它不起作用,因为您无法修改正在运行的可执行文件。这意味着您需要另一个程序来更改您的主程序,这将是另一个文件。因此它与使用第一个选项的文件数量相同,但工作量更大。
  4. 另一个需要注意的是,如果有人(意外)删除了您保存的密码,您可以拥有主密码后备密码。但是你应该考虑一下,因为知道主密码的人可以删除旧密码并进入你的程序。

答案 1 :(得分:3)

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

如果你编写一个抽象差异的包装类,你的应用程序代码可以统一使用它作为一个小键/值存储。或多或少的现成解决方案是in this recipekilnconfig

然后说到密码,请使用py-bcrypt安全地保留密码。

答案 2 :(得分:1)

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

  1. 制作一个文件“passwords.pwd”(Windows无法识别文件类型 - 适合虚拟用途)
  2. 不要存储密码,而是存储密码的哈希函数(您可以使用passlib或自己的方法):

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

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