OK, In case anyone wants to know, I got to the bottom of this.
The chain is pretty easy to work out:
Create Service Master Key (automatically done upon install)
Create Database Master Key (user creates their own key)
SymetricEncrypt(Service Key,Database Master Key) -> Store Encrypted Master Key into Master DB
Create Certificate
SymetricEncrypt(Database Master Key, Certificate Private Key) -> Store Encrypted private key in Master DB
Create Database Encryption Key (system creates a random key, but must be manually added to database)
ASymetricEncrypt(Certificate, Database Encryption Key) -> Store Encrypted DEK into database.
So, to decrypt the database data, you'll need to:
Use the SMK to decrypt the DMK
Use the DMK to decrypt the cert private key
Use the certificate to decrypt the DEK
Use the DEK to decrypt the database
The starting point is the Service Master Key... how is this stored (if you encrypt it, you can't retrieve data, and if left in plaintext your system is exposed).
The answer is, the SMK is encrypted with Data Protection API, which is a service built into windows.
Basically, data is encrypted with "secrets" from your user profile. So the same user profile must be used to decrypt the SMK.
Now that I know this, I can use DPAPI in my applications to encrypt my encryption keys :)
Note that encryption of modules in SQL Server is not really encryption; it is more like weak obfuscation. Anyone with a search engine and a few minutes to kill can reverse engineer your objects, so encrypting them is almost completely pointless. DENY VIEW DEFINITION
is far more effective here (as well as not giving your developers sysadmin
and other privilege escalation).
As for the data, SQL Server 2016 will have Always Encrypted (read about it here), it may make a lot of your work easier if you can wait for that. One of the big plusses is that the app can send the data through the provider already encrypted, so it can't be sniffed out by trace or other man-in-the-middle attacks. Be aware of limitations, too, though:
Best Answer
Taking into consideration the remarks of CLOSE SYMMETRIC KEY (highlighting mine)
Security best practices usually suggest having a security mechanism (symmetric key) open for the minimum amount of time that is it necessary and only in the scope (stored procedure) necessary.
Referencing the example code in DECRYPTBYKEYAUTOCERT, there are basically two ways to decrypt column encrypted data.
OPTION ONE
DecryptByKey
and then close the key before returning control.OPTION TWO
DecryptByKeyAutoCert
function to automatically decrypt the data without having to explicitly open the key. (Requires VIEW DEFINITION permission on the symmetric key and CONTROL permission on the certificate.)