Skip to content
Advertisement

Python – Store cryptography keys in SQL database

Working on a “Password Saver” and will be using the module “cryptography” to encrypt the passwords. I need to save the key you generate from cryptography in the database as well, but I am not sure how you actually do this.

Done some google searches myself and it seems to be called a “byte string”? Not really sure what it is though.

This is what I have currently:

from cryptography.fernet import Fernet
import mysql.connector

db = mysql.connector.connect(
    host='localhost',
    user='root',
    password='',
    database='password_saver'
)

cursor = db.cursor()

key = Fernet.generate_key()

cursor.execute(f"INSERT INTO `encryption`(`encryption_key`) VALUES ({key})")

With that code I am getting this error: mysql.connector.errors.ProgrammingError: 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'b'cryptographys key is here')' at line 1

Not sure if there is a specific data type I need to use for SQL or if it is something I need to do in python?

Advertisement

Answer

TL;DR

Use: key = Fernet.generate_key().decode(), and change the query to a parameterised query.


There are two key elements in play here:

  • What is a byte string?
  • SQL injection

Byte String:

Given the rule that everything in a computer is a number, a ‘byte string’ is just that, it’s a string of bytes – which is not human readable. However, the reason we can read b'my string' is because Python is doing us a favour in converting the bytes back into a readable string. But under the hood, it’s just a string of bytes.

Further (interesting) reading on the subject

As for converting the byte string into a string (str), something MySQL can store in a VARCHAR field, it’s as simple as:

b'my string'.decode() 

So in your case, the key will be:

key = Fernet.generate_key().decode()

Another option:

Or, if you want to store the raw byte string in the database, you can convert your encryption_key column to a BLOB data type. This is a ‘Binary Large OBject’ field, used to store bytes. However, when it comes time to use the key value, you’ll have to convert it into a string. So might as well do the conversion up front, and just store the string.


SQL Injection:

Please read up on this, I won’t get into it here – but it’s important.

The short story is use parameterised queries.

Change this:

cursor.execute(f"INSERT INTO `encryption` (`encryption_key`) VALUES ({key})")

To this:

cursor.execute("INSERT INTO `encryption` (`encryption_key`) VALUES (%s)", (key,))   
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement