Password not working when inserting users in Sonarqube in Python - python

user_password = 'admin'
salt = bcrypt.gensalt(rounds=16)
password = bcrypt.hashpw(user_password.encode('utf-8'), salt)
print(password)
sql_statementInsert = "INSERT into users
(crypted_password,login,uuid,external_login,external_identity_provider,external_id,is_root,onboarded,hash_method,active,name)
values ('{}','cosmin','1ea2ad82-b07c-11ea-b3de-0242ac130004','cosmin','sonarqube','user',false,true,'BCRYPT',true,'cosmin') on conflict (login) do nothing;".format(password.decode("utf-8"))
The generated hash for this example is: $2b$08$1KDDzD5DoVOEopOWUb0Rbu8A0FtYtI02BopFoY4Qxp5URuf3KA0s2.
I have this code which is generating some hash based on the user_password, but when trying to log in with "admin" value is not working. But when I am inserting directly the following hash in the crypted_password is working: $2a$12$uCkkXmhW5ThVK8mpBvnXOOJRLd64LJeHTeCkSuB3lfaR2N0AYBaSi

Solved this by using the good library, I needed py-bcrypt, the wrong one was bcrypt only. Also if you use the new lib you don't need to decode the password when you insert it.

Related

Encrypt/Hide sqlite3 database (Tkinter & Python)

I am currently working on a password saving application using tkinter, and I don't want the database to be visible/accesible from the computer's local storage. Is there a way to achieve this with a pre-existing python library, or do I have to pay for a service?
You can try encrypting your database. I'm fairly sure sqlite doesn't offer encryption by default, you might need an extension like SQLCipher.
If you are looking for a password verification system, you could use one-way hashes like Sha256 or a salted algorithm. If you need a password manager, you could use PyCryptoDomex to encrypt the user's password with a "master key" that the user has to remember. Then when you want to fetch a passcode, ask them for the master key again and use it to decrypt the password.
you can use Sqlite3En package or SQLCipher
Sqlite3En doc:
https://github.com/yous1010/Sqlite3En_python/tree/master
SQLCipher :
https://www.zetetic.net/sqlcipher/
A simple example for sqlite3En :
To Encript db :
from Sqlite3En import Sqlite3En
Sqlite3En.Encrypt_existing_DB_By_Password('DBfile1\\' , 'DBName.db' ,'Table_Name' , password = 'password' ) #DBfile1\\ is DB path folder
To open and connect Encrypted DB :
Memory_conn = sqlite3.connect(":memory:")
Sqlite3En.Open_Encrypted_DB_By_Password ('DBfile1\\','DBName.db','Table_Name',Memory_conn , password = 'password' )
now you can use sqlite db as usual
to select data :
Memory_conn.execute("SELECT * FROM Table_Name)
To insert new value in DB:
Memory_conn.execute("INSERT INTO Table_Name (ID,NAME,AGE) VALUES (1, 'sam', 35)");
Memory_conn.commit()
Sqlite3En.Save_Change_On_EnDB_By_Password(Memory_conn,'DBName.db','Table_Name','DBfile1\\',password = 'password' )

bcrypt different hash for same string?

I have created users in mysql with the same password then this code snippet changes the plain text passwords to a hash using bcrypt. Why is the hash different for the same string?
import mysql.connector
import bcrypt
mydb = mysql.connector.connect(
host="localhost",
user="root",
password="........",
database="briandb",
)
mycursor = mydb.cursor()
for user in ["bob", "alice"]:
password = "ttt"
print(password)
hashed = bcrypt.hashpw(password.encode("utf-8"), bcrypt.gensalt())
print(hashed)
mycursor.execute(
f'UPDATE users set password = "{hashed}" where user = "{user}"'
)
mydb.commit()
You've discovered a key feature of robust password hashing: Each time you hash a password you get a different result. Why?
A different random salt (from bcrypt.gensalt() here) is used each time.
Why is this important?
If a cybercreep breaks into your system and steals your users table, they'll have your salted hashed passwords. When the hashing is done correctly, it is very difficult to recover the unsalted passwords. If they, next, break into a bank's system and steal their hashed passwords, we don't want them to be able to conclude that certain users have the same password on both systems. If they could guess that, they'd know which users to target for deeper cybercrimes.

hashnig passwords with argon2_cffi

I am trying to understand how should I use argon2_cffi to store hashed passwords in my database.
Specifically, I am using this code to write the hashed password into my PostgreSQL table.
from argon2 import PasswordHasher
ph = PasswordHasher()
new_user = User(
name=POST.get('name', 'default_value'),
fullname=POST.get('fullname', 'default_value'),
nickname=POST.get('nickname', 'default_value'),
hashed_password=ph.hash(POST.get('password', 'default_value')))
session.add(new_user)
However, this produces a different password everytime the user inserts a password in my form, although the inserted text is the same.
Of course, I know this is he correct behaviour, but what should I do in order to verify that a given registered user has inserted the right password if I cannot produce the same hash?
Sorry, found out myself in the docs...
import argon2
ph = argon2.PasswordHasher()
def login(db, user, password):
hash = db.get_password_hash_for_user(user)
# Verify password, raises exception if wrong.
ph.verify(hash, password)
# Now that we have the cleartext password,
# check the hash's parameters and if outdated,
# rehash the user's password in the database.
if ph.check_needs_rehash(hash):
db.set_password_hash_for_user(user, ph.hash(password))

Pushing results of Imaplib to Mysql database leading to "TypeError"

I am trying to create a local database of my email using Python.
I am using Imaplib to read email from Imap server. My target is to push the extracted emails to a local MySql database in the format "SUBJECT", "SENDER", "RECEIVER".
I have built up the code that creates a local database, read emails(with specific message).
I am not sure how to craft the code that pushes the results to my Database "EMAIL".
EDIT : I have managed to solve my previous issue of parsing mails and adding it to database. Now I am stuck with type conversion error for Mysql.
Here is my new script:
def parse_email(raw_email):
email_complete = email.message_from_string(raw_email)
email_to = email_complete["To"]
email_from = email_complete["From"]
email_header = email_complete.items()
email_msg = get_first_text_block(email_complete)
con = MySQLdb.connect(host="127.0.0.1", # your host, usually localhost
user="admin", # your username
passwd="pwd", # your password
db="sec_crawl") # name of the data base
con.cursor().execute("INSERT INTO email VALUES (?,?,?,?)",
(buffer(str(email_to)),buffer(str(email_from)),buffer(str(email_header)),buffer(str(email_msg))))
con.commit()
On executing this script, I get the following error :
TypeError: not all arguments converted during string formatting
Here is the part of script that creates the database:
cur.execute("DROP TABLE IF EXISTS EMAIL")
cur.execute("CREATE TABLE email(email_to TEXT,email_from TEXT,email_header TEXT, email_msg TEXT)")
con.close()
I am not sure about the error. I did search some previous questions
Python MySQLdb TypeError: not all arguments converted during string formatting
But the problem is still there.
I am using Python 2.7 on Windows 8.
you have to use %s instead of ? like this
con.cursor().execute("INSERT INTO email VALUES (%s,%s,%s,%s)",
(buffer(str(email_to)),buffer(str(email_from)),buffer(str(email_header)),buffer(str(email_msg))))
'?' are typically used with prepared statements which MySQLdb doesn't support.

SQLAlchemy & PassLib

tl;dr -- How do I use a Python-side library such as PassLib to hash passwords before inserting them into a MySQL DB with SQLAlchemy?
Alright, so I've been banging my head on my desk for a day or two trying to figure this out, so here it goes:
I am writing a web application using Pyramid/SQLAlchemy and I'm trying to interface with my MySQL database's Users table.
Ultimately, I want to do something like the following:
Compare a password to the hash:
if user1.password == 'supersecret'
Insert a new password:
user2.password = 'supersecret'
I'd like to be able to use PassLib to hash my passwords before they go to the database, and I'm not really a fan of using the built-in MySQL SHA2 function since it's not salted.
However, just to try it, I do have this working using the SQL-side function:
from sqlalchemy import func, TypeDecorator, type_coerce
from sqlalchemy.dialects.mysql import CHAR, VARCHAR, INTEGER
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column
class SHA2Password(TypeDecorator):
"""Applies the SHA2 function to incoming passwords."""
impl = CHAR(64)
def bind_expression(self, bindvalue):
return func.sha2(bindvalue, 256)
class comparator_factory(CHAR.comparator_factory):
def __eq__(self, other):
local_pw = type_coerce(self.expr, CHAR)
return local_pw == func.sha2(other, 256)
class User(Base):
__tablename__ = 'Users'
_id = Column('userID', INTEGER(unsigned=True), primary_key=True)
username = Column(VARCHAR(length=64))
password = Column(SHA2Password(length=64))
def __init__(self, username, password):
self.username = username
self.password = password
This was copied from the example 2 at http://www.sqlalchemy.org/trac/wiki/UsageRecipes/DatabaseCrypt
So that works and allows me to use the built-in MySQL SHA2 function (by calling func.sha2()) and do exactly what I want. However, now I'm trying to replace this with PassLib on the Python side.
PassLib presents two functions: one to create a new password hash, and one to verify a password:
from passlib.hash import sha256_crypt
new_password = sha256_crypt.encrypt("supersecret")
sha256_crypt.verify("supersecret", new_password)
I can't quite figure out how to actually implement this. Having read all the documentation, I think it is either a different form of TypeDecorator, a custom type declaration, a hybrid value, or a hybrid property. I tried following this, but it doesn't really make sense to me nor does the code suggested there actually run.
So, to sum up my question -- how do I overload the = and == operators so that they run things through the appropriate hash functions?
PasswordType from sqlalchemy-utils should be the best fit for this issue. It uses passlib. Snipped from the docs:
The following usage will create a password column that will automatically hash new passwords as pbkdf2_sha512 but still compare passwords against pre-existing md5_crypt hashes. As passwords are compared; the password hash in the database will be updated to be pbkdf2_sha512.
class Model(Base):
password = sa.Column(PasswordType(
schemes=[
'pbkdf2_sha512',
'md5_crypt'
],
deprecated=['md5_crypt']
))
Verifying password is as easy as:
target = Model()
target.password = 'b'
# '$5$rounds=80000$H.............'
target.password == 'b'
# True
As I understand it, what you want is this:
Encrypt the user's password when creating the account. Use your salt and algorithm
When the user logs in, hash the incoming password the same way you did when you stored it
Compare the two hashes using regular string comparison in your db request
So, something like this for the login code:
from passlib.hash import sha256_crypt
passHash = sha256_crypt.encrypt(typed_password)
// call your sqlalchemy code to query the db with this value (below)
// In your SQLAlchemy code assuming "users" is your users table
// and "password" is your password field
s = users.select(and_(users.username == typed_username, users.password == passHash))
rs = s.execute()
rs would be the resultset of matching users (should be zero or one of course).
Disclaimer - I did not test any of this
Edit:
Thank you for pointing out that PassLib uses a different salt each time it's run. Your best bet in that case, since there doesn't seem to be a straightforward way to do it with sqlalchemy, is the below:
s=users.select(users.username == typed_username)
rs = s.execute()
userRow = rs.fetchone()
if (sha256_crypt.verify(userRow.password)):
# you have a match
Also, to address your request for abstracting: a common methodology for handling this operation is to create a "security" utility class for getting the user (object) that matches the passed login credentials.
The problem with your current setup is that the User constructor has two different operational goals that, though related, are not necessarily the same thing: authenticating a user and getting a User object (for, say, a list of users in a group). The constructor becomes needlessly complex in that case. It's better to put that logic where it can be encapsulated with other security or login-related functionality such as logging in a user via session ID or SSO token instead of username/password:
security.loginUser(username, password)
# or security.loginUser(single_sign_on_token), etc. for polymorphic Security
loggedInUser = security.getLoggedInUser()
... later ...
otherUser = User(username) #single job, simple, clean

Categories