SQLServer 数据加密解密:常用的加密解密(一)

来源:互联网 发布:虎鲨软件站 编辑:程序博客网 时间:2024/05/17 01:54

来源:http://blog.csdn.net/kk185800961/article/details/44871603

是基本示例,更多参考官方文档:

1. Transact-SQL 函数
2. 数据库密钥
3. 证书
4. 非对称密钥
5. 对称密钥


[sql] view plain copy
 print?
  1. --  drop table EnryptTest  
  2. create table EnryptTest  
  3. (  
  4.     id int not null primary key,  
  5.     EnryptData nvarchar(20),  
  6. )  
  7.   
  8. insert into EnryptTest  
  9. values(1,N'888888'),(2,N'888888'),(3,N'123456'),(4,N'A');  
  10.   
  11.   
  12. select * from EnryptTest;  

【Transact-SQL 函数加密】

[sql] view plain copy
 print?
  1. /***********************************【Transact-SQL 函数加密】********************************/  
  2. --  使用 TRIPLE DES 算法(128 密钥位长度)的通行短语加密数据。  
  3.   
  4.   
  5. --  添加测试列  
  6. alter table EnryptTest add PassPhrase varbinary(256)  
  7. alter table EnryptTest add PassPhrase2 varbinary(256)--用于验证器验证  
  8.   
  9.   
  10. --  加密(EncryptByPassPhrase)  
  11. --  https://technet.microsoft.com/zh-cn/library/ms190357%28v=sql.105%29.aspx?f=255&MSPPError=-2147217396  
  12. update EnryptTest set PassPhrase = EncryptByPassPhrase('Hello.kk',EnryptData)  
  13. go  
  14.   
  15. update EnryptTest   
  16. set PassPhrase2 = EncryptByPassPhrase  
  17.     (  
  18.       'Hello.kk'            --用于生成对称密钥的通行短语  
  19.     , EnryptData            --要加密的明文  
  20.     , 1                     --指示是否将验证器与明文一起加密。如果将添加验证器,则为 1  
  21.     , convert(varbinary,id) --用于派生验证器的数据(如 主键)  
  22.     )  
  23. go  
  24.   
  25. --  解密(DecryptByPassPhrase)  
  26. --  https://technet.microsoft.com/zh-cn/library/ms188910%28v=sql.105%29.aspx?f=255&MSPPError=-2147217396  
  27.   
  28. select convert(nvarchar,DecryptByPassphrase('Hello.kk',PassPhrase)) from EnryptTest;  
  29. go  
  30.   
  31. select convert(nvarchar,DecryptByPassphrase(  
  32.       'Hello.kk'    --生成解密密钥的通行短语  
  33.     , PassPhrase2   --要解密的加密文本varbinary   
  34.     , 1             --添加验证器  
  35.     , convert(varbinary,id)))--验证器为主键  
  36. from EnryptTest;  
  37. go  
  38.   
  39.   
  40. --附:未用验证器的,数据并不安全  
  41. --如:把所有id的密码都改为与A一样,其他密码的解密与A一样,别人就有可能登录其他账号  
  42. update EnryptTest set PassPhrase = (select PassPhrase from EnryptTest where id=4)  
  43. go  
  44. select id,EnryptData,convert(nvarchar,DecryptByPassphrase('Hello.kk',PassPhrase))   
  45. from EnryptTest;  
  46.   
  47.   
  48. --  删除测试列  
  49. alter table EnryptTest drop column PassPhrase   
  50. alter table EnryptTest drop column PassPhrase2  
  51. go  


[sql] view plain copy
 print?
  1. DECLARE @ENPWD VARBINARY(MAX)   
  2. DECLARE @DEPWD NVARCHAR(100)  
  3. DECLARE @ENSTR NVARCHAR(100)    
  4. SET @ENSTR = 'hello.KK' --加密密码  
  5. --加密  
  6. SELECT @ENPWD = ENCRYPTBYPASSPHRASE( @ENSTR, N'13500000000')  
  7. SELECT @ENPWD  
  8. --解密  
  9. SELECT @DEPWD =CAST( DECRYPTBYPASSPHRASE(@ENSTR,@ENPWD) AS NVARCHAR(MAX))  
  10. SELECT @DEPWD  
  11. go  


