證書(Certificates)全稱是公鑰證書,是一種數字簽名語句,它把公鑰的值綁定到用戶、設備或服務的ID上,這些用戶、設備或服務ID擁有私鑰,而私鑰用於對數據進行解密。SQL Server中的證書同時包含公鑰和密鑰,前者用來加密,后者解密。為了保證私鑰的安全,證書的私鑰會被加密,可以使用數據庫主密鑰或密碼對證書的私鑰進行加密。視圖 sys.certificates的字段 pvt_key_encryption_type 表示私鑰加密的方式。
一,證書的應用和包含內容
證書實際上是一個非對稱密鑰,公鑰綁定到個人用戶,私鑰由證書發行機構保存。為了避免數據在傳輸的過程中被竊取,通常情況下,使用證書來加密對稱密鑰,而使用對稱密鑰來加密和解密數據。用戶使用證書的公鑰來加密對稱密鑰,並把對稱密鑰(由證書加密)和數據(由對稱密鑰加密)發送到證書發行結構;證書發行機構通過用戶的ID來識別證書,通過證書的私鑰來解密對稱密鑰,並通過對稱密鑰來解密數據。
接收證書的實體是證書的主題(Subject),證書包含的信息:
- 主題的公鑰
- 主題的標識符信息,例如名稱和電子郵件地址。
- 有效期,證書可用的開始和過期日期
- 證書發行機構的標識符信息
- 證書發行結構的數字簽名,該簽名證明了公鑰與主題的標識符信息之間的綁定的有效性。
簽名是指:對信息進行數字簽名的過程,需要把信息和發件人持有的秘密信息轉換為標簽,這個標簽就叫做簽名。
證書實際上是非對稱密鑰,包含一對密鑰。把公鑰授權給用戶,用戶使用公鑰加密;發行人用私鑰解密。
SQL Server可以在內部生成證書(即自簽名證書),也可以從外部文件或程序集載入。由於可以對證書進行備份,然后從文件中載入證書,這使得證書比非對稱密鑰更易於移植,而非對稱密鑰卻做不到,這意味着可以在數據庫中方便地重用同一個證書。
二,創建自簽名的證書
管理員使用CREATE CERTIFICATE命令來創建證書,以下命令用於創建自簽名的證書:
CREATE CERTIFICATE certificate_name [ ENCRYPTION BY PASSWORD = 'password' ] WITH SUBJECT = 'certificate_subject_name' [ , START_DATE = 'datetime' | EXPIRY_DATE = 'datetime']
參數注釋:
- ENCRYPTION BY PASSWORD ='password':指定用於加密私鑰的密碼。只有在使用密碼對證書進行加密證書時才會使用該選項;如果省略該選項,那么使用數據庫主密鑰(Database Master Key)來加密私鑰。
- SUBJECT ='certificate_subject_name':證書的主題名稱
- START_DATE 和 EXPIRY_DATE:用於指定證書的有效期
當創建自簽名的證書時,私鑰也會被創建,當使用ENCRYPTION BY PASSWORD = 'password' 時,表明使用密碼對私鑰進行加密;當省略該語句時,表明使用DMK對私鑰進行加密。
三,從文件創建證書
從已有的文件中創建證書,文件是CA頒發的證書,通過文件把證書加載到SQL Server中:
CREATE CERTIFICATE certificate_name FROMFILE = 'path_to_file' [ WITH PRIVATE KEY ( <private_key_options> ) ]<private_key_options> ::= { FILE = 'path_to_private_key' [ , DECRYPTION BY PASSWORD = 'password' ] [ , ENCRYPTION BY PASSWORD = 'password' ] }
參數注釋:
- File = 'paht_to_file':用於制定一個包含證書的DER編碼的文件,擴展名是.cer。
- WITH PRIVATE KEY:指定把證書的私鑰加載到SQL Server中。
- FILE ='path_to_private_key':用於制定私鑰的路徑
- DECRYPTION BY PASSWORD = 'key_password':指定密鑰,用於解密文件中的私鑰。如果私鑰不受密碼的保護,則此子句是可選的。不建議把私鑰保存到沒有密碼保護的文件中。
- ENCRYPTION BY PASSWORD = 'password':用於指定加密私鑰的密碼,只有當你想要通過密碼來加密私鑰時,使用該選項。如果省略該子句,SQL Server默認使用數據庫主密鑰來加密私鑰。
舉個例子,從已有的.cer文件來創建證書:
CREATE CERTIFICATE Shipping11 FROM FILE = 'c:\Shipping\Certs\Shipping11.cer' WITH PRIVATE KEY (FILE = 'c:\Shipping\Certs\Shipping11.pvk', DECRYPTION BY PASSWORD = 'sldkflk34et6gs%53#v00'); GO
還有其他方式來創建證書,詳細信息,請閱讀微軟文檔:CREATE CERTIFICATE (Transact-SQL)
四,證書重編碼
把證書和私鑰編碼為二進制,以二進制格式返回證書的公鑰部分:
CERTENCODED ( cert_id )
以二進制格式返回證書的私鑰部分,該函數以PVK格式來返回私鑰:
CERTPRIVATEKEY ( cert_ID , ' encryption_password ' [ , ' decryption_password ' ] )
證書ID可以通過函數Cert_ID('name')來獲得,也可以通過 sys.certificates 查詢獲得:
Cert_ID()
例子1:返回證書的二進制
在當前數據庫中創建自簽名證書,並返回證書的二進制形式:
CREATE CERTIFICATE Shipping04 ENCRYPTION BY PASSWORD = 'pGFD4bb925DGvbd2439587y' WITH SUBJECT = 'Sammamish Shipping Records', EXPIRY_DATE = '20401031'; GO SELECT CERTENCODED(CERT_ID('Shipping04')); SELECT CERTPRIVATEKEY(CERT_ID('Shipping04'), 'jklalkaa/; uia3dd');
例子2,使用證書的二進制來創建證書
在另一個數據庫中,利用證書和私鑰的二進制來創建證書
CREATE CERTIFICATE TARGET_CERT FROM BINARY = <insert the binary value of the @CERTENC variable> WITH PRIVATE KEY ( BINARY = <insert the binary value of the @CERTPVK variable> , DECRYPTION BY PASSWORD = 'jklalkaa/; uia3dd');
五,證書的加密和解密
證書本質上是一個非對稱密鑰,可以使用證書來加密和解密數據。
1,使用證書來加密
時使用證書的公鑰來加密數據,返回值的類型是varbinary,最大長度是8000Bytes。
EncryptByCert ( certificate_ID , { 'cleartext' | @cleartext } )
2,使用證書來解密
使用證書的私鑰來解密,私鑰是自動調用的:
DecryptByCert ( certificate_ID , { 'ciphertext' | @ciphertext } [ , { 'cert_password' | @cert_password } ] )
六,管理證書
證書的授權
證書是數據庫級別的Securable,管理員可以把已創建的證書授權給相應的人員來使用:
GRANT permission [ ,...n ] ON CERTIFICATE :: certificate_name TO principal [ ,...n ]
證書的備份
使用BACKUP CERTIFICATE導出證書,把證書存放在安全的地方保存:
BACKUP CERTIFICATE certname TO FILE = 'path_to_file' [ WITH PRIVATE KEY ( FILE = 'path_to_private_key_file' , ENCRYPTION BY PASSWORD = 'encryption_password' [ , DECRYPTION BY PASSWORD = 'decryption_password' ] ) ]
參數注釋:
- TO FILE = 'path_to_file':把證書的公鑰保存到文件中
- WITH PRIVATE KEY :把證書的私鑰保存到文件:
- ENCRYPTION BY PASSWORD = 'encryption_password':用於加密私鑰的密碼,在把私鑰寫入到備份文件之前,使用密碼對私鑰進行加密。
- DECRYPTION BY PASSWORD = 'decryption_password':用於解密私鑰的密碼,在把私鑰寫入到備份文件之前,使用密鑰對私鑰進行解密。如果使用數據庫主密鑰對私鑰進行加密,那么該參數省略。
舉個例子,把證書的公鑰和私鑰都進行備份,私鑰使用密碼進行解密和加密:
BACKUP CERTIFICATE sales09 TO FILE = 'c:\storedcerts\sales09cert' WITH PRIVATE KEY ( DECRYPTION BY PASSWORD = '9875t6#6rfid7vble7r' , FILE = 'c:\storedkeys\sales09key' , ENCRYPTION BY PASSWORD = '9n34khUbhk$w4ecJH5gh' ); GO
參考文檔: