0

im trying to hash a password from a file and then match it with the password given by the user. it's not ment to be super safe just safe enought so that the password isn't plain text in the file. I get the error

TypeError: Unicode-objects must be encoded before hashing

it works if i type hashpass = hashlib.md5(b'p').hexdigest() but then it only encrypts "p"

How do i get it to encrypt my string inputs?

PROGRAM

import hashlib

status = ""

def passhash():    
    code = open("password.txt", "r")
    password = code.readline()                
    global encrypt
    encrypt = hashlib.md5(password).hexdigest()

def checkPassword():
    for key in range(3):        
        p = input("Enter the password >>")      
        hashpass = hashlib.md5(p).hexdigest()

        if hashpass == encrypt:            
            print("password correct!")
            status = "q"
            return status
        else:
            print ('wrong password, try again')
    print ('you have failed')

def Main():
    status = input("p for program, q to quit: ")
    if status == "p":
        passhash()
        checkPassword()
    elif status == "q":
        print("Byebye")
        status = "q"
        return status

while status != "q":            
    status = Main()}
StDuz
  • 3
  • 1
  • 3
  • Well, did you do as the error message suggests and try [encoding `password`](https://docs.python.org/3/library/stdtypes.html#str.encode)? – senshin May 05 '14 at 11:00
  • 1
    You don't want to use md5 for any password hashing, it is not designed for it. Instead you want to look into [`passlib` module](https://pypi.python.org/pypi/passlib), or use the [`crypt` module](https://docs.python.org/2/library/crypt.html) on unix platforms. They are not any more complicated to use than your naive approach. – Antti Haapala May 05 '14 at 11:41

2 Answers2

4

Encode your Unicode string before hashing and/or open the file in binary mode. Pick an encoding and stick to it; UTF-8 supports all of Unicode:

p = input("Enter the password >>")      
hashpass = hashlib.md5(p.encode('utf8')).hexdigest()

You either have to do the same in passhash() or open the file in binary mode and assume that the file uses the same encoding.

Martijn Pieters
  • 889,049
  • 245
  • 3,507
  • 2,997
1

The expression b'p' encodes the string literal 'p' as bytes, not the value of the p variable. Try p.encode('utf-8').

By the way, what you're doing is pointless. Since you're storing plaintext and collecting plaintext input from the user, hashing the two before comparing them doesn't add any security.

The right way to approach this is to store the password hash (never storing the plaintext) and hashing the input for comparison. Better yet to hash the password with a random salt; store the salt and hashed password; and hash the input with the salt for comparison.

Chris Johnson
  • 17,500
  • 5
  • 69
  • 74