English 中文(简体)
Python身份验证API
原标题:
  • 时间:2008-09-16 09:17:41
  •  标签:

I m looking for a python library that will help me to create an authentication method for a desktop app I m writing. I have found several method in web framework such as django or turbogears.

I just want a kind of username-password association stored into a local file. I can write it by myself, but I m really it already exists and will be a better solution (I m not very fluent with encryption).

最佳回答

将以下内容视为伪代码。。

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()

这是一种非常不安全的散列密码方法。你不想这么做。如果您想知道原因,请阅读Bycrypt Paper由为OpenBSD开发密码哈希系统的人撰写。此外,如果想就如何破解密码进行深入讨论,请查看本次采访开膛手杰克(流行的unix密码破解器)的作者。

现在B-Crypt很棒,但我不得不承认,我没有使用这个系统,因为我没有EKS Blowfish算法,也不想自己实现它。我使用的是FreeBSD系统的一个稍微更新的版本,我将在下面发布。要点是这样的。不要只是打乱密码。对密码进行Salt处理,然后对密码进行散列处理,并重复10000次左右。

如果这没有意义的话,下面是代码:

#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常量。这是该系统中的可扩展成本因素。您需要进行测试,以确定您希望等待计算每个哈希的可接受时间,以及密码文件受到基于离线字典的攻击的风险。

安全性很难,我提出的方法不是最好的方法,但它比简单的哈希要好得多。此外,它的实现非常简单。所以,即使你不选择更复杂的解决方案,这也不是最糟糕的。

hope this helps, Tim

我认为您应该制定自己的身份验证方法,因为您可以使其最适合您的应用程序,但使用库进行加密,例如pycrypto或其他一些更轻量级的库。

顺便说一句,如果你需要pycrypto的windows二进制文件,你可以得到它们此处

如果你想要简单,那么就使用一个字典,其中的密钥是用户名,值是密码(用类似SHA256的东西加密)Pickle将其从磁盘中取出(由于这是一个桌面应用程序,我认为将其保存在内存中的开销可以忽略不计)。

例如:

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"

请注意,这会将密码存储为hash-所以它们基本上是不可恢复的。如果你丢失了密码,你会被分配一个新密码,而不是找回旧密码。

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-authenticate-to-a-3rd第三方现场

使用“md5”它比base64好得多

>>> import md5
>>> hh = md5.new()
>>> hh.update( anoop )
>>> hh.digest
<built-in method digest of _hashlib.HASH object at 0x01FE1E40>




相关问题
热门标签