Python 身份验证 API
-
09-06-2019 - |
题
我正在寻找一个 python 库,它将帮助我为我正在编写的桌面应用程序创建身份验证方法。我在Web框架中找到了几种方法,例如django或turbogears。
我只想将一种用户名-密码关联存储到本地文件中。我可以自己写它,但我真的它已经存在并且将是一个更好的解决方案(我对加密不是很熟练)。
解决方案
将以下内容视为伪代码..
try:
from hashlib import sha as hasher
except ImportError:
# You could probably exclude the try/except bit,
# but older Python distros dont have hashlib.
try:
import sha as hasher
except ImportError:
import md5 as hasher
def hash_password(password):
"""Returns the hashed version of a string
"""
return hasher.new( str(password) ).hexdigest()
def load_auth_file(path):
"""Loads a comma-seperated file.
Important: make sure the username
doesn't contain any commas!
"""
# Open the file, or return an empty auth list.
try:
f = open(path)
except IOError:
print "Warning: auth file not found"
return {}
ret = {}
for line in f.readlines():
split_line = line.split(",")
if len(split_line) > 2:
print "Warning: Malformed line:"
print split_line
continue # skip it..
else:
username, password = split_line
ret[username] = password
#end if
#end for
return ret
def main():
auth_file = "/home/blah/.myauth.txt"
u = raw_input("Username:")
p = raw_input("Password:") # getpass is probably better..
if auth_file.has_key(u.strip()):
if auth_file[u] == hash_password(p):
# The hash matches the stored one
print "Welcome, sir!"
我建议使用 SQLite3(可用于其他设置等),而不是使用逗号分隔的文件。
另外,请记住,这不是很安全 - 如果应用程序是本地的,邪恶的用户可能只需替换 ~/.myauth.txt
文件..本地应用程序的身份验证很难做好。您必须使用用户密码对其读取的任何数据进行加密,并且通常要非常小心。
其他提示
dbr 说:
def hash_password(password): """Returns the hashed version of a string """ return hasher.new( str(password) ).hexdigest()
这是一种非常不安全的哈希密码方法。你 不 想做这个。如果您想知道为什么请阅读 比密纸 由为 OpenBSD 开发密码散列系统的人开发。另外,如果想深入讨论密码如何被破解,请查看 这次采访 与 Jack the Ripper(流行的 UNIX 密码破解程序)的作者合作。
现在 B-Crypt 很棒,但我必须承认我不使用这个系统,因为我没有可用的 EKS-Blowfish 算法,并且不想自己实现它。我使用 FreeBSD 系统的一个稍微更新的版本,我将在下面发布。要点是这样的。不要只是对密码进行哈希处理。对密码加盐,然后对密码进行哈希处理并重复 10,000 次左右。
如果这没有意义,这里是代码:
#note I am using the Python Cryptography Toolkit
from Crypto.Hash import SHA256
HASH_REPS = 50000
def __saltedhash(string, salt):
sha256 = SHA256.new()
sha256.update(string)
sha256.update(salt)
for x in xrange(HASH_REPS):
sha256.update(sha256.digest())
if x % 10: sha256.update(salt)
return sha256
def saltedhash_bin(string, salt):
"""returns the hash in binary format"""
return __saltedhash(string, salt).digest()
def saltedhash_hex(string, salt):
"""returns the hash in hex format"""
return __saltedhash(string, salt).hexdigest()
对于部署这样的系统,要考虑的关键是 HASH_REPS 常量。这是该系统中的可扩展成本因素。您需要进行测试,以确定等待计算每个哈希值的特殊时间量与密码文件受到基于离线字典的攻击的风险之间的关系。
安全性很难,我提出的方法并不是实现此目的的最佳方法,但它比简单的哈希要好得多。此外,它的实施起来非常简单。因此,即使您不选择更复杂的解决方案,这也不是最糟糕的。
希望这会有所帮助,蒂姆
如果你想要简单,那么使用字典,其中键是用户名,值是密码(使用 SHA256 等加密)。 泡菜 它与磁盘之间的传输(因为这是一个桌面应用程序,我假设将其保留在内存中的开销可以忽略不计)。
例如:
import pickle
import hashlib
# Load from disk
pwd_file = "mypasswords"
if os.path.exists(pwd_file):
pwds = pickle.load(open(pwd_file, "rb"))
else:
pwds = {}
# Save to disk
pickle.dump(pwds, open(pwd_file, "wb"))
# Add password
pwds[username] = hashlib.sha256(password).hexdigest()
# Check password
if pwds[username] = hashlib.sha256(password).hexdigest():
print "Good"
else:
print "No match"
请注意,这会将密码存储为 散列 - 所以它们基本上是不可恢复的。如果您丢失密码,您将获得一个新密码,而无法找回旧密码。
import hashlib
import random
def gen_salt():
salt_seed = str(random.getrandbits(128))
salt = hashlib.sha256(salt_seed).hexdigest()
return salt
def hash_password(password, salt):
h = hashlib.sha256()
h.update(salt)
h.update(password)
return h.hexdigest()
#in datastore
password_stored_hash = "41e2282a9c18a6c051a0636d369ad2d4727f8c70f7ddeebd11e6f49d9e6ba13c"
salt_stored = "fcc64c0c2bc30156f79c9bdcabfadcd71030775823cb993f11a4e6b01f9632c3"
password_supplied = 'password'
password_supplied_hash = hash_password(password_supplied, salt_stored)
authenticated = (password_supplied_hash == password_stored_hash)
print authenticated #True
也可以看看 gae 向第 3 方网站进行身份验证
使用“md5”比base64好得多
>>> import md5
>>> hh = md5.new()
>>> hh.update('anoop')
>>> hh.digest
<built-in method digest of _hashlib.HASH object at 0x01FE1E40>