【数据库主密钥】

[sql] view plain copy
 print?
  1. /***************************************【数据库主密钥】***********************************/  
  2.   
  3. select * from sys.key_encryptions  
  4. select * from sys.crypt_properties  
  5.   
  6. --  创建数据库主密钥  
  7. --  https://technet.microsoft.com/zh-cn/library/ms174382(v=sql.105).aspx  
  8. create master key encryption by password = N'Hello@MyMasterKey' --必须符合Windows密码策略要求  
  9. go  
  10.   
  11. --  打开当前数据库的数据库主密钥  
  12. --  https://technet.microsoft.com/zh-cn/library/ms186336(v=sql.105).aspx  
  13. open master key decryption by password = N'Hello@MyMasterKey'  
  14. go  
  15.   
  16. --  更改数据库主密钥的属性  
  17. --  https://technet.microsoft.com/zh-cn/library/ms186937(v=sql.105).aspx  
  18. alter master key regenerate with encryption by password = N'Hello@MyMasterKey'  
  19.   
  20. alter master key add encryption by password = N'Hello@kk'  
  21. alter master key drop encryption by password = N'Hello@kk'  
  22.   
  23. alter master key add encryption by service master key  
  24. alter master key drop encryption by service master key  
  25.   
  26. --  导出数据库主密钥  
  27. --  https://technet.microsoft.com/zh-cn/library/ms174387(v=sql.105).aspx  
  28. backup master key   
  29. to file = N'D:\XXDB_MasterKey'   
  30. encryption by password = N'Hello@MyMasterKey'  
  31. go  
  32.   
  33. --  从备份文件中导入数据库主密钥  
  34. --  https://technet.microsoft.com/zh-cn/library/ms186336(v=sql.105).aspx  
  35. restore master key   
  36.     from file = N'D:\XXDB_MasterKey'  
  37.     decryption by password = N'Hello@MyMasterKey'  
  38.     encryption by password = N'Hello@MyMasterKey' --New Password  
  39. go  
  40.   
  41. --  从当前数据库中删除主密钥  
  42. --  https://technet.microsoft.com/zh-cn/library/ms180071(v=sql.105).aspx  
  43. drop master key  
  44. go  

【证书】

[sql] view plain copy
 print?
  1. /*****************************************【证书】*************************************/  
  2. --  证书和非对称密钥使用数据库级的内部公钥加密数据,并且使用数据库级内部私钥解密数据  
  3. --  当使用数据库主密钥对私钥进行加密时,不需要 ENCRYPTION BY PASSWORD 选项。私钥使用数据库主密钥进行加密  
  4. --(有点难理解,最后给出例子)  
  5.   
  6. select * from sys.key_encryptions  
  7. select * from sys.crypt_properties  
  8. select * from sys.certificates  
  9.   
  10. select * from EnryptTest  
  11.   
  12. --  添加测试列  
  13. alter table EnryptTest add CertificateCol varbinary(max)  
  14. go  
  15.   
  16. --  创建证书  
  17. --  https://technet.microsoft.com/zh-cn/library/ms187798%28v=sql.105%29.aspx?f=255&MSPPError=-2147217396  
  18. create certificate Mycertificate  
  19. encryption by password = N'Hello@Mycertificate' --加密密码  
  20. with subject = N'EnryptData certificate',       --证书描述    
  21. start_date = N'20150401',   --证书生效日   
  22. expiry_date = N'20160401';  --证书到期日    
  23. go  
  24.   
  25. --  使用证书的公钥加密数据  
  26. --  https://msdn.microsoft.com/zh-cn/library/ms188061(v=sql.105).aspx  
  27. update EnryptTest   
  28. set CertificateCol = EncryptByCert(CERT_ID('Mycertificate'),CONVERT(VARCHAR(MAX),EnryptData))  
  29. go  
  30.   
  31. --  用证书的私钥解密数据  
  32. --  https://msdn.microsoft.com/zh-cn/library/ms178601(v=sql.105).aspx  
  33. select *,CONVERT(VARCHAR(MAX ),DECRYPTBYCERT(CERT_ID('Mycertificate'),CertificateCol,N'Hello@Mycertificate'))  
  34. from EnryptTest;  
  35. go  
  36.   
  37. --  修改私钥密码   
  38. --  https://msdn.microsoft.com/zh-cn/library/ms189511(v=sql.105).aspx  
  39. alter certificate mycertificate   
  40. with private key (  
  41.     decryption by password = N'Hello@Mycertificate',   
  42.     encryption by password = N'Hello@Mycertificate')  
  43. go  
  44.   
  45. --  从证书中删除私钥   
  46. alter certificate mycertificate remove private key  
  47. go  
  48.   
  49. --  备份证书  
  50. --  https://msdn.microsoft.com/zh-cn/library/ms178578(v=sql.105).aspx  
  51. backup certificate mycertificate   
  52. to file = N'D:\mycertificate.cer' --用于加密的证书备份路径  
  53. with private key (   
  54.     file = N'D:\mycertificate_saleskey.pvk' , --用于解密证书私钥文件路径   
  55.     decryption by password = N'Hello@Mycertificate' ,--对私钥进行解密的密码  
  56.     encryption by password = N'Hello@Mycertificate' );--对私钥进行加密的密码  
  57. go  
  58.   
  59. --  创建/还原证书  
  60. create certificate mycertificate   
  61. from file = N'D:\mycertificate.cer'   
  62. with private key (  
  63.     file = N'D:\mycertificate_saleskey.pvk',   
  64.     decryption by password = 'Hello@Mycertificate');  
  65. go  
  66.   
  67. --  删除对称密钥  
  68. --  https://msdn.microsoft.com/zh-cn/library/ms182698(v=sql.105).aspx  
  69. drop certificate  Mycertificate;  
  70. go  
  71.   
  72. --  删除测试列  
  73. alter table EnryptTest drop column CertificateCol;  
  74. go  

