Query encrypted column in MS SQL using LINQ - c#

I need to encrypt some columns in my MS SQL database (name, ssn ...) and I have been looking at column encryption as described by a few sites such as:
Encrypting Column Level Data in SQL Server
and
Introduction to SQL Server Encryption and Symmetric Key Encryption Tutorial.
I've been able to use an Trigger on insert to encrypt a column and I can decrypt the column within SQL Studio using:
OPEN SYMMETRIC KEY TestTableKey
DECRYPTION BY PASSWORD = 'Pa$$w0rd'
CONVERT(VARCHAR(50),DECRYPTBYKEY(EncryptSecondCol)) AS DecryptSecondCol
FROM TestTable
But how do I access the data from my application? I still want to be able to search for names. The only thing I can think of is using a Stored Procedure and sending the decryption password as a parameter in the LINQ statement so the stored procedure can decrypt the data and then execute the query.
Am I on the right track?
I'm new to this so I welcome other useful suggestions.

Yes, I have seen stored procedures to decrypt encrypted text. I've also seen stored procedures to encrypt text, which I prefer to Triggers because I don't like Triggers - see these answers.
However, I prefer to put encryption logic in my application layer - using, for example, the Enterprise Library Encryption Code. The passphrase and salt are easily encrypted in the config file using the Enterprise Library console.
Is there a specific reason for doing this work in the database? If you must do it that way, you could use EL to protect your passphrase and pass that into the stored procedure you've written.

If you are using MS SQL Server Enterprise or Developer editions, you can use TDE:
TDE

Related

Decrypt via T-SQL data that was encrypted via C#

I have a SQL Server table with 1 column containing encrypted data.
The data was encrypted using the answer provided by #CraigTP to this question... Encrypting & Decrypting a String in C#
I need to retrieve & decrypt this data using only T-SQL. Is that possible? How?

Symmetric Key Encryption in SQl Server and decryption in C#

hope everyone will be fine here.
I have created a column with encrypted data using SQL Server Symmetric Key encryption feature. What I have done is given below:
CREATE MASTER KEY ENCRYPTION
BY PASSWORD = 'Test1'
CREATE CERTIFICATE EncryptTestCert
WITH SUBJECT = 'Test1'
CREATE SYMMETRIC KEY TestTableKey
WITH ALGORITHM = TRIPLE_DES ENCRYPTION
BY CERTIFICATE EncryptTestCert
CREATE SYMMETRIC KEY Test1
WITH ALGORITHM = TRIPLE_DES ENCRYPTION
BY CERTIFICATE EncryptTestCert
OPEN SYMMETRIC KEY TestTableKey DECRYPTION
BY CERTIFICATE EncryptTestCert
UPDATE [Security].[User]
SET EncryptedPhone = ENCRYPTBYKEY(KEY_GUID('TestTableKey'),Phone)
It has successfully Updated EncryptedPhone column with encrypted data (which is in varbinary).
Now the problem is that, I am using LINQToSQL on application and I am using inline Linq To SQL query (not stored procedure or sql query), I need to decrypt this data to view on the page. As you can see from the above database code, I am using TripleDES to create encrypted data. However I am unable to understand how can I achieve the decrypted data on C# which was encrypted through SQL query.

Authentication at SQL vs Server (Crypto.VerifyHashedPassword /HashBytes)

I have an application that stores hashed passwords in the database.The applicatin is written in .Net and It uses SQL Server 2012.The authentication workflow is as follows:
Users types Email Address/Password
Database Call is done to retrieve the record by email Address
Servers side verification of the stored hashed password against the password that is typed using this code:
Crypto.VerifyHashedPassword(hashedPassword, password);
I am wondering whether this can be done solely in the database and what are the disadvantages of that approach. I understand that i will be sending clear text passwords to the TSQL Stored Procedure.
I was reading about HashBytes and it seems a candidate for hashing. It seems that I can hash it and convert it to NVARCHAR field and do a comparison on that as follows:
SELECT
....
FROM dbo.Users
WHERE EmailAddress = '<Entered_EmailAddress>'
AND Password = master.dbo.fn_varbintohexstr(HashBytes('SHA2_256', '<Entered_Password>' ))

Entity Framework and Encrypted Database

I have a column (salary) encrypted in database (MS SQL Server).
I am using the entity framework to display/edit the records from the front end. Any idea how to decrypt the column in the front end to show the salary value?
Thanks
If you are doing encryption on database level you must use database level for decryption - use ObjectContext.ExecuteStoreQuery<YourEntityType>(...) to load records from database - pass SQL command with correct decryption usage into that method.

SQL column encryption

I personally think SQL column encryption is a huge waste ;-), but must implement it due to a customer push. So my questions are:
What actually does it do -- Will an admin see encrypted data, but the application will see cleartext data?
What happens to the data when it gets backed up? I assume that backups remain encrypted, in which case are they usable if we need to recover onto a different server?
Where does the encryption key actually come from?
Can I specify a fixed encryption key, so that at least the database recovery will easily work on an server I move to. I really don't want some magical key algorithm, which shoots me in the foot in the future when the key suddenly is not available.
If the customer is pushing for column encryption but you don't know where the the key will actually come from, your customer is wasting his money and you are wasting his time. Even more so if you are even thinking about fixed keys.
There is an exhaustive explanation on MSDN explaining the key encryption hierarchy. All the schemes have the key chain rooted either in the DPAPI for the case where the service itself must access the encrypted storage w/o any key provided by the user, either in a password explicitly provided by the user.
Encryption is a measure put in place to mitigate specific security threats. Depending on what those threats are (they are nowhere specified in your post) column level encryption may be the right answer, but almost always deploying Transparent Database Encryption is a much better solution.
There is no encryption scheme that can hide the content from an administrator that desires to see the content. Period. Every solution that claims the contrary is snake oil.
http://msdn.microsoft.com/en-us/library/ms179331.aspx
You can create a symmetric key to encrypt the data and can use a string to create it (with the KEY_SOURCE option) that will enable you to recreate it later (this isn't in the linked sample bit is in the docs). This has to be opened to access the actual data. This is protected by a certificate which is in turn protected by the database master key. DO NOT lose the password for your database master key. The Database master key is protected by a server key, so if you restore to another server you must open your database master key with the password and reencrypt with the new server's service master key.
If you created the symmetric key with a static string (KEY_SOURCE option), then you can recreate it with a different certificate and database master key and still access your encrypted data.
-- backup service master key tied to computer (used to decrypt database master password,
-- if this is the same on two servers you can move the database between them)
BACKUP SERVICE MASTER KEY TO FILE = 'C:\ServiceMasterKey.smk'
ENCRYPTION BY PASSWORD = 'topsecret'
go
-- create database master key
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'dbpassword'
go
-- create certificate to use to encrypt symmetric key
CREATE CERTIFICATE TestCertificate WITH SUBJECT = 'Test Certificate',
EXPIRY_DATE = '01/01/2016'
go
-- create symmetric key to encrypt data
CREATE SYMMETRIC KEY TestKey WITH ALGORITHM = TRIPLE_DES,
KEY_SOURCE ='pass_phrase' ENCRYPTION BY CERTIFICATE TestCertificate
go
create table CCInfo (ID int, Plain varchar(16), Encrypted varbinary(128))
go
insert into CCInfo (ID, Plain) values (1, '1234567890ABCDEF')
insert into CCInfo (ID, Plain) values (2, '1234123412341234')
insert into CCInfo (ID, Plain) values (3, '1234567890ABCDEF')
insert into CCInfo (ID, Plain) values (4, '1111111123456789')
go
-- encrypt credit card data
OPEN SYMMETRIC KEY TestKey DECRYPTION BY CERTIFICATE TestCertificate
update CCInfo set Encrypted = EncryptByKey(Key_GUID('TestKey'), Plain)
CLOSE SYMMETRIC KEY TestKey
go
-- check that data is the same
OPEN SYMMETRIC KEY TestKey DECRYPTION BY CERTIFICATE TestCertificate
select ID, Plain, Encrypted, convert(varchar(16), DecryptByKey(Encrypted)) as Decrypted
from CCInfo
CLOSE SYMMETRIC KEY TestKey
A couple things to note:
This is called "Cell-level" encryption, and it is a manual process - you can't just mark a column as "encrypted"
It may require access to Certificate Services, which carries its own set of challenges and overhead (I'm not positive about this, it may depend on whether you use AD)
To answer your specific questions:
Nobody sees unencrypted data directly in the database - you must use a stored procedure to encrypt and decrypt the data. The column itself must be converted to a varbinary column. I believe access can be controlled based on both the key and the stored procedures.
The data is backed up as a varbinary column.
The encryption key is generated in the database by someone with appropriate permissions
I think so? The latter part of this encryption tutorial should give you an idea of what's entailed.
More information can be found in the MSDN Database Encryption documentation.

Categories