Recommendations for (symmetric) encryption in .Net?

What is considered “best practice” for encrypting certain sensitive or personally identifiable data in an SQL database (via PCI, HIPAA, or other applicable compliance standards)?

There are many questions regarding specific aspects of the solution, but I have not seen such high-level discussions. After looking around for quite some time, I came up with the following:

  • Using CryptoAPI and Rijndael
  • Create IV and save it with encrypted data
  • Use DPAPI (scope) to "protect" the symmetric key.
  • Keep the symmetric key in the registry or file or database, share the key and store it in several places for additional protection.
  • Do not decrypt data if it is really necessary, that is, not after reading from the database. Instead, store the ciphertext in memory.

Is this adequate? Outdated? Audit security? Reckless?

+7
c # encryption encryption-symmetric pci
source share
3 answers

Your approach is good, with some adjustments in my eyes (I usually code for PCI compatibility):

Use CryptoAPI and Rijndael

Use Rijndael / AES256 at a minimum, independent of other APIs

Create IV and save it with encrypted data

Good

Use DPAPI (machine area) to "protect" the symmetric key

Not sure if that matters. I would just save IV next to the data that was encrypted, or if you are really paranoid on some other medium. Make sure that IV is not accessible to the public.

Keep the symmetric key in the registry or file or database, share the key and store it in several places for additional protection.

Saving in multiple places will not help you if someone steals your media. Outsmart a little to break the key into everything, but certainly DO NOT store it with your IV and / or encrypted text. That would be bad.

Do not decrypt data if it is really necessary, that is, not after reading from the database. Instead, store the ciphertext in memory.

Of course. Keeping the encrypted text in memory is in order, but do not skip it anywhere and do not decrypt it, unless absolutely necessary for you, and even then DO NOT EXPOSE the entire unencrypted data set - just what is needed from it at least. In addition, do not keep the key in memory if possible - a memory dump may expose it.

Additions:

  • Regardless of the database in which you store your encrypted text, restrict read access completely to the proc (s) that you select for this identifier. Do not allow read access to tables that store this data in ANY, even the SA account. Thus, the person who burst into your system, it is difficult to keep your encryption texts, not knowing which identifiers to look for. Do the same for any table (s) referencing the table identifier of the ciphertext. DO NOT ALLOW THE EXPECTED READINGS OF THESE TABLES!
  • Restrict database access by IP
  • Never store plaintext plaintext in memory over state. Let it be dereferenced / garbage collected as soon as the request is complete.
  • Limit the server (s) running this code to as few users as possible.
  • It is possible to combine encryption methods for stronger ciphertext (for example, AES + Blowfish)

I hope for this help. Some of them are my personal opinions, but I still respect PCI, as far as I know.

+6
source share

I saw that one of the previous comments mentioned that it doesn’t matter if you use CryptoAPI. I just wanted to point out that CryptoAPI is FIPS 140-2 compliant, while Bouncy Castle and built-in managed classes (all of them with "Managed" at the end of their names in the System.Security.Cryptography namespace) are not If you have a FIPS compliance requirement, it’s probably easiest for you to use CryptoAPI.

+1
source share

I would add:

  • Keeping a hidden IV is not important. This is normal if IV is public. Just use a good IV, which means use a cryptographic random number generator so that your IVs are indistinguishable from random ones.

  • Keeping the encryption key separate from the data it encrypts.

  • Add authentication to your encryption. For example, add an HMAC with a second symmetric encryption key key spanning encrypted text. If you do not use any form of authenticated encryption, then your encrypted text may be altered and you will not be able to find out (AES will decrypt the garbage just fine). You want some falsifier of ciphertext to be noticed.

0
source share

All Articles