【非对称密钥】

[sql] view plain copy
 print?
  1. /***************************************【非对称密钥】*************************************/  
  2. --  默认情况下,私钥受数据库主密钥保护  
  3.   
  4. select * from sys.key_encryptions  
  5. select * from sys.crypt_properties  
  6. select * from sys.certificates  
  7. select * from sys.asymmetric_keys  
  8. select * from sys.openkeys  
  9.   
  10. select * from EnryptTest  
  11.   
  12. --  添加测试列  
  13. alter table EnryptTest add AsymmetricCol varbinary(max)  
  14. go  
  15.   
  16. --  创建非对称密钥  
  17. --  https://msdn.microsoft.com/zh-cn/library/ms174430(v=sql.105).aspx  
  18. create asymmetric key MyAsymmetric   
  19. with   
  20.     algorithm=rsa_512   
  21.     encryption by password='Hello@MyAsymmetric';  
  22. go    
  23.   
  24. --  加密(EncryptByAsymKey)  
  25. --  https://msdn.microsoft.com/ZH-CN/library/ms186950(v=sql.105).aspx  
  26. update EnryptTest   
  27. set AsymmetricCol = EncryptByAsymKey(asymkey_id ('MyAsymmetric'),convert(varchar(max ),EnryptData))    
  28. go  
  29.   
  30. --  解密(DecryptByAsymKey)  
  31. --  https://msdn.microsoft.com/ZH-CN/library/ms189507(v=sql.105).aspx  
  32. select *,convert(varchar(max),DecryptByAsymKey(asymkey_id('MyAsymmetric'),AsymmetricCol,N'Hello@MyAsymmetric'))  
  33. from EnryptTest  
  34. go  
  35.   
  36. --  更改非对称密钥属性  
  37. --  https://msdn.microsoft.com/zh-cn/library/ms187311(v=sql.105).aspx  
  38.   
  39. --  更改私钥密码  
  40. alter asymmetric key MyAsymmetric   
  41.     with private key (  
  42.     decryption by password = N'Hello@MyAsymmetric',--原私钥密码  
  43.     encryption by password = N'Hello@MyAsymmetric');--新私钥密码  
  44. go  
  45.   
  46. --  删除私钥,只保留公钥  
  47. --  如果将非对称密钥映射到 EKM 设备上的可扩展密钥管理 (EKM) 密钥并且未指定 REMOVE PROVIDER KEY 选项,  
  48. --  则会从数据库中删除该密钥,但不会从设备上删除它。这时会发出一条警告。  
  49. alter asymmetric key MyAsymmetric remove private key;  
  50. go  
  51.   
  52. --  删除非对称密钥  
  53. --  https://msdn.microsoft.com/ZH-CN/library/ms188389(v=sql.105).aspx  
  54. drop symmetric key MyAsymmetric ;  
  55. go  
  56.   
  57. --  删除测试列  
  58. alter table EnryptTest drop column AsymmetricCol  
  59. go  

