Currently, I use EncryptedType
from sqlalchemy_utils
in order to automatically encrypt data on the way in to the table and decrypt the data when it's being retrieved from the table, using some predefined string as the encryption key. This works fine, but now requirements have changed and while I still need to encrypt the data on the way in to the table, I now need to keep that data encrypted when it is retrieved. I'm not sure if this is something that EncryptedType
supports or if there is any other way to do this using SQLAlchemy without rolling my own in what I would assume would be the cryptography library.
Example of my table:
class MyTable(db.Model):
__tablename__ = "my_table"
id = db.Column(db.Integer, primary_key=True, autoincrement="auto")
name = db.Column(db.String(50), nullable=False)
username = db.Column(EncryptedType(db.String, _key), nullable=True)
password = db.Column(EncryptedType(db.String, _key), nullable=True)
Always Encrypted supports two types of encryption: randomized encryption and deterministic encryption. Deterministic encryption always generates the same encrypted value for any given plain text value. Using deterministic encryption allows point lookups, equality joins, grouping and indexing on encrypted columns.
Make sure you have enabled Always Encrypted for the database connection for the Query Editor window, from which you will run a SELECT query retrieving and decrypting your data. This will instruct the . NET Framework Data Provider for SQL Server (used by SSMS) to decrypt the encrypted columns in the query result set.
To create a column encryption key, use Object Explorer to connect to the database instance, navigate to the database, then to Security , and expand the Always Encrypted Keys folder. Right-click Column Encryption Keys , and then select New Column Encryption Key .
I found that using the cryptography library, which is what EncryptedType
uses to handle encryption, was the simplest solution here.
I added an __init__
method to the model class and handled the encryption there.
from cryptography.fernet import Fernet
key = "my_encryption_key_here"
class MyTable(db.Model):
__tablename__ = "my_table"
id = db.Column(db.Integer, primary_key=True, autoincrement="auto")
name = db.Column(db.String(50), nullable=False)
username = db.Column(EncryptedType(db.String, _key), nullable=True)
password = db.Column(EncryptedType(db.String, _key), nullable=True)
auth_password = db.Column(EncryptedType(db.String, _key), nullable=True)
def __init__(self, name, username, password, auth_password):
cipher_suite = Fernet(key)
self.name = name
self.username = cipher_suite.encrypt(bytes(username))
self.password = cipher_suite.encrypt(bytes(password))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With