Python认证API

6 投票
6 回答
10571 浏览
提问于 2025-04-11 09:18

我在找一个Python库,想用它来为我正在写的桌面应用程序创建一个认证方法。

我在一些网页框架,比如Django或TurboGears,找到了几种方法。

我只想要一种把用户名和密码关联起来,并存储在本地文件里的方式。我自己可以写这个,但我真的希望能找到一个现成的解决方案,因为我对加密不是很熟悉。

6 个回答

3

我觉得你应该自己创建一个认证方法,这样可以让它更适合你的应用程序。不过在加密方面,建议使用一个库,比如pycrypto,或者其他一些更轻量的库。

顺便说一下,如果你需要pycrypto的Windows版本,可以在这里找到。

11

dbr 说:

def hash_password(password):
    """Returns the hashed version of a string
    """
    return hasher.new( str(password) ).hexdigest()

这种方式来加密密码真的不安全。你绝对不想这么做。如果你想知道原因,可以看看这篇由为 OpenBSD 设计密码加密系统的人写的 B-Crypt 论文。另外,如果你想了解密码是怎么被破解的,可以看看 这篇采访,采访的对象是 Jack the Ripper 的作者(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 常量。这是这个系统中的可扩展成本因素。你需要进行测试,以确定你希望每次计算哈希时能接受的等待时间,以及你密码文件遭受离线字典攻击的风险之间的平衡。

安全性是个难题,我提供的方法并不是最好的,但比简单的哈希要好得多。而且实现起来非常简单。所以即使你不选择更复杂的解决方案,这个方法也不是最糟糕的。

希望这能帮到你,
Tim

0

把下面的内容当作伪代码来看待..

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 这个文件.. 本地应用的身份验证很难做到安全。你需要用用户的密码来加密任何读取的数据,并且通常要非常小心。

撰写回答