【对称密钥】

[sql] view plain copy
 print?
  1. /***************************************【对称密钥】*************************************/  
  2. --  也称为单密钥加密,采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密.  
  3. --  非对称密钥消耗多些系统性能,一般使用对称密钥加密数据,使用非对称密钥保护对称密钥  
  4.   
  5. select * from sys.key_encryptions  
  6. select * from sys.crypt_properties  
  7. select * from sys.certificates  
  8. select * from sys.asymmetric_keys  
  9. select * from sys.openkeys  
  10. select * from sys.symmetric_keys  
  11.   
  12. select * from EnryptTest  
  13.   
  14. --  添加测试列  
  15. alter table EnryptTest add SymmetricCol varbinary(max)  
  16. go  
  17.   
  18. --  创建对称密钥  
  19. --  https://msdn.microsoft.com/zh-cn/library/ms188357(v=sql.105).aspx  
  20. create symmetric key MySymmetric    --以密码加密的对称密钥  
  21. with   
  22.     algorithm=aes_128   
  23.     encryption by password='Hello@MySymmetric';  
  24. go  
  25. create symmetric key MySymmetric    --以非对称密钥加密的对称密钥  
  26. with   
  27.     algorithm=aes_128   
  28.     encryption by asymmetric key MyAsymmetric  
  29. go  
  30.   
  31. --  打开对称密钥(打开才能有效使用加密解密函数)  
  32. --  https://msdn.microsoft.com/zh-cn/library/ms190499(v=sql.105).aspx  
  33. open symmetric key MySymmetric decryption by password='Hello@MySymmetric';  
  34. go  
  35. open symmetric key MySymmetric decryption by asymmetric key MyAsymmetric with password='Hello@MyAsymmetric';  
  36. go  
  37.   
  38. --  加密数据  
  39. --  https://technet.microsoft.com/zh-cn/library/ms174361%28v=sql.105%29.aspx?f=255&MSPPError=-2147217396  
  40. update EnryptTest set SymmetricCol = encryptbykey(key_guid('MySymmetric'),convert(varchar(max),EnryptData))  
  41. go  
  42.   
  43. --  解密数据  
  44. --  https://technet.microsoft.com/zh-cn/library/ms181860(v=sql.105).aspx  
  45. select *,convert(varchar(max ) ,convert (varchar(max ),decryptbykey(SymmetricCol)))    
  46. from EnryptTest  
  47. go  
  48.   
  49. --  关闭对称密钥,或关闭在当前会话中打开的所有对称密钥  
  50. --  https://msdn.microsoft.com/zh-cn/library/ms177938%28v=sql.105%29.aspx?f=255&MSPPError=-2147217396  
  51. --  close all symmetric keys;   
  52. close symmetric key MySymmetric;  
  53. go  
  54.   
  55. --  alter symmetric 添加或删除新的加密方式(如添加多多个密码,任何一个密码都可用)  
  56. --  https://msdn.microsoft.com/zh-cn/library/ms189440(v=sql.105).aspx  
  57.   
  58. open symmetric key MySymmetric decryption by password='Hello@MySymmetric';  
  59.   
  60. alter symmetric key MySymmetric add encryption by password = 'Hello@kk' --New another Password  
  61.   
  62. close symmetric key MySymmetric;  
  63.   
  64. open symmetric key MySymmetric decryption by password='Hello@kk'--Use New Password  
  65.   
  66. select convert(varchar(max ) ,convert (varchar(max ),decryptbykey(SymmetricCol))) from EnryptTest  
  67.   
  68. alter symmetric key MySymmetric drop encryption by password = 'Hello@kk'--Drop the new Password  
  69.   
  70. close symmetric key MySymmetric;  
  71. go  
  72.   
  73. --  删除对称密钥  
  74. --  https://msdn.microsoft.com/zh-cn/library/ms182698(v=sql.105).aspx  
  75. drop symmetric key MySymmetric;  
  76. go  
  77.   
  78. --  删除测试列  
  79. alter table EnryptTest drop column SymmetricCol  
  80. go  

