6

I have a small python program which will be used locally by a small group of people (<15 people).But for accountability, i want to have a simple username+password check at the start of the program ( doesn't need to be super secure).For your information, I am just a beginner and this is my first time trying it.When i search around, i found that python has passlib for encryption. But even after looking though it i am still not sure how to implement my encryption.So, there are a few things that i want to know.

  1. How do i store the passwords of users locally? The only way i know at the moment is to create a text file and read/write from it but that will ruin the whole purpose of encryption as people can just open the text file and read it from there.
  2. What does hash & salt means in encryption and how does it work? (a brief and simple explanation will do.)
  3. What is the recommended way to implement username and password check?

I am sorry for the stupid questions. But i will greatly appreciate if you could answers my question.

Chris Aung
  • 9,152
  • 33
  • 82
  • 127

4 Answers4

7
import getpass
import pickle
import hashlib
from os import path

def Encryption(data):
    return hashlib.sha512(data).hexdigest()

## First we check if the database exists.
if path.isfile('database.db'):
    with open('database.db', 'rb') as fh:
        db = pickle.load(fh)

## If it doesn't, we will create one.
else:
    ## First we create the desired variable.
    db = {'torxed' : Encryption('wham'), 'someoneelse' : Encryption('pass')}
    ## Then we open a filehandle to it.
    with open('database.db', 'wb') as fh:
        ## And then we dump the variable into the filehandle.
        ## This will keep the variable intact between sessions,
        ## meaning the next time you start your script, the variable will look the same.
        pickle.dump(db, fh)


## Then we ask the user for his/hers credentials.
user = raw_input('Username: ')
_pass = getpass.getpass('Password: ')

## If the user exists in the "db" and the decoded password
## Matches the logged in user, it's a-ok :)
if user in db and db[user] == Encryption(_pass):
    print('You logged in')

Adding more users

import pickle, hashlib

def Encryption(data):
    return hashlib.sha512(data).hexdigest()

with open('database.db', 'rb') as fh:
    db = pickle.load(fh)

db['new_user'] = Encryption('password')

with open('database.db', 'wb') as fh:
    pickle.dump(db, fh)

Another way would be to use sys.argv to get the username and password from the commandline when addings users, in that case:

import pickle, hashlib, sys
if len(sys.argv) < 3:
    raise ValueError('Need two parameters, username and password')

def Encryption(data):
    return hashlib.sha512(data).hexdigest()

with open('database.db', 'rb') as fh:
    db = pickle.load(fh)

db[sys.argv[1]] = Encryption(sys.argv[2])

with open('database.db', 'wb') as fh:
    pickle.dump(db, fh)

I should expand on this answer and explain that you should salt passwords as well, and not just store them with a SHA hash.

Also note that passwords are strictly speaking "unsafe" when stored in memory, as there is no SecureString (more) in Python as of writing this. But for basic purposes this answer still applies.

Torxed
  • 22,866
  • 14
  • 82
  • 131
  • i prefer the username and password to be changeable.Not hard coded. So, i suppose i need some way to store the password. But thanks for the help – Chris Aung May 02 '13 at 09:28
  • My edit does :) Forgot to add that portion to the file. Note that, to completely secure your string you will need proper encryption, but you could do a `base64.b64encode` on the strings you store in the data, at least that will "obscure" it a bit. Also, i'm assuming Python2.X here, `raw_input` is in fact `input()` on python3.x – Torxed May 02 '13 at 09:28
  • yes i am using python 2.7 on windows xp. & thanks for the help – Chris Aung May 02 '13 at 09:33
  • @ChrisAung You're welcome, made a small edit to the variable `pass`, it's not a valid variable name. :) so changed it to _pass – Torxed May 02 '13 at 09:35
  • 1 more thing.. how do we add new user and password to the database? – Chris Aung May 02 '13 at 09:38
  • @ChrisAung I added a small side-script that you can run to add more users. I also incorporated Kousik_Chodhury's solution on protecting the passwords (which, was a better idea then just b64 the string) :) – Torxed May 02 '13 at 10:23
1

you can do hashing like this.

import hashlib
def Encryption(data):
    return hashlib.sha224(data).hexdigest()

when you want to save the password then call this function and save the encode password.

Torxed
  • 22,866
  • 14
  • 82
  • 131
Kousik
  • 21,485
  • 7
  • 36
  • 59
0

You could use Pickle, its an easy way to serialize things to a .pkl file which would be difficult to just open and read from.

Chachmu
  • 7,725
  • 6
  • 30
  • 35
-1

You could use htpasswd which is installed with apache or can be downloaded seperately. Use subprocess.check_output to run it and you can create Python functions to add users, remove them, verify they have given the correct password etc. Pass the -B option to enable salting and you will know that it's secure (unlike if you implement salts yourself).

r3m0t
  • 1,850
  • 16
  • 21
  • I don't really see the point in using 3:d party software when Python had this built-in and there's Python modules to do the same job? Also, if you need to use check_output to add main functionality in your code, you really gotta recosinder what you're about to do.. – Torxed May 02 '13 at 16:36