I have this change password request form.In which the user enter their oldpasswords.
this oldpassword is the md5 format.
How to compare the md5 value from db to the oldpassword entered by user
import md5
oldpasswd_byuser=str("tom")
oldpasswd_db="sha1$c60da$1835a9c3ccb1cc436ccaa577679b5d0321234c6f"
opw= md5.new(oldpasswd_byuser)
#opw= md5.new(oldpasswd_byuser).hexdigest()
if(opw == oldpasswd_db):
print "same password"
else:
print "Invalid password"
the hash you put in there is a salted sha1 hexdigest as django (and probably many others) stores it by default.
the code to verify it is in contrib/auth/models.py. From there you can see that django works with md5 by default. All you have to do is to update the old hashes to the following form:
md5$<salt>$<hash>
if your hashes aren't salted yet leave the salt empty (md5$$<hash>), but update the hash to sha1 the next time the user performs a valid login.
I don't think that oldpasswd_db is a MD5. It more looks like a combination of hash method (SHA1 in this case), a salt and the password hash itself.
Try to concatenate the salt value with the password:
import hashlib
hashlib.sha1('c60datom').hexdigest()
It's not md5, it's sha1 - "sha1$xxx.
You'd have to use sha1 functions instead.
There is a documentation on this at http://docs.python.org/library/sha.html
to compare the value of your current password to the password stored in the database you can do:
import md5
input_password = request.POST['password']
md5_hashed_input_password = md5.new(input_password).hexdigest()
#comapre the value to that stored in db
if md5_hashed_input_password == db_password: #password in db should be stored in md5 hash format
print 'password match'
else:
print 'password mismatch'
Related
I have created a login/signup script in python using sqlite3 and kivy. Affter creating the database, the user can enter their username, email and password. The password is hashed before being inserted into the database. The signup function works, however I am having an error with validating the user's username and password with those in the database, where the code outputs 'login sucessful' after a wrong username/password.
def login_menu_press(self):
login = False
lusername = self.login_username.text
lpassword = self.login_password.text
print(f"Your username is {lusername}, and your password is {lpassword}.")
self.login_username.text = ""
self.login_password.text = ""
# Hashing inputted password
context = CryptContext(
schemes=["pbkdf2_sha256"],
default="pbkdf2_sha256",
# More rounds = more secure, but slower to hash
pbkdf2_sha256__default_rounds=50000
)
# Hash the inputted password
hash_pass = context.hash(lpassword)
# Connect to database
conn = sqlite3.connect('users.db')
# Create cursor
c = conn.cursor()
# Query database
command = f"SELECT * from users WHERE username='{lusername}' AND Password = '{hash_pass}';"
c.execute(command)
if not c.fetchone():
print("Login successful")
login = True
else:
print("Login failed")
I belive that the error persits after the Query database comment, any help is appreciated, thanks!
I excpeted that login sucessful outputs when the username and password is supposed to be correct, which is correct. However, the code outputs this again when the username and password is anything else random.
Edit the password inputted by the user is hashed with the same algorithm that was used to hash the password that the user signs up with, therefore the hashed values will be the same.
Hash alghoritm which you used use salt, thus for exatly same input string it will output different hash values:
# Hash the inputted password
lpassword = "Rambo"
hash_pass = context.hash(lpassword)
print(hash_pass)
hash_pass = context.hash(lpassword)
print(hash_pass)
hash_pass = context.hash(lpassword)
print(hash_pass)
$pbkdf2-sha256$50000$wniP0br3XguBsJbSuvc.xw$vmebKLd0Uvz4IF7DbX/TzCgD5p1/cmPYApaf2eKeZ4w
$pbkdf2-sha256$50000$wJjT2tv7H8NY633vXYvROg$D0CxPTfO8jIaLPHvUtawhzKMX75LqDYSNa.z3Bf/58s
$pbkdf2-sha256$50000$tZbSWmvNmdPau9eas1ZKaQ$qMVGQWPtlLvFZ/WlG.iDO7.jIHhFiirMZw0gysfqXhs
So there is no way to match previously inserted and hashed password value. You have to use hash function which will always generate same value for same input string, like SHA-256 for instance. Replace:
hash_pass = context.hash(lpassword)
with:
import hashlib # on top of main.py
hash_pass = hashlib.sha256(lpassword.encode()).hexdigest()
And comment out this part of code:
context = CryptContext(
schemes=["pbkdf2_sha256"],
default="pbkdf2_sha256",
# More rounds = more secure, but slower to hash
pbkdf2_sha256__default_rounds=50000
)
Also you you have to change your condition: if not c.fetchone(): to if c.fetchone():
i am creating a login function and a part of this includes checking a password entered by the user against the password stored in the database.
The problem is, when the password is created during the sign up step, it is stored as an encrypted string using fernet. Now I tried to see if encrypting the password entered by the user with the same key would produce the same encrypted string value as the one in the database, but fernet will create unique strings using the same key on the same plaintext.
What other ways can i check a password entered against its encrypted counterpart in the database?
import sqlite3
from cryptography.fernet import Fernet
key = Fernet.generate_key()
fernet = Fernet(key)
def loginFunc():
email = input("What is your email: ")
password = input("what is your password: ")
#a variable that can be used to save the data from users database
emailList = '''SELECT * FROM users WHERE `email` = ? and `password` = ?'''
#takes arguments into variable
password_checkEnc = fernet.encrypt(password.encode())
inputs = (email, password_checkEnc)
#executes line 62 to save the data that matches the arguments from 'inputs' and stores in emailList
cursor.execute(emailList, inputs)
user = cursor.fetchone()
#if statement to check if the database holds the data that is being searched for, allowing either the user to login or not
if user is not None:
print("login successful")
else:
print("incorrect information")
Why not just decrypt the password and check that way? My understanding of fernet key encryption is to do exactly what you're describing, creating a random encryption of the value each time. The purpose of the key is to decrypt it later. It would probably help to see your code where you initially encrypt the password but just looking at what you have here, it looks like you're generating a new key, not using the same one as before. You have to actually save the key you create initially with something like this:
# key generation
key = Fernet.generate_key()
fernet = Fernet(key)
# string the key in a file
with open('C:/locationofyourchoosing/newkey.key', 'wb') as filekey:
filekey.write(key)
# using the key to encrypt
f = Fernet(key)
f.encrypt(databasepassword)
Then you use this same key to decrypt the value later like this:
# opening the key
with open('C:/locationofyourchoosing/newkey.key', 'rb') as filekey:
key = filekey.read()
f = Fernet(key)
f.decrypt(databasepassword)
Then from there you can check the equality of the password. Forgive me if this isn't what you're looking for but I'm not sure you can produce the same encrypted string each time as I believe that would defeat the purpose. I hope this helps and again, if I'm missing the mark completely, please let me know as I'm just a touch confused as to why you're wanting to check equality this way.
I am using the snippet below to encrypt user password before saving in the database.
from pbkdf2 import crypt
pwhash = crypt(password_from_user)
Example: $p5k2$$Y0qfZ64u$A/pYO.3Mt9HstUtEEhWH/RXBg16EXDMr
Then, I save this in database. Well locally, I can perform a check doing something like this:
from pbkdf2 import crypt
pwhash = crypt("secret")
alleged_pw = raw_input("Enter password: ")
if pwhash == crypt(alleged_pw, pwhash):
print "Password good"
else:
print "Invalid password"
but how do I perform checks with what is on the db as the encrypted string is not always the same. I'm using python-pbkdf2.
Okey, Did more research and figured out that to achieve this, i first have to encrypt the password and save in db.as:
pwhash = crypt("secret",iterations=1000)
which can produce a string like $p5k2$3e8$her4h.6b$.p.OE5Gy4Nfgue4D5OKiEVWdvbxBovxm
and to validate when a user wants to login with same password, i use the function below:
def isValidPassword(userPassword,hashKeyInDB):
result = crypt(userPassword,hashKeyInDB,iterations = 1000)
return reesult == hashKeyInDB #hashKeyInDB in this case is $p5k2$3e8$her4h.6b$.p.OE5Gy4Nfgue4D5OKiEVWdvbxBovxm
this method returns True if the password is same or False if otherwise.
First of all I am using Python bottle with Sqlite3. The trouble that I am having is that when I initialize my salt at the beginning of the program, and then stop the program and restart it, the whole thing breaks because it makes a different salt. So when I restart the program, I can't login with any of the old accounts, and I can't make a user with the same name because theyre still stored in the credentials DB.
salt:
salt = uuid.uuid4().hex
hash:
hashed_password = hashlib.sha512(passwordInput + salt).hexdigest()
I am verifying the account by
row = (c.execute("SELECT * FROM Credentials WHERE usernameDB =? AND passhashDB =?", (usernameInput, hashed_password, ))).fetchone()
if row:
etc...
How should I go about fixing this?
If all accounts had the same salt, it would not be able to protect against a rainbow table computed for this salt.
Each user must have its own salt.
The salt is stored together with the password hash in the database.
(The salt itself being stored unencrypted is not a problem; you need it again to check the hash.)
Something like this:
def new_user(name, password):
salt = uuid.uuid4().hex
hash = hashlib.sha512(password + salt).hexdigest()
c.execute("INSERT INTO Credentials(usernameDB,passhashDB,salt) VALUES(?,?,?)",
(name, hash, salt))
def check_login(name, password):
c.execute("SELECT salt, passhashDB FROM Credentials WHERE usernameDB = ?",
(name,))
for row in c:
salt = row[0]
actual_hash = row[1]
input_hash = hashlib.sha512(password + salt).hexdigest()
if input_hash != actual_hash:
raise Exception("invalid password")
else:
raise Exception("invalid user name")
I setup a simple bcrpyt authorization on python. The hash matches every single time regardless of what the password is. I can't for the life of me figure out why it's doing this.
I for the life of me can't understand why it's doing this.
if bcrypt.hashpw(password, user.password) == user.password:
uj = user_json(str(user.user_id), user.email, user.firstname, user.lastname, user.state, user.city)
self.write(uj)
else:
self.write(error_json(cna="cannot authorize user"))
Again regardless of the password I enter. The hash always returns something matching.