【主密钥证书示例】

[sql] view plain copy
 print?
  1. --  测试数据  
  2. /*  
  3. drop certificate  Mycertificate;  
  4. go  
  5. drop master key  
  6. go  
  7. drop table EnryptTest  
  8. go  
  9. */  
  10. create table EnryptTest  
  11. (  
  12.     id int not null primary key,  
  13.     EnryptData nvarchar(20),  
  14. )  
  15. go  
  16.   
  17. insert into EnryptTest  
  18. values(1,N'888888'),(2,N'888888'),(3,N'123456'),(4,N'A');  
  19. go  
  20.   
  21. select * from EnryptTest;  
  22.   
  23. alter table EnryptTest add CertificateCol varbinary(max)  
  24. go  
  25.   
  26.   
  27.   
  28. --创建主密钥  
  29. create master key encryption by password = N'Hello@MyMasterKey'  
  30. go  
  31. /*  
  32. key_id  thumbprint  crypt_type  crypt_type_desc             crypt_property  
  33. ------  ----------  ----------  ---------------------   ------------------  
  34. 101     0x01        ESKM        ENCRYPTION BY MASTER KEY    0x7A2FEDA8139F1DE8F3377424C120DBDB8E1F7EAAEC1BBD73E72AC04F5CEECBFAC15FC7E130CA1756281EA0D8E6997F44  
  35. 101     NULL        ESKP        ENCRYPTION BY PASSWORD      0x61D8F28F12CE4A1247F91E0ED828F2E937206E5D69B0754EE76756567AB428CBD5B54B76BCD1FC15E5E12202DBA4E187  
  36. */  
  37.   
  38. --创建证书,因为默认使用主密钥加密,此处不需要密码  
  39. create certificate Mycertificate  
  40. with subject = N'EnryptData certificate',  
  41. start_date = N'20150401',  
  42. expiry_date = N'20160401';  
  43. go  
  44.   
  45. --加密解密都自动使用服务主密钥加密了。即使使用“close master key ”也不起作用  
  46. update EnryptTest   
  47. set CertificateCol = EncryptByCert(CERT_ID('Mycertificate'),CONVERT(VARCHAR(MAX),EnryptData))  
  48. go  
  49. select *,CONVERT(VARCHAR(MAX ),DECRYPTBYCERT(CERT_ID('Mycertificate'),CertificateCol))   
  50. from EnryptTest;  
  51. go  
  52.   
  53. --现在删除“服务主密钥”  
  54. alter master key drop encryption by service master key  
  55. go  
  56.   
  57. --再查询数据,没有解密出来。不自动使用主密钥加密解密了  
  58. select *,CONVERT(VARCHAR(MAX ),DECRYPTBYCERT(CERT_ID('Mycertificate'),CertificateCol))   
  59. from EnryptTest;  
  60. go  
  61.   
  62. --这时需要显式打开主密钥,使用主密钥密码加密解密  
  63. open master key decryption by password = N'Hello@MyMasterKey'  
  64. go  
  65.   
  66. --再查询数据,解密出来了。  
  67. select *,CONVERT(VARCHAR(MAX ),DECRYPTBYCERT(CERT_ID('Mycertificate'),CertificateCol))   
  68. from EnryptTest;  
  69. go  
  70.   
  71. --最后关闭主密钥  
  72. close master key   
  73. go  
  74.   
  75. --查看主密钥,少了"ENCRYPTION BY MASTER KEY",没有了主密钥进行加密,而是使用密码进行加密  
  76. select * from sys.key_encryptions  
  77. /*  
  78. key_id  thumbprint  crypt_type  crypt_type_desc         crypt_property  
  79. ------  ----------  ----------  ---------------------   ------------------  
  80. 101     NULL        ESKP        ENCRYPTION BY PASSWORD  0xFB7D746C3CF0471147ECD710B1173B69A966421089FBB813BCF108E1ED90574F5C5F0998BA44F48869E05E9093BC59E6  
  81. */  
  82.   
  83.   
  84. --删除测试数据  
  85. drop certificate  Mycertificate;  
  86. go  
  87. drop master key  
  88. go  
  89. drop table EnryptTest  
  90. go  
  91.   
  92.   
  93. 参考:  
  94. 服务主密钥:https://msdn.microsoft.com/zh-cn/library/ms189060(v=sql.90).aspx  


