I have been researching the best encryption to use in a .NET application for managing a sensitive database field (column). This encryption is on top of e.g. AWS at-rest encryption applied to the whole of the database and is aimed at frustrating use of the sensitive data by anyone other than the application (which knows the encryption key). Defence in-depth!
It seems to me from lots of reading that the sweet spot for a proven, widely-used secure solution is:
- use AES-GCM (AES-256) to encrypt the sensitive data
- for IV, use cryptographic-standard random value (e.g. via https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography.randomnumbergenerator.create?view=net-7.0) rather than database record (row) primary key. (This is because although the primary key is unique, it is a v4 uuid from a PRNG and so perhaps less suitable? The primary key is also used in the associated data.)
- guarantee uniqueness of IV by storing it in its own database column with UNIQUE constraint applied
- use database table name plus record primary key (always unique) as associated data to bind encrypted data to correct database record
- use long-lasting encryption keys (safe due to guaranteed IV uniqueness)
Does this seem reasonable and are there any improvements the community would suggest?
I am considering AES-GCN over the likes of XChaCha20-Poly1305 due to greater use and scrutiny as well as in-the-box availability in .NET (see e.g. https://www.scottbrady91.com/c-sharp/aes-gcm-dotnet, avoids "rolling my own").
Any comments or experience appreciated.