I need to encrypt several columns in a database.
Do I create one certificate and a symmetric key for each column or one certificate and one symmetric key per column.
What is the best practice?
Where is the data coming from? If you have an application, especially a web based application you should encrypt the data prior to transmitting it.
Have you thought about using SQL Server's Transparent Data Encryption (TDE)?
In my experience with MS SQL 2008 cell level encryption, you need to set up a master key for your database, create a certificate for your database, and based on that certificate a symmetric key that you will use to encrypt cell level data.
Columns for which you want to encrypt the data on have to be of one of type VARBINARY (or two others: I believe VARCHAR, and NVARCHAR, but I'm not certain). There is also a specific method of inserting/updating data in these columns, as well as reading data from these columns.
We're currently storing a few selected columns of sensitive information encrypted in this manner in VARBINARY(256) columns, along with TDE on top of our database.
More information and helpful tutorials can be found here:
http://www.sqlservergeeks.com/articles/sql-server-bi/19/cell-level-encryption-in-sql-server
http://blogs.technet.com/b/keithcombs/archive/2005/11/24/415079.aspx
Related
I have 2 (DB1,DB2) databases in SQL Azure.
DB1.Customer
DB2.Customer
Each has column called Surname which is column encrypted.
I want to insert records from DB1.Customer to DB2.Customer. I initially tried a Data Compare tool, but it omitted the encrypted column ie "Surname". Is my only way to do this, is to decrypt "Surname", recompare, insert data, re-encrypt "Surname" column for both DBs, or is there another way to avoid decryption.
I have also tried:
1) SSMS / Tasks/ Generate Scripts / Advanced / Data only but the encrypted data is shown as "binary" in the SQL.
Thanks in advance.
I think this is refer to Migrate Sensitive Data Protected by Always Encrypted.
The following table shows the recommended settings appropriate for several migration scenarios.
Hope this helps.
I am using C# 4.0, VS 2010 MVC 3 and Entity Framework for a web application and using SQL server 2008R2 for data storage. I need to encrypt three columns in one table - two are text columns and one is a date column, to update them and to search for items in those columns using the above technologies.
TDE is not an option.
It seems best practice to perform all the encryption functions on the SQL server however, although there are plenty of examples on how to encrypt the columns as a one off exercise, there is nothing on updating or searching these fields once encrypted.
I can see no other way than to move the encryption and decryption into the application.
All guidance, assistance, pointers and hints are very welcome.
Thank you.
You cannot search encrypted data, by definition. What you can search instead is a hash of the known plain text and deal with possible collisions. For this you need to add additional columns to save the hash of the plain text being encrypted. See Indexing encrypted data for more details and an example.
As for updates I really don't see what the question is. You update the encrypted value with a new encrypted value, just like any other update.
TDE is, by a large margin, a much much better option. Just sayin'.
I would be using shared hosting for my SQL Server. I wanted to encrypt the primary key column(auto generated ID) and a varchar column. I searched around and came across TDE. But, being a shared hosting, i cannot use it. So, was looking for any alternatives. The data is already there in the tables, so encrypting from application is not possible now. And there are many SQL statements that search using the above said varchar column. So, performance is also a concern.
Thanks,
Dev
encrypt the primary key column(auto generated ID)
And how will you be able to find a record if its ID is encrypted?? Answering 'I serach by encrypted ID' disqualifies you for not salting the key...
And now for the real issue. You said that you'll be deploying on shared hosting, but you do not mention what kind of protection are you expcecting that ecnryption will provide. The problem is key management. Data will be encrypted with a key and the server will need to decrypt that dtaa somehow. No matter how you turn the problem arround, the root key used to decrypt all the other keys will be also on shared hosting, and hence you will not achieve anything but a slight bump on the road to your data. To put up a fence, the key must be retrieved somewhere from ouside the scope of the shared hosting, eg. your applicaiton will ask for the password to decrypt the root key when interacting with the users, which is by all practical means impossible. Note that
TDE would had solved nothing since the root of trust has the very same problem in TDE or in columnar encryption. If you need privacy, use private hosting.
And to answer the question:
to encrypt data you use ENCRYPTBYKEY.
to decrypt data use DECRYPTBYKEY
the encryption key should be encrypted with a certificate and the certificate should be encrypted with a password, or with the database master key. See Encryption Hierarchy.
you open the encryption key in the session using OPEN SYMMETRIC KEY
you open the master key in the session using OPEN MASTER KEY
you search encrypted dtaa by creating a hash and searching the hash, see Indexing encrypted data
And if you use columnar encryption you never encrypt the primary key. Doing so is completely non-sensical. And claiming any sort of privacy in shared hosting environment is a pipe dream. The only thing you could protect agfainst, at best, is accidental media loss (the hosting HDD turning up at a flea market).
Dev,
I think in your case the only choice is to encrypt from application.
Alternatively you can rename your table, substitute the VIEW instead of renamed table. Encrypt all existing data:
update real_table set field1 = call_encrypt_function(field1), field2 = call_encrypt_function(field2)
In that view you can do select call_decrypt_function(field1),call_decrypt_function(field2) from real_table. For insert and updates you need to master INSTEAD OF INSERT and INSTEAD OF UPDATE triggers. Of course you need to use WITH ENCRYPTION for that objects. I saw that approach in XP_CRYPT, however I prefer free solutions. SQL Server provides basic encryption functions for free.
I am just wondering if there is a MS technology which allow to transparently encrypt the column of table.
There is a symmetric/assymetric encription which allow to encrypt one column of the table. But this technology is not transparent for user applications. The application needs to open keys and use the ENCRYPTBYKEY/DECRYPTBYKEY functions.
There is TDE which allow to transparently encrypt the database, but it works with databases, backups and transaction log - not one column of database.
Is it possible to transparently encrypt one of the column in the table?
Unfortunately no, unless you implement it yourself.
In SQL Server 2008 TDE is implemented at the database level (no column is_encrypted in sys.databases), so it is the only way of doing it.
I've been trying to figure out a good way to encrypt sensitive columns in my DB. I thought the built-in encryption mechanisms of SQL Server would do the trick but either I'm missing something or doing it wrong.
The original plan was to create a table with columns that were encrypted with a symmetric key, and have a view select the data from the table unencrypted. However, I was unable to figure out how to use the DecryptByKey method in the view select statement. Plus it occurred to me that the data would be unencrypted going TO and FROM the view, so unless the connection was secure then it would sorta be pointless.
Then I thought to bring all the encryption/decryption to my app. I figured that
If the DB was completely unable to decrypt its own data, then someone infiltrating the DB wouldn't be able to do much at all.
It would save the server the effort of trying to decrypt/encrypt the info, as encryption/decryption in the DB could affect performance globally instead of just on a single workstation.
So as it sits, my app has "hard-coded" IVs and Keys for each column that needs to be encrypted. It sends the encrypted info to the DB, and receives encrypted info from the DB. This is just for messing around mind you, I know I have to put the IVs and keys somewhere else...they simply aren't safe in the app code.
I was thinking of this crazy idea:
The client app would contain a single Key and IV. The server would contain the Keys/IVs of all of the encrypted columns in a single table. However, the values of the Keys/IVs would be encrypted with the Key/IV that the client app held.
On startup, the client app would load all the Keys/IVs from the DB into memory, and decrypt them as needed to view the data selected from the server.
There could also be a relation which would join users with keys they were allowed to use. So the app would only decrypt columns that the user was authorized to see.
Do you think the idea is a win or loose? And how have some of you implemented encryption given a client-app/SQL Server scenario?
YOu loose. Point. No chance to use indices etc.
If you want safety, put it on a safe server and load Enterprise Edition and use database file encryption.
Consider putting in a middle tier to handle the encryption/decryption for you. Assuming you can put it on the server you can keep control of the bits and not worry about the client app (which may be somewhat out of your control) from being decompiled (and exposing keys).