Best practices for (symmetric) encryption in .Net?
Asked Answered
G

4

16

What is considered "best practice" for encrypting certain sensitive or personally identifiable data in a SQL database (under PCI, HIPAA, or other applicable compliance standards)?

There are many questions here regarding individual aspects of a solution, but I have not seen any that discuss the approach at a high level. After looking around for quite some time, I came up with the following:

  • Use CryptoAPI and Rijndael
  • Generate IV and store it with the encrypted data
  • Use DPAPI (Machine scope) to "protect" the symmetric key
  • Store the symmetric key in the registry or a file or the database, split the key and store parts in multiple places for added protection
  • do not decrypt the data unless it is really needed, i.e. not upon read from the database. Instead, hold cipher text in memory.

Is this adequate? Outdated? Audit-safe? Reckless?

Grammatical answered 13/3, 2014 at 16:40 Comment(5)
From a security standpoint, I don't think it matters if you use CryptoAPI--just as long as you use Rijndael or AES (currently). You could use bouncy castle to do that, for example. Storing IV independent of encrypted data seems more secure. Storing the symmetric key on different hardware--that is more secure--is always a better practice. And only store non-sensitive data when possible. e.g. if you don't need a social security #, don't use that as an identifier. Having said that, answers to this question are likely going to be opinion-based.Tuque
@PeterRitchie Keeping the IV secret doesn't gain you much. For example with AES-CBC, all it prevents is the decryption of the of the first 16 bytes. Everything else can be recovered without IV.Erstwhile
@Erstwhile Agreed, I only said "more" secure.Tuque
@Wolfwyrd except that's a question specific to php and has some php-specific answers.Tuque
It depends on the compliance. On HIPAA if it is a closed system then I am not sure you must encrypt. Granted probably not a best practice. But the compliance and physical security are factors. You are looking at the right stuff.Skerrick
A
17

Your approach is good, with a few adjustments in my eyes (I code for PCI compliance generally):

Use CryptoAPI and Rijndael

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

Generate IV and store it with the encrypted data

Good

Use DPAPI (Machine scope) to "protect" the symmetric key

Not sure if it matters. I'd just keep the IV next to the data that's encrypted, or if you're really paranoid on some other medium. Ensure that the IV is not accessible to the public.

Store the symmetric key in the registry or a file or the database, split the key and store parts in multiple places for added protection

Storing in multiple places will not help you if someone steals your media. It's a bit overkill to split the key up all over heck, but definitely do NOT store it with your IV and/or ciphertext. That'd be bad.

do not decrypt the data unless it is really needed, i.e. not upon read from the database. Instead, hold cipher text in memory.

Definitely. Holding cipher text in memory in fine, but don't pass it around anywhere, and don't decrypt except when you absolutely must, and even then don't EXPOSE the entire unencrypted dataset - only what is needed from it at the minimum. Also, do not hold the key in memory if possible - a memory dump could expose it.

Additions:

  • Whatever database you store your cipher text in, restrict read access entirely to the proc(s) that select for a given identifier. Do not allow read access to the tables that store this data to ANYONE, even the SA account. This way, a person who breaks into your system will have a hard time pulling down your cipher texts without knowing what IDs to look for. Do the same for any table(s) referencing the identifier on the ciphertext table. DO NOT ALLOW BLANKET READS OF THESE TABLES!
  • Restrict database access by IP
  • Never persist any unencrypted plaintext in memory over state. Allow it to be dereferenced/garbage collected as soon as the request is completed.
  • Restrict the server(s) running this code to as few users as possible.
  • Possibly combine encryption methods for a stronger ciphertext (AES + Blowfish for example)

Hope these help. Some of them are my personal opinions but remain PCI compliant to the best of my knowledge.

Anklebone answered 13/3, 2014 at 17:9 Comment(1)
You said "Ensure that the IV is not accessible to the public". But isn't storing the IV alongside the encrypted data basically making it public? Also, I thought it was OK to make the IV public, so long as the same IV isn't used globally -- ideally, it would be unique to each ciphertext (i.e. encrypted value).Cothran
L
1

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 the built-in managed classes (all the ones with "Managed" at the end of their names in the System.Security.Cryptography namespace) are not. If you have a requirement for FIPS compliance, it's probably easiest to for you to use CryptoAPI.

Louvain answered 30/6, 2015 at 19:12 Comment(3)
It's worth noting that FIPS mandates weak security. Avoid it unless the NSA mandates it.Helsa
...or any other client / stakeholder requires it. If it's a requirement then it's a requirement. If it's not a requirement then the world is your oyster... or at least just a little bit. ;)Louvain
you could always encrypt with a strong cipher (Rijndael), then encrypt that with the mandated solution. generally the mandates are a floor not a ceiling.Looming
F
1

I would add:

  • Keeping the IV hidden is not important. It's OK if the IV is public. Just use good IVs, which means, use a cryptographic-strong random number generator so that your IVs are indistinguishable from random.

  • Storing the encryption key separate from the data that it encrypts.

  • Add authentication to your encryption. For example, add an HMAC keyed with a second symmetric encryption key, covering the ciphertext. If you don't use some form of authenticated encryption, then your ciphertext could be modified, and you have no way of knowing (AES will decrypt garbage just fine.) You want any tampering of the ciphertext to be noticed.

Fiacre answered 1/7, 2015 at 22:17 Comment(3)
I know it's been 5yrs since you posted this, but could you expound on the last bullet point regarding HMAC? How would this work when encrypting one or more values, as compared to standard symmetric encryption?Cothran
@MassDotNet Google "Authenticated Encryption" en.wikipedia.org/wiki/Authenticated_encryption. Also, "AES GCM mode" as an example. If you use GCM mode, you get authenticated encryption included.Fiacre
Great, ty for the response and link!Cothran
H
1

Taken more generic list of best practices, from OWASP (Cryptographic Storage Cheat Sheet):

  • Use strong approved cryptographic algorithms
    • Do not implement an existing cryptographic algorithm on your own
    • Only use approved public algorithms such as AES, RSA public key cryptography, and SHA-256 or better for hashing
    • Do not use weak algorithms, such as MD5 or SHA1
    • Avoid hashing for password storage, instead use Argon2, PBKDF2, bcrypt or scrypt
  • Use approved cryptographic modes
    • In general, you should not use AES, DES or other symmetric cipher primitives directly. NIST approved modes should be used instead. Quote from Nist: "The approved algorithms for encryption/decryption are symmetric key algorithms: AES and TDEA."
  • Use strong random numbers
  • Ensure that any secret key is protected from unauthorized access

Also, according to this Cisco article:

  • DES is to be avoided and so is RSA-768, -1024
  • RSA-2048 and RSA-3072 are acceptable
  • AES-CBC mode is acceptable, while
  • AES-GCM mode is part of the Next Generation Encription.
Hake answered 29/8, 2018 at 8:35 Comment(1)
I don't understand what "[using] symmetric cipher primitives directly" means. The NIST quote says that AES is an approved symmetric key algorithm -- doesn't that means I can use AES?Cothran

© 2022 - 2024 — McMap. All rights reserved.