<p>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.</p>

<p>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).</p>

[{'answer_id': 70712, 'author': 'Toni Ruža', 'author_id': 6267, 'author_profile': 'https://Stackoverflow.com/users/6267', 'pm_score': 2, 'selected': False, 'text': '<p>I think you should make your own authentication method as you can make it fit your application best but use a library for encryption, such as <a href="http://www.pycrypto.org" rel="nofollow noreferrer">pycrypto</a> or some other more lightweight library.</p>\n\n<p>btw, if you need windows binaries for pycrypto you can get them <a href="http://www.voidspace.org.uk/python/modules.shtml#pycrypto" rel="nofollow noreferrer">here</a></p>\n'}, {'answer_id': 70832, 'author': 'Tony Meyer', 'author_id': 4966, 'author_profile': 'https://Stackoverflow.com/users/4966', 'pm_score': 0, 'selected': False, 'text': '<p>If you want simple, then use a dictionary where the keys are the usernames and the values are the passwords (encrypted with something like SHA256).  <a href="http://docs.python.org/lib/module-pickle.html" rel="nofollow noreferrer">Pickle</a> it to/from disk (as this is a desktop application, I\'m assuming the overhead of keeping it in memory will be negligible).</p>\n\n<p>For example:</p>\n\n<pre><code>import pickle\nimport hashlib\n\n# Load from disk\npwd_file = "mypasswords"\nif os.path.exists(pwd_file):\n    pwds = pickle.load(open(pwd_file, "rb"))\nelse:\n    pwds = {}\n\n# Save to disk\npickle.dump(pwds, open(pwd_file, "wb"))\n\n# Add password\npwds[username] = hashlib.sha256(password).hexdigest()\n\n# Check password\nif pwds[username] = hashlib.sha256(password).hexdigest():\n   print "Good"\nelse:\n   print "No match"\n</code></pre>\n\n<p>Note that this stores the passwords as a <a href="http://docs.python.org/lib/module-hashlib.html" rel="nofollow noreferrer">hash</a> - so they are essentially unrecoverable.  If you lose your password, you\'d get allocated a new one, not get the old one back.</p>\n'}, {'answer_id': 70915, 'author': 'dbr', 'author_id': 745, 'author_profile': 'https://Stackoverflow.com/users/745', 'pm_score': 1, 'selected': True, 'text': '<p>Treat the following as pseudo-code..</p>\n\n<pre><code>try:\n    from hashlib import sha as hasher\nexcept ImportError:\n    # You could probably exclude the try/except bit,\n    # but older Python distros dont have hashlib.\n    try:\n        import sha as hasher\n    except ImportError:\n        import md5 as hasher\n\n\ndef hash_password(password):\n    """Returns the hashed version of a string\n    """\n    return hasher.new( str(password) ).hexdigest()\n\ndef load_auth_file(path):\n    """Loads a comma-seperated file.\n    Important: make sure the username\n    doesn\'t contain any commas!\n    """\n    # Open the file, or return an empty auth list.\n    try:\n        f = open(path)\n    except IOError:\n        print "Warning: auth file not found"\n        return {}\n\n    ret = {}\n    for line in f.readlines():\n        split_line = line.split(",")\n        if len(split_line) &gt; 2:\n            print "Warning: Malformed line:"\n            print split_line\n            continue # skip it..\n        else:\n            username, password = split_line\n            ret[username] = password\n        #end if\n    #end for\n    return ret\n\ndef main():\n    auth_file = "/home/blah/.myauth.txt"\n    u = raw_input("Username:")\n    p = raw_input("Password:") # getpass is probably better..\n    if auth_file.has_key(u.strip()):\n        if auth_file[u] == hash_password(p):\n            # The hash matches the stored one\n            print "Welcome, sir!"\n</code></pre>\n\n<p>Instead of using a comma-separated file, I would recommend using SQLite3 (which could be used for other settings and such.</p>\n\n<p>Also, remember that this isn\'t very secure - if the application is local, evil users could probably just replace the <code>~/.myauth.txt</code> file.. Local application auth is difficult to do well. You\'ll have to encrypt any data it reads using the users password, and generally be very careful.</p>\n'}, {'answer_id': 80008, 'author': 'tim.tadh', 'author_id': 14107, 'author_profile': 'https://Stackoverflow.com/users/14107', 'pm_score': 4, 'selected': False, 'text': '<p>dbr said:</p>\n\n<blockquote>\n<pre><code>def hash_password(password):\n    """Returns the hashed version of a string\n    """\n    return hasher.new( str(password) ).hexdigest()\n</code></pre>\n</blockquote>\n\n<p>This is a really insecure way to hash passwords. You <em>don\'t</em> want to do this. If you want to know why read the <a href="http://www.openbsd.org/papers/bcrypt-paper.pdf" rel="noreferrer" title="&quot;B-Crypt Paper">Bycrypt Paper</a> by the guys who did the password hashing system for OpenBSD. Additionally if want a good discussion on how passwords are broken check out <a href="http://www.securityfocus.com/columnists/388" rel="noreferrer">this interview</a> with the author of Jack the Ripper (the popular unix password cracker).</p>\n\n<p>Now B-Crypt is great but I have to admit I don\'t use this system because I didn\'t have the EKS-Blowfish algorithm available and did not want to implement it my self. I use a slightly updated version of the FreeBSD system which I will post below. The gist is this. Don\'t just hash the password. Salt the password then hash the password and repeat 10,000 or so times.</p>\n\n<p>If that didn\'t make sense here is the code: </p>\n\n<pre><code>#note I am using the Python Cryptography Toolkit\nfrom Crypto.Hash import SHA256\n\nHASH_REPS = 50000\n\ndef __saltedhash(string, salt):\n    sha256 = SHA256.new()\n    sha256.update(string)\n    sha256.update(salt)\n    for x in xrange(HASH_REPS): \n        sha256.update(sha256.digest())\n        if x % 10: sha256.update(salt)\n    return sha256\n\ndef saltedhash_bin(string, salt):\n    """returns the hash in binary format"""\n    return __saltedhash(string, salt).digest()\n\ndef saltedhash_hex(string, salt):\n    """returns the hash in hex format"""\n    return __saltedhash(string, salt).hexdigest()\n</code></pre>\n\n<p>For deploying a system like this the key thing to consider is the HASH_REPS constant. This is the scalable cost factor in this system. You will need to do testing to determine what is the exceptable amount of time you want to wait for each hash to be computed versus the  risk of an offline dictionary based attack on your password file. </p>\n\n<p>Security is hard, and the method I present is not the best way to do this, but it is significantly better than a simple hash. Additionally it is dead simple to implement. So even you don\'t choose a more complex solution this isn\'t the worst out there.</p>\n\n<p>hope this helps,\nTim</p>\n'}, {'answer_id': 1992484, 'author': 'Dustin Getz', 'author_id': 20003, 'author_profile': 'https://Stackoverflow.com/users/20003', 'pm_score': 0, 'selected': False, 'text': '<pre><code>import hashlib\nimport random\n\ndef gen_salt():\n    salt_seed = str(random.getrandbits(128))\n    salt = hashlib.sha256(salt_seed).hexdigest()\n    return salt\n\ndef hash_password(password, salt):\n    h = hashlib.sha256()\n    h.update(salt)\n    h.update(password)\n    return h.hexdigest()\n\n#in datastore\npassword_stored_hash = "41e2282a9c18a6c051a0636d369ad2d4727f8c70f7ddeebd11e6f49d9e6ba13c"\nsalt_stored = "fcc64c0c2bc30156f79c9bdcabfadcd71030775823cb993f11a4e6b01f9632c3"\n\npassword_supplied = \'password\'\n\npassword_supplied_hash = hash_password(password_supplied, salt_stored)\nauthenticated = (password_supplied_hash == password_stored_hash)\nprint authenticated #True\n</code></pre>\n\n<p>see also <a href="https://stackoverflow.com/questions/1990722/gae-authenticate-to-a-3rd-party-site">gae-authenticate-to-a-3rd-party-site</a></p>\n'}, {'answer_id': 10495626, 'author': 'Anoop Augustine', 'author_id': 1322161, 'author_profile': 'https://Stackoverflow.com/users/1322161', 'pm_score': -1, 'selected': False, 'text': '<p>Use " md5 " it\'s much better than base64</p>\n\n<pre><code>&gt;&gt;&gt; import md5\n&gt;&gt;&gt; hh = md5.new()\n&gt;&gt;&gt; hh.update(\'anoop\')\n&gt;&gt;&gt; hh.digest\n&lt;built-in method digest of _hashlib.HASH object at 0x01FE1E40&gt;\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/70653', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/11563/']