非對稱密鑰(Asymmetric Keys)跟對稱密鑰相對,它使用一對密鑰(算法),一個密鑰用於加密,另一個密鑰用於解密,加密的密鑰稱為私鑰(private key),解密的密鑰稱為公鑰(public key)。私鑰由一方安全保管,不能外泄,而公鑰則可以發給任何請求它的人。比如,你向銀行請求公鑰,銀行將公鑰發給你,你使用公鑰對消息加密,那么只有私鑰的持有人——銀行才能對你的消息解密。與對稱加密不同的是,銀行不需要將私鑰通過網絡發送出去,因此安全性大大提高。
跟對稱密鑰相比,非對稱密鑰提供的安全級別更高,付出的代價是消耗的資源更多。我們建議開發者避免使用非對稱密鑰對大量的數據進行加密和解密操作,推薦的做法是:對數據進行壓縮,使用對稱密鑰來加密壓縮之后的數據,由於對稱密鑰可能在數據傳遞過程中被竊取和破譯,因此,推薦使用非對稱密鑰來保護對稱密鑰。
舉個例子,發送方把對稱加密的密鑰使用非對稱加密的公鑰進行加密,發送出去;接收方使用私鑰進行解密得到對稱加密的密鑰,這樣,雙方使用對稱加密來進行溝通。
ENCRYPTBYASYMKEY()函數使用非對稱密鑰來加密數據,該函數加密的數據字節長度是有限度的,根據算法的不同,加密的長度限制不同:
- 對於RSA_512算法,最多加密53bytes;
- 對於RSA_1024算法,最多加密117bytes;
- 對於RSA_2048算法,最多加密245bytes;
在SQL Server中,證書和非對稱密鑰都使用RSA密鑰,是RSA密鑰的包裝(wrapper)。
非對稱密鑰是數據庫級別的安全實體。 默認情況下,該實體同時包含公共密鑰和私有密鑰。默認情況下,私鑰受數據庫主密鑰保護。 如果尚未創建數據庫主密鑰,則需要密碼來保護私鑰。
一,創建非對稱密鑰
非對稱密鑰可以通過文件來導入,也可以在SQL Server中創建。
CREATE ASYMMETRIC KEY asym_key_name [ FROM FILE = 'path_to_strong-name_file' ] [ WITH ALGORITHM = <algorithm> ] [ ENCRYPTION BY PASSWORD = 'password' ] <algorithm> ::= { RSA_4096 | RSA_3072 | RSA_2048 | RSA_1024 | RSA_512 }
參數注釋:
FROM FILE = 'path_to_strong-name_file':從文件導入已有的密鑰對,或從程序集或DLL文件導入公共密鑰。
在不使用FROM子句的情況下執行時,CREATE ASYMMETRIC KEY會生成一個新的密鑰對。加密的算法,推薦使用RSA_4096、RSA_3072和RSA_2048,而RSA_1024 和 RSA_512已經過時了。
對於新建的非對稱密鑰,可以使用密碼來保護私鑰,這需要在ENCRYPTION BY PASSWORD = 'password' 設置,如果省略該子句,那么使用數據庫主密鑰來保護私鑰。
舉個例子,創建一個新的非對稱密鑰,使用密碼保護密鑰:
CREATE ASYMMETRIC KEY PacificSales09 WITH ALGORITHM = RSA_2048 ENCRYPTION BY PASSWORD = '<enterStrongPasswordHere>'; GO
二,修改非對稱密鑰
修改非對稱密鑰,可以移除密鑰的私鑰,也可以修改保護私鑰的密碼。修改非對稱密鑰的語法如下:
ALTER ASYMMETRIC KEY Asym_Key_Name <alter_option> <alter_option> ::= <password_change_option> | REMOVE PRIVATE KEY <password_change_option> ::= WITH PRIVATE KEY ( <password_option> [ , <password_option> ] ) <password_option> ::= ENCRYPTION BY PASSWORD = 'strongPassword' | DECRYPTION BY PASSWORD = 'oldPassword'
參數注釋:
- REMOVE PRIVATE KEY:移除私鑰,但是保留公鑰
- ENCRYPTION BY PASSWORD ='strongPassword': 用於指定一個新的密鑰來保護私鑰
- DECRYPTION BY PASSWORD ='oldPassword':用於指定解密私鑰的舊密碼,如果私鑰被DMK保護,那么不需要改子句。
舉個例子,修改保護私鑰的密碼:
ALTER ASYMMETRIC KEY PacificSales09 WITH PRIVATE KEY ( DECRYPTION BY PASSWORD = '<oldPassword>', ENCRYPTION BY PASSWORD = '<enterStrongPasswordHere>'); GO
三,使用非對稱密鑰來加密和解密數據
用非對稱密鑰來加密和解密數據,需要用到以下函數:
ASYMKEY_ID ( 'Asym_Key_Name' ) EncryptByAsymKey ( Asym_Key_ID , { 'plaintext' | @plaintext } ) DecryptByAsymKey (Asym_Key_ID , { 'ciphertext' | @ciphertext } [ , 'Asym_Key_Password' ] )
在解密數據時,如果私鑰是用密碼來保護的,需要提供密碼(設置參數'Asym_Key_Password')來解密,如果密鑰是用DMK來解密的,那么不需要提供解密私鑰的密碼。
示例1,用非對稱密鑰來加密:
EncryptByAsymKey(AsymKey_ID('JanainaAsymKey02'), @cleartext)
示例2,用非對稱密鑰來解密,密鑰用密碼來解密。
DecryptByAsymKey( AsymKey_Id('JanainaAsymKey02'), CipherData, N'pGFD4bb925DGvbd2439587y' )
四,舉個例子
雖然非對稱加密很安全,但是和對稱加密比起來,它非常的慢,所以我們還是要用對稱加密來傳送消息,但對稱加密所使用的密鑰我們可以通過非對稱加密的方式發送出去。為了解釋這個過程,請看下面的例子:
(1) Alice需要在銀行的網站做一筆交易,她的瀏覽器首先生成了一個隨機數作為對稱密鑰。
(2) Alice的瀏覽器向銀行的網站請求公鑰。
(3) 銀行將公鑰發送給Alice。
(4) Alice的瀏覽器使用銀行的公鑰將自己的對稱密鑰加密。
(5) Alice的瀏覽器將加密后的對稱密鑰發送給銀行。
(6) 銀行使用私鑰解密得到Alice瀏覽器的對稱密鑰。
(7) Alice與銀行可以使用對稱密鑰來對溝通的內容進行加密與解密了。
參考文檔:
CREATE ASYMMETRIC KEY (Transact-SQL)