【证书备份还原示例】

[sql] view plain copy
 print?
  1. --  drop table EnryptTest    
  2. create table EnryptTest    
  3. (    
  4.     id int not null primary key,    
  5.     EnryptData nvarchar(20),    
  6. )   
  7. go   
  8.   
  9. insert into EnryptTest    
  10. values(1,N'888888'),(2,N'888888'),(3,N'123456'),(4,N'A');    
  11. go  
  12.   
  13. alter table EnryptTest add CertificateCol varbinary(max)  --证书加密的列  
  14. go    
  15.   
  16. select * from EnryptTest;   
  17.   
  18.   
  19. --将相关信息删除  
  20. drop certificate  Mycertificate;  
  21. go    
  22. drop master key    
  23. go    
  24.   
  25.   
  26. --  创建以密码加密的证书  
  27. create certificate Mycertificate    
  28. encryption by password = N'Hello@Mycertificate'  
  29. with subject = N'EnryptData certificate',   
  30. start_date = N'20150401',  
  31. expiry_date = N'20160401';   
  32. go    
  33.   
  34.   
  35. --  证书加密数据  
  36. update EnryptTest set CertificateCol = EncryptByCert(CERT_ID('Mycertificate'),CONVERT(VARCHAR(MAX),EnryptData))    
  37. go  
  38.   
  39. --  解密(正常)  
  40. select *,convert(varchar(max ),decryptbycert(cert_id('Mycertificate'),CertificateCol,N'Hello@Mycertificate'))   
  41. from EnryptTest;    
  42. go   
  43.   
  44. --  备份证书  
  45. backup certificate mycertificate     
  46. to file = N'D:\mycertificate.cer'    
  47. with private key (     
  48.     file = N'D:\mycertificate_saleskey.pvk' ,  
  49.     decryption by password = N'Hello@Mycertificate' ,  
  50.     encryption by password = N'Hello@Mycertificate' );  
  51. go  
  52.   
  53. --  删除证书  
  54. drop certificate  Mycertificate;  
  55. go  
  56.   
  57. --  解密(失败)  
  58. select *,convert(varchar(max ),decryptbycert(cert_id('Mycertificate'),CertificateCol,N'Hello@Mycertificate'))   
  59. from EnryptTest;    
  60. go   
  61.   
  62. --  还原证书  
  63. create certificate mycertificate     
  64. from file = N'D:\mycertificate.cer'     
  65. with private key (    
  66.     file = N'D:\mycertificate_saleskey.pvk',     
  67.     decryption by password = N'Hello@Mycertificate' ,    
  68.     encryption by password = N'Hello@Hello.KK' );  --新证书密码  
  69. go  
  70.   
  71. --  解密(正常)  
  72. select *,convert(varchar(max ),decryptbycert(cert_id('Mycertificate'),CertificateCol,N'Hello@Hello.KK')) --新证书密码  
  73. from EnryptTest;    
  74. go   
  75.   
  76. --  删除测试数据  
  77. drop certificate  Mycertificate;  
  78. go   
  79. drop table EnryptTest   
  80. go  
  81.   
  82.   
  83. 没有数据库主密钥情况下,使用密码加密的证书。证书直接加密解密数据,备份还原后,对之前的加密数据仍正常解密,因为备用还原都是同一个证书。而使用证书加密的对称密钥,对称密钥不能备份,删除重建后,key_guid不一样了,之前使用对称密钥加密的数据已经不能使用新的对称密钥解密了。查看select * from sys.symmetric_keys,可以看到不一样了。  


加密解密函数:https://msdn.microsoft.com/zh-cn/library/ms173744.aspx

插图2张:

原创粉丝点击