Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
I've been looking at the new encryption functionality in SQL Server 2005. Here's some sql that executes on IDW15 - June CTP (most of it should work on IDW14 - April CTP apart from DecryptByKeyAutoCert I think...
This sample code sets up a database and a table that will contain some data (national insurance numbers) we want to store encrypted. It shows how to set up a master key, certicate and encryption key and how to use these to insert and select data. It also demonstrates how to set up a view that takes away a lot of the pain.
It does expose that in IDW15 at least you need to give CONTROL level permission to a certificate to make this work - which I hope gets fixed in the next release... with CONTROL you can do anything to a certificate, including dropping and altering it and removing the private key!!! The last of these works even if the cert is used to decrypt keys in the database - which presents an untenable security problem. What we want is just to require REFERENCES level permission (I think).
Other than this little niggle, the functionality is awesome! I have been doing encryption/decryption in the middle tier: it's great to be able to move this to the database - particularly as this makes it much easier to create reports in report server that otherwise had to use a custom assembly to decrypt data.
Copy the below into management studio and walk through it.
create database SecurityDemo
go
use SecurityDemo
go
-- Create a master key - this is used as the root of the encryption
-- hierarchy: all keys and certs are encrypted with this
-- it is scoped to the database
create master key encryption by password = <'pass@word1'>
-- Now we will create a simple table with a column that will store
-- national security numbers in encrypted form
create table people (
id int identity constraint pk_people_id primary key clustered,
firstname nvarchar(50),
lastname nvarchar(50),
encrypted_ninumber varbinary(128) )
go
-- Now lets create a certicate - we will use this to encrypt a key
-- this will give a warning about an invalid start date, but
-- we can ignore this since sql doesn't care about cert dates
create certificate ni_cert with subject = 'NI Certificate'
go
-- Now create a symmetric key to encrypt/decrypt the data
create symmetric key ni_key with algorithm = aes_256
encryption by certificate ni_cert
go
-- Now we will create a procedure to insert and encrypt the data
create procedure dbo.insert_people (
@firstname nvarchar(50),
@lastname nvarchar(50),
@ninumber nchar(9)
) as
-- open the symmetric key
open symmetric key ni_key decryption by certificate ni_cert
-- insert and encrypt the data
insert people(firstname, lastname, encrypted_ninumber)
values(
@firstname,
@lastname,
EncryptByKey(Key_GUID('ni_key'), @ninumber)
)
-- close the key now
close symmetric key ni_key
go
-- now lets insert some data
insert_people 'James', 'World', 'JZ123488B'
go
-- looking at this data, you can see its nice and encrypted
select * from people
go
-- ok, so lets create a procedure to decrypt this
create procedure dbo.select_person (
@id int
) as
open symmetric key ni_key decryption by certificate ni_cert
select
id,
firstname,
lastname,
convert(nchar(9),DecryptByKey(encrypted_ninumber)) as ninumber
from
people
close symmetric key ni_key
go
-- and try it out
exec select_person 1
go
-- how about if we want another use to call this spoc?
create login bob with password = <'pass@word1'>
go
create user bob for login bob
go
-- this won't work as bob has no permissions
execute as user='bob' -- lets us run in the context of bob
exec select_person 1
revert -- puts us back to our dbo context
go
-- let's give him some and then the above should work
grant execute on dbo.select_person to bob
grant references on symmetric key::ni_key to bob
-- eek!!! currently need to grant *control* permission to bob
-- in IDW15... hope this improves!
grant control on certificate::ni_cert to bob
-- now it works
execute as user='bob' -- lets us run in the context of bob
exec select_person 1
revert -- puts us back to our dbo context
go
-- lets take away bob's permissions
revoke execute on dbo.select_person to bob
revoke references on symmetric key::ni_key to bob
revoke control on certificate::ni_cert to bob
go
-- a new feature lets us create a view that automatically decrypts
-- the data
create view view_people as
select
id,
firstname,
lastname,
convert(
nchar(9),
DecryptByKeyAutoCert(cert_id('ni_cert'),
null, encrypted_ninumber)
) AS ninumber
from
people
go
select * from view_people
go
-- can bob look at this view? clearly he needs permission on the view
grant select on view_people to bob
go
-- lets try...
execute as user='bob'
select * from view_people
revert
go
-- hmmm! we got null - this is what anyone gets that doesn't
-- have an open key when they try to read encrypted data
-- lets grant him permissions - control of the cert and references on the key
grant control on certificate::ni_cert to bob
grant references on symmetric key::ni_key to bob
go
-- lets try again
execute as user='bob'
select * from view_people
revert
go
-- this works! and best of all we didn't have to manage
-- opening the key
-- if they fix the level of permissions required on the cert
-- then this will be an awesome way to manage encrypted data
-- current weakness of needing CONTROL permission for bob on the cert:
-- we can do this and remove the ability to decrypt our data!
execute as user='bob'
alter certificate ni_cert remove private key
revert
go
-- certs can be backed up and restored, but this still sucks
-- other than that, this is an awesome feature set!
Comments
Anonymous
June 16, 2009
PingBack from http://workfromhomecareer.info/story.php?id=34588Anonymous
June 16, 2009
PingBack from http://fixmycrediteasily.info/story.php?id=16911Anonymous
June 19, 2009
PingBack from http://edebtsettlementprogram.info/story.php?id=24292