数据加密 第五篇:非对称密钥

非对称密钥(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' )

 

参考文档:

CREATE ASYMMETRIC KEY (Transact-SQL)

ENCRYPTBYASYMKEY (Transact-SQL)

DECRYPTBYASYMKEY (Transact-SQL)