I'm just trying to store and retrieve a bcrypt password in a mysql database. The column type for the password is BINARY(60) as suggested by this answer. I'm using the mysql python connector. Here is my script.
cnx = mysql.connector.connect(user='akhil', password='apples', host='127.0.0.1', database='test')
cursor = cnx.cursor()
# Generate a password and store it in the database
add_user = ("INSERT INTO login (username, password) VALUES (%s, %s)")
hashed=bcrypt.hashpw(b'secret1', bcrypt.gensalt(14))
cursor.execute(add_user, (1, hashed))
cnx.commit()
# Retrieve the password and validate it
query = ("SELECT username, password FROM login WHERE username=%s")
cursor.execute(query, (1,))
for (username, password) in cursor:
print(type(password)) # <class 'str'>
if bcrypt.checkpw(b'secret1', password.encode('utf-8')):
print('Password matches for user 1')
else:
print('Password does not match for user 1')
Now this outputs 'Password matches...' so it works. But here is my login table
+----------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+------------+------+-----+---------+-------+
| username | int(11) | YES | | NULL | |
| password | binary(60) | YES | | NULL | |
+----------+------------+------+-----+---------+-------+
Clearly the password datatype is BINARY(60). Why is it getting converted to a string by the mysql python connector? I looked at this answer, which suggested to pass raw=True
to the connection constructor, but when I did that (and also removed my manual utf-8 encoding of the returned password from the database), I got the following output/error
<class 'bytearray'>
Traceback (most recent call last):
File "C:/Users/akhil/School/blackmirror/bernard.py", line 20, in <module>
if bcrypt.checkpw(b'super secret1', password):
File "C:\Users\akhil\School\blackmirror\env\lib\site-packages\bcrypt\__init__.py", line 112, in checkpw
return _bcrypt.lib.timingsafe_bcmp(ret, hashed_password, len(ret)) == 0
TypeError: initializer for ctype 'void *' must be a cdata pointer, not bytearray
Should I just leave the .encode('utf-8')
, is that the correct way to do this?