简体   繁体   中英

SQL Server Encryption and nhibernate

We have a database that has a few encrypted columns (symetric key as described here ). I'm trying to map these tables in a legacy app using using old-school NHybernate 2.1.2.4.

I thought I would be able to map the encrypted columns using a formula, like this:

<property name="Name" column="Name">
  <formula>
    OPEN SYMMETRIC KEY MyKey DECRYPTION BY CERTIFICATE MyCert
    SELECT CONVERT(NVARCHAR(150), DECRYPTBYKEY(Name)) AS Name FROM [Company] WHERE [Company].[Id] = Id
  </formula>
</property>

Unfortunately this does not work since I'm not allowed to use the open statement there. I can reproduce the problem in pure SQL by trying this:

SELECT 
    Company.Id, 
      (OPEN SYMMETRIC KEY MyKey DECRYPTION BY CERTIFICATE MyCert 
      SELECT CONVERT(NVARCHAR(150), DECRYPTBYKEY(Name)) FROM [Company] WHERE Id = Company.Id),
    Address
  FROM Company;

This gives the same error since Open does not return anything, it's a void statement.

Is there any way to get NHibernate to call Open somewhere else? Maybe just after opening a connection or in the session handling somewhere?

Otherwise, is there a valid SQL syntax to get that statement working inside a query?

Views, functions and stored procedures are not an option since they defeat the purpose of encrypted columns.

---- Edit ----

Doing the Open statement when the session is opened and putting this in the config:

<property name="Name" column="Name" formula="CONVERT(NVARCHAR(150), DECRYPTBYKEY(Name))" />

Seems to fix half of the problem, the field is read-only :-(

By the way, updating the field using plain SQL also gives crazy results. When I do this:

UPDATE Company 
  SET Name = ENCRYPTBYKEY(KEY_GUID('MyKey'), 'Hello World')
  WHERE Id=1000;

And then read it back using CONVERT(NVARCHAR(150), DECRYPTBYKEY(Name)) , I get some interesting characters '效汬潗汲d' back instead of 'Hello World'.

I guess upgrading our SQL2005 database and using TDE as Remus Rusanu mentioned is the best option.

What's the purpose of your encryption? By using a certificate encrypted by the database master key, as it appears to be the case, any user or application can decrypt the data. You are not providing cryptographic protection, you only offer access protection (grant/deny/revoke access to data and/or keys). Cryptographic protection would require your user to specify the password required to unlock the root of the key hierarchy. What you're doing has valid use (loss of media protection) but it can be handled 1 million times better by Transparent Database Encryption or by BitLocker .

As for your problem: just open the key in the session (ie. when you open the connection). There is zero reasons to try to open it on-demand on per-statement access.

For decryption during read, you can use DECRYPTBYKEYAUTOCERT in the formula- that performs decryption without having to specify OPEN SYMMETRIC KEY. Unfortunately, it being a formula field means it can only be used for reads. This 5-part blog series goes into details of how to make this work for read and write, but I admit as does the author of the series - it is a bit hacky.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM