在python脚本中隐藏密码(仅限不安全的混淆)

ber*_*sch 118 python security

我有一个python脚本正在创建一个ODBC连接.使用连接字符串生成ODBC连接.在此连接字符串中,我必须包含此连接的用户名和密码.

是否有一种简单的方法可以隐藏文件中的密码(只是在我编辑文件时没有人能读取密码)?

Dav*_*ebb 108

Base64编码在标准库中,可以阻止肩膀冲浪:

>>> import base64
>>>  print(base64.b64encode("password".encode("utf-8")))
cGFzc3dvcmQ=
>>> print(base64.b64decode("cGFzc3dvcmQ=").decode("utf-8"))
password
Run Code Online (Sandbox Code Playgroud)

  • 在这种情况下,我不认为`base64`比`rot13`更好地混淆.相反,`base64`具有其典型特征(等号,......),因此比其他方法更容易检测.但是,任何混淆都没有实际的好处.真的很糟糕,这个答案是这个评价很高的.它只是给人一种虚假的安全感...... (77认同)
  • base64不是加密.它充其量是模糊不清的. (16认同)
  • 如果您正在记录密码以便脚本可以使用该密码,那么任何有权访问该脚本的人都能够获取密码,无论您使用哪种加密方法.这里的要求只是隐藏在打开脚本时查看脚本的人的密码.在这种情况下,`base64`优于`rot13`,因为它在Python标准库中. (12认同)
  • 我同意.base64编码的密码看起来更加神秘. (4认同)
  • 但是,无法帮助运行它的用户必须可读的脚本,而密码则不能. (4认同)
  • 这会在Python 3中引发TypeError.这可以通过使用`base64.b64encode("password".encode('utf-8'))`和`base64.b64decode("cGFzc3dvcmQ =")来解决.decode('utf- 8' )` (4认同)
  • 真?`>>> u'abc'.encode('rot13')``'nop'.这里的问题是,在问答中不清楚这应该只是帮助那些看着你的人并可能误导他人的人. (2认同)

Mar*_*ett 50

当您需要为远程登录指定密码时,Douglas F Shearer是Unix中普遍认可的解决方案.
您可以添加--password-from-file选项以指定路径并从文件中读取明文.
然后,该文件可以位于受操作系统保护的用户自己的区域中.它还允许不同的用户自动获取自己的文件.

对于不允许脚本用户知道的密码 - 您可以使用elavated权限运行脚本,并拥有该root/admin用户拥有的密码文件.

  • 别介意我搞清楚了.对于任何关心的人:如果脚本设置了setuid位,操作系统将_'pass'_ setuid位解释为解释器.不幸的是,存在巨大的安全漏洞,因此大多数现代发行版都会关闭脚本的setuid. (4认同)
  • 在不提供 root 或管理员密码的情况下,如何以提升的权限运行脚本?与设置 UID 位有关吗? (2认同)

小智 45

这是一个简单的方法:

  1. 创建一个python模块 - 让我们称之为peekaboo.py.
  2. 在peekaboo.py中,包括密码和需要该密码的任何代码
  3. 创建一个编译版本 - peekaboo.pyc - 通过导入这个模块(通过python命令行等...).
  4. 现在,删除peekaboo.py.
  5. 你现在可以愉快地导入peekaboo仅依靠peekaboo.pyc.由于peekaboo.pyc是字节编译的,因此临时用户无法读取.

这应该比base64解码更安全 - 尽管它容易受到py_to_pyc反编译器的攻击.

  • 如果你想更进一步,你可以使用[Cython](http://cython.org/)将任何.py文件编译成C并生成一个特定于平台的二进制文件(例如:.pyd for windows ,.所以对于macOS等)...通过`cythonizing`你的脚本并共享生成的二进制文件你将得到这个答案的好处+添加另一层混淆,因为现在你已经反编译C代码来获取密码.这不是100%安全,但要获取要隐藏的敏感数据需要花费大量人力. (7认同)
  • 这仍然有一些缺点,但它实际上非常接近我想要的.它允许我演示包含用户/密码连接的python脚本,而不会在屏幕上显示密码,或者必须在命令提示符下键入它.导入peekaboo`importing peekabo`后,密码可用作`peekaboo.password`(如果peekaboo.py包含`password ='secret'`) (2认同)
  • cythonizing,完美 (2认同)

jon*_*erg 27

如果您正在使用Unix系统,请利用标准Python库中的netrc模块.它从单独的文本文件(.netrc)中读取密码,该文件具有此处描述的格式.

这是一个小用法示例:

import netrc

# Define which host in the .netrc file to use
HOST = 'mailcluster.loopia.se'

# Read from the .netrc file in your home directory
secrets = netrc.netrc()
username, account, password = secrets.authenticators( HOST )

print username, password
Run Code Online (Sandbox Code Playgroud)


tdu*_*ehr 19

假设用户在运行时无法提供用户名和密码的最佳解决方案,可能是一个单独的源文件,仅包含导入主代码的用户名和密码的变量初始化.凭据更改时,只需要编辑此文件.否则,如果您只担心具有平均记忆的肩膀冲浪者,基本64编码可能是最简单的解决方案.ROT13太容易手动解码,不区分大小写并且在加密状态下保留太多含义.在python脚本之外编码您的密码和用户ID.他是否在运行时进行脚本解码以供使用.

为自动化任务提供脚本凭据始终是一个冒险的提议.您的脚本应该有自己的凭据,并且它使用的帐户应该没有其他所需的访问权限.至少密码应该很长而且是随机的.

  • 这听起来不错,但你能举一个例子实现吗?现在它只是对一般做法的描述,对于以前没有这样做过的人来说并没有那么有用。 (3认同)

Dou*_*rer 17

如何从脚本外部的文件导入用户名和密码?这样即使有人掌握了脚本,他们也不会自动获取密码.


tzo*_*zot 15

base64是满足您简单需求的方法.无需导入任何内容:

>>> 'your string'.encode('base64')
'eW91ciBzdHJpbmc=\n'
>>> _.decode('base64')
'your string'
Run Code Online (Sandbox Code Playgroud)

  • Base64只增加了安全的幻觉. (18认同)
  • 乔纳森,好像你没有读过这个问题.这是关于_obscurity_(和一个非常临时的),而不是_security_,所以我不明白为什么你认为我的答案没有帮助. (12认同)
  • 傻到底究竟是什么?!整个回复,还是非进口部分? (2认同)
  • @Dennis 使用 base64 模块是当今的首选方式。后者在较新版本的 Python 中不再起作用。 (2认同)

jit*_*ter 5

for python3 obfuscation using base64 is done differently:

import base64
base64.b64encode(b'PasswordStringAsStreamOfBytes')
Run Code Online (Sandbox Code Playgroud)

which results in

b'UGFzc3dvcmRTdHJpbmdBc1N0cmVhbU9mQnl0ZXM='
Run Code Online (Sandbox Code Playgroud)

note the informal string representation, the actual string is in quotes

and decoding back to the original string

base64.b64decode(b'UGFzc3dvcmRTdHJpbmdBc1N0cmVhbU9mQnl0ZXM=')
b'PasswordStringAsStreamOfBytes'
Run Code Online (Sandbox Code Playgroud)

to use this result where string objects are required the bytes object can be translated

repr = base64.b64decode(b'UGFzc3dvcmRTdHJpbmdBc1N0cmVhbU9mQnl0ZXM=')
secret = repr.decode('utf-8')
print(secret)
Run Code Online (Sandbox Code Playgroud)

for more information on how python3 handles bytes (and strings accordingly) please see the official documentation.


小智 5

我这样做的方法如下:

在 python 外壳中:

>>> from cryptography.fernet import Fernet
>>> key = Fernet.generate_key()
>>> print(key)
b'B8XBLJDiroM3N2nCBuUlzPL06AmfV4XkPJ5OKsPZbC4='
>>> cipher = Fernet(key)
>>> password = "thepassword".encode('utf-8')
>>> token = cipher.encrypt(password)
>>> print(token)
b'gAAAAABe_TUP82q1zMR9SZw1LpawRLHjgNLdUOmW31RApwASzeo4qWSZ52ZBYpSrb1kUeXNFoX0tyhe7kWuudNs2Iy7vUwaY7Q=='
Run Code Online (Sandbox Code Playgroud)

然后,使用以下代码创建一个模块:

from cryptography.fernet import Fernet

# you store the key and the token
key = b'B8XBLJDiroM3N2nCBuUlzPL06AmfV4XkPJ5OKsPZbC4='
token = b'gAAAAABe_TUP82q1zMR9SZw1LpawRLHjgNLdUOmW31RApwASzeo4qWSZ52ZBYpSrb1kUeXNFoX0tyhe7kWuudNs2Iy7vUwaY7Q=='

# create a cipher and decrypt when you need your password
cipher = Fernet(key)

mypassword = cipher.decrypt(token).decode('utf-8')
Run Code Online (Sandbox Code Playgroud)

完成此操作后,您可以直接导入 mypassword,也可以根据需要导入令牌和密码以进行解密。

显然,这种方法有一些缺点。如果某人同时拥有令牌和密钥(就像他们拥有脚本一样),他们就可以轻松解密。但是它确实会混淆,如果您编译代码(使用 Nuitka 之类的东西),至少您的密码不会在十六进制编辑器中显示为纯文本。