http://www.netbei.com/2009/0604/5540.html
1.2 数据库主密钥
正如每个SQL Server有一个服务主密钥,每个数据库有自己的数据库主密钥 。数据库主密钥通过CREATE MASTER KEY语句生成:
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'password' |
这个语句创建数据库主密钥,使用指定的密码加密它,并保存在数据库中。同时,数据库主密钥也被使用服务主密钥加密之后保存在master数据库中,这就是所谓的“自动密钥管理 ”。这个特性我们待会再讲。
象服务主密钥一样,你可以备份和恢复数据库主密钥。使用BACKUP MASTER KEY备份数据库主密钥。语法类似于备份服务主密钥:
BACKUP MASTER KEY TO FILE = 'path_to_file' ENCRYPTION BY PASSWORD = 'password' |
恢复数据库主密钥使用RESTORE MASTER KEY语句,它需要使用DECRYPTION BY PASSWORD子句提供备份时指定的加密密码,还要使用ENCRYPTION BY PASSWORD子句,SQL Server使用它提供的密码来加密数据库主密钥之后保存在数据库中。
RESTORE MASTER KEY FROM FILE = 'path_to_file' DECRYPTION BY PASSWORD = 'password' ENCRYPTION BY PASSWORD = 'password' [ FORCE ] |
同样,FORCE表示你将忽略在解密过程中的错误。
建议你在创建了数据库主密钥之后立即备份数据库主密钥,并把它保存到一个安全的地方 。同样,使用FORCE语句可能导致已加密数据的丢失。
要删除数据库主密钥,使用DROP MASTER KEY语句,它删除当前数据库的主密钥。在执行之前,确定你在正确的数据库上下文中。
1.3 自动密钥管理
当创建数据库主密钥时,它被使用提供的密码加密然后被保存到当前数据库中。同时,它被使用服务主密钥加密并保存到master数据库中。这份保存的数据 库主密钥允许服务器在需要的时候解密数据库主密钥,这就是自动密钥管理。没有自动密钥管理的话,你必须在每次使用证书或密钥加密或解密数据(它需要使用数 据库主密钥)时使用OPEN MASTER KEY语句同时提供加密的密码。使用自动密钥管理,你不需要执行OPEN MASTER KEY语句,也不需要提供密码 。
自动密钥管理的缺点就是每个sysadmin角色的成员都能够解密数据库主密钥。你可以通过 ALTER MASTER KEY语句的DROP ENCRYPTION BY SERVICE MASTER KEY子句,从而不使用自动密钥管理。ALTER MASTER KEY的使用方法参见联机丛书。
2. 证书
2.1 创建证书
当你配置好服务主密钥和数据库主密钥后,你就可以创建证书了。SQL Server可以创建自签名的X.509证书。使用CREATE CERTIFICATE语句来创建证书:
CREATE CERTIFICATE certificate_name [ AUTHORIZATION user_name ] { FROM <existing_keys> | <generate_new_keys> } [ ACTIVE FOR BEGIN_DIALOG = { ON | OFF } ] <existing_keys> ::= ASSEMBLY assembly_name | { [ EXECUTABLE ] FILE = 'path_to_file' [ WITH PRIVATE KEY ( <private_key_options> ) ] } <generate_new_keys> ::= [ ENCRYPTION BY PASSWORD = 'password'] WITH SUBJECT = 'certificate_subject_name' [ , <date_options> [ ,...n ] ] <private_key_options> ::= FILE = 'path_to_private_key' [ , DECRYPTION BY PASSWORD = 'password' ] [ , ENCRYPTION BY PASSWORD = 'password' ] <date_options> ::= START_DATE = 'mm/dd/yyyy' | EXPIRY_DATE = 'mm/dd/yyyy' CREATE CERTIFICATE语句有这么多的选项,幸运的是,大多数时候只用到很少的选项。下面的语句创建一个使用密码来保护的证书: CREATE CERTIFICATE TestCertificate ENCRYPTION BY PASSWORD = 'thisIsAP@$$w0rd' WITH SUBJECT = 'This is a test certificate', START_DATE = '1/1/2006', EXPIRY_DATE = '12/31/2008'; |
如果不使用ENCRYPTION BY PASSWORD子句,证书将使用数据库主密钥来保护。如果不指定START_DATE子句,将使用执行此命令的日期来填写证书的Start Date字段。
除了CREATE CERTIFICATE,SQL Server还提供了DROP CERTIFICATE,ALTER CERTIFICATE,BACKUP CERTIFICATE语句来管理证书。
注:不使用RESTORE语句来恢复证书。使用CREATE CERTIFICATE语句来恢复已经备份的证书。
2.2 使用证书来加密和解密
通过内置的函数EncryptByCert,DecryptByCert和Cert_ID,可以使用证书来加密和解密数据。Cert_ID函数得到指定名字的证书的ID。格式为:
Cert_ID ( 'cert_name' ) cert_name为证书的名字。 EncryptByCert函数需要证书ID,格式为: EncryptByCert ( certificate_ID , { 'cleartext' | @cleartext } ) |
certificate_ID为通过Cert_ID函数得到的证书ID,cleartext为要加密的明文。类型为 nvarchar、char、varchar、binary、varbinary 或 nchar。Enc ryptByCert函数的返回值是最大大小为 8,000 个字节的 varbinary 。
DecryptByCert语句用来解密先前使用证书加密的数据。格式为:
DecryptByCert (certificate_ID, { 'ciphertext' | @ciphertext } [ , { 'cert_password' | @cert_password } ] )
同样,certificate_ID为通过Cert_ID函数得到的证书ID,ciphertext是加密后的数据。如果创建证书时使用了 ENCRYPT BY PASSWORD,则cert_password是当时创建时设定的密码,如果没有使用ENCRYPT BY PASSWORD,那这里也不需要cert_password。
下面的脚本创建数据库主密钥,创建一个测试证书,使用证书进行加密、解密。
-- Sample T-SQL Script to demonstrate Certificate Encryption -- Use the AdventureWorks database USE AdventureWorks; -- Create a Database Master Key CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'p@ssw0rd'; -- Create a Temp Table CREATE TABLE Person.#Temp (ContactID INT PRIMARY KEY, FirstName NVARCHAR(200), MiddleName NVARCHAR(200), LastName NVARCHAR(200), eFirstName VARBINARY(200), eMiddleName VARBINARY(200), eLastName VARBINARY(200)); -- Create a Test Certificate, encrypted by the D MK CREATE CERTIFICATE TestCertificate WITH SUBJECT = 'Adventureworks Test Certificate', EXPIRY_DATE = '10/31/2009'; -- EncryptByCert demonstration encrypts 100 names from the Person.Contact table INSERT INTO Person.#Temp (ContactID, eFirstName, eMiddleName, eLastName) SELECT ContactID, EncryptByCert (Cert_ID('TestCertificate'), FirstName), EncryptByCert(Cert_ID('TestCertificate'), MiddleName), EncryptByCert(Cert_ID('TestCertificate'), LastName) FROM Person.Contact WHERE ContactID <= 100; -- DecryptByCert demonstration decrypts the previously encrypted data UPDATE Person.#Temp SET FirstName = DecryptByCert (Cert_ID('TestCertificate'), eFirstName), MiddleName = DecryptByCert(Cert_ID('TestCertificate'), eMiddleName), LastName = DecryptByCert(Cert_ID('TestCertificate'), eLastName); -- View the results SELECT * FROM Person.#Temp; -- Clean up work: drop temp table, test certificate and master key DROP TABLE Person.#Temp; DROP CERTIFICATE TestCertificate; DROP MASTER KEY; |