在Python中混淆字符串

10

我有一个必须传递给方法的密码字符串。一切运作良好,但我不太放心以明文形式存储密码。是否有一种方法可以混淆该字符串或真正加密它?我知道混淆可以被反向工程,但我认为我至少应该尝试一下对密码进行一些掩盖。至少它不会对索引程序或偶然看到我的代码的人显露出来。

我知道pyobfuscate,但我不想混淆整个程序,只是其中一个字符串,并可能是定义变量的整行代码。

目标平台是GNU Linux Generic(如果有区别的话)。


如果你需要真正的、正确的加密,请看一下 bcryptpy-bcrypt。要了解为什么应该使用它,请阅读 Paul Buchet 的文章,http://paulbuchheit.blogspot.com/2007/09/quick-read-this-if-you-ever-store.html。 - Cristian Ciupitu
6个回答

26

如果你只是想防止密码被偶然瞥见,可以考虑将密码编码/解码成base64格式。这样做并不安全,但密码就不会轻易被人类或机器读取。

import base64
# Encode password (must be bytes type)
encoded_pw = base64.b64encode(raw_pw)

# Decode password (must be bytes type)
decoded_pw = base64.b64decode(encoded_pw)

这是一个非常好的答案,你可以在你的代码中使用最好的超强加密——但是由于你必须在代码中存储解密密钥,所以你并没有获得任何安全性。不过你可能会轻易地自欺欺人认为你有! - Martin Beckett
1
这并不能防止真正的窥探。但它可以防止未经训练的人瞥一眼代码并说:“哦,看那个!”然后看到: password = "abc123sdfsdf" - Caedis
我喜欢更短的拼写方式password = 'c2VjcmV0'.decode('base64')但是在Python 3.0中将无法使用。 - Marius Gedminas
很多人似乎认为有某种方法可以使用这些密码来保证安全性。据我所知,除了明文或简单转换的文本之外,没有其他存储访问内部系统密码的方法。Base64是你能得到的最好的选择。 - dimo414

2
显然,你的最佳选择是将其委派给第三方。如果你可以使用其他凭据(例如,你的进程正在运行的用户帐户)进行身份验证,你可以将权限级别留给操作系统层。或者,如果足够重要/可能,你可以提示用户(将密钥存储在(可以说)稍微不容易被攻击的湿件中)。
如果你确实需要存储一些密码或密钥,我建议你将其单独存储在一个文件中,并在需要时对其进行解密。这样做有以下优点:
- 你可以尽可能地设置文件权限(即只能由你的程序运行的帐户读取),而不像程序的其余部分可能会被更多人读取。 - 你不会意外地将其提交到版本控制系统中! - 对于Python字符串而言,你不需要受到可打印字符的限制(或使用笨拙的转义),因此如果可能,你可以使用任意的密钥文件,而不仅仅是易于人类阅读的密码。如果它不是人为输入的,则没有理由具有所有密码的弱点。
为了使其不易被破解,你可以使用像base64这样的方法,或者使用自己编写的方案,例如XOR或解密与存储在其他位置的另一个键。请注意,这并不能防止除机会肩并攻击(如果有的话)以外的任何事情 - 确保有一定程度的真实安全性(包括明显的物理访问计算机等)。

1

首先,您应该避免明文存储密码。这是唯一的“真正”解决方案。

现在,您可以使用哈希模块(在Python 2.5及以下版本中使用md5和类似模块)轻松加密密码。

import hashlib
mypass = "yo"
a = hashlib.sha256(mypass).digest()

一个很酷的解决方案,但密码是明文的,因为必须以这种方式读入方法。我需要一种以混乱的方式存储密码的方法,这对于人类来说毫无意义,除非经过一些工作,但Python确切知道我在谈论什么。 - Caedis
我建议加盐。这是一个众所周知的事实,很多用户使用相同的密码。为了保护具有数据库访问权限的人不做任何相关性,您应该执行以下操作: salt = ''.join(random.choice(string.ascii_letters) for _ in range(1,5)) hashed_password = 'sha256:%s:%s' % (salt, hmac.new(salt, password, hashlib.sha256).hexdigest()) - drdaeman
哈希是单向的。一旦它被哈希,我就无法解密它。我需要将明文发送到该方法。 - Caedis
1
@caedis:在一个方法中输入明文密码并不是好的设计。很可能对其进行编码不会改变软件(糟糕)安全性太多——因为你永远不应该能够以文本形式检索密码。 - David Cournapeau
@David: 要求密码(或至少某种密钥)有时是必要的。 这里的一些答案似乎假设 Caedis 在服务器端,试图验证客户端的密码,但实际上 他的程序 是认证过程中的客户端。 有时可以通过受信任的中介来执行身份验证(例如基于进程用户凭据的操作系统身份验证)。 但是,如果唯一可用的身份验证是基于已知机密的身份验证,则客户端必须知道该机密。 - Brian
显示剩余2条评论

0

使用base64编码可以很好地混淆密码,而且不需要用户干预,但代价是不安全的。如果用户可以通过访问系统钥匙环服务进行登录,请查看keyring包。我曾在OS X和Linux系统上使用它来存储密码。


0
许多接受密码的协议和设施都有指定密钥文件而不是密码的方法。这种策略在这里可能很有用;与其硬编码一个密码,不如硬编码一个文件名(或者更好的办法是将其作为参数!)。你甚至可以像SSH那样进一步做到拒绝加载那些不属于当前用户的、只能被该用户读取的密钥文件。

在这种情况下,我无法使用密钥文件。 - Caedis

0

这很大程度上取决于您为什么要保留密码以及您认为存在安全问题的地方。

如果您将来要将此密码存储或与数据库匹配:

这不应该是一个问题,但如果您担心,可以提前使用数据库的密码加密功能并存储它(SELECT PASSWORD('mySamplePassword');),然后在稍后的查询中直接比较加密版本。

如果您要保存它以备后续传输:

实际上没有太多事情可以做。传输本身很可能比您处理密码更容易被嗅探。

如果不知道您正在做什么的更多细节,这就有点难回答了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接