zoukankan      html  css  js  c++  java
  • TDE与列级数据加密

    一、测试TDE
    此部分内容扩展SQL Server安全系列的第九篇:SQL Server安全透明数据加密的测试TDE章节。启用TDE的详细步骤请参考原文。

    -- Create a test database
    CREATE DATABASE UestDB
    GO
    -- Create a certificate in master to use with TDE
    USE master;
    GO
    -- TDE hooks into encryption key hierarchy in SQL Server
    CREATE MASTER KEY ENCRYPTION BY PASSWORD = '!drJP9QXC&Vi%cs';
    GO
    -- Create the certificate used to protect the database encryption key
    CREATE CERTIFICATE UestDBTDECert WITH SUBJECT = 'Certificate to implement TDE on UestDB';
    GO
    
    -- Backup the master_key
    BACKUP MASTER KEY TO FILE = 'D:SQL2012MasterKey.bak' ENCRYPTION BY PASSWORD = 'pass';
    GO
    -- Backup the certificate
    -- Either create the D:SQL2012 folder or change it in the code below
    BACKUP CERTIFICATE UestDBTDECert TO FILE = 'D:SQL2012UestDBTDECert'
        WITH PRIVATE KEY ( FILE = 'D:SQL2012UestDBTDECertPrivateKey' , 
        ENCRYPTION BY PASSWORD = 'RISiS9Ul%CByEk6' );
    GO
    -- Must backup private key as well
    View Code

    代码1 创建主密钥、证书并备份主密钥、证书

    USE UestDB;
    GO
    -- Create the database encryption key for TDE. Analogous to database master key for data encryption.
    CREATE DATABASE ENCRYPTION KEY 
        WITH ALGORITHM = TRIPLE_DES_3KEY
        ENCRYPTION BY SERVER CERTIFICATE UestDBTDECert;
    GO
    -- Get a warning about backing up the key, if you haven't already
    -- ...take the advice and back it up!
    
    -- Now need to turn TDE on. 
    ALTER DATABASE UestDB SET ENCRYPTION ON;
    GO
    View Code

    代码2 创建数据库加密密钥并启用TDE
    接下来模拟证书和主库密钥丢失的情况
    ->1 del master_key + certificate
    ->2 create master_key + certificate
    ->3 create master_key + restore certificate
    ->4 restore master_key + certificate
    首先备份UestDB数据库

    --backup test database
    BACKUP DATABASE UestDB
        TO DISK = N'D:SQL2012MSSQL11.SQL12MSSQLBackupUestDB.bak'
        WITH NOFORMAT, INIT, NAME = N'UestDB Full Database Backup',
        SKIP, NOREWIND, NOUNLOAD, COMPRESSION, STATS = 10;
    GO
    View Code

    代码3 备份数据库
    1、删除证书、删除master_key+重启数据库服务

    USE master
    GO
    -- Oops! We lost the certificate and don't have a copy!
    -- Or, going to restore the database to another server instance
    DROP CERTIFICATE UestDBTDECert; 
    GO
    DROP MASTER KEY;
    GO
    View Code

    证书'UestDBTDECert'是由主密钥加密的,因此需先删除证书才能删除master_key。重启数据库服务后在对象资源管理器下展开UestDB数据报错:


    图1 UestDB不能访问
    查看ERRORLOG日志如下所示:

    图2 删除证书、删除master_key
    2、用源代码重新创建master_key、创建证书+重启数据库服务

    -- Create a certificate in master to use with TDE
    USE master;
    GO
    -- TDE hooks into encryption key hierarchy in SQL Server
    CREATE MASTER KEY ENCRYPTION BY PASSWORD = '!drJP9QXC&Vi%cs';
    GO
    -- Create the certificate used to protect the database encryption key
    CREATE CERTIFICATE UestDBTDECert WITH SUBJECT = 'Certificate to implement TDE on UestDB';
    GO
    View Code

    重启数据库服务后,UestDB库依然不能访问,ERRORLOG日志如下所示:

    图3 重新创建master_key、创建证书
    3、用源代码重新创建master_key、还原证书+重启数据库服务

    -- Clean up
    USE master;
    GO
    DROP CERTIFICATE UestDBTDECert;
    GO
    DROP MASTER KEY;
    GO
    -- TDE hooks into encryption key hierarchy in SQL Server
    CREATE MASTER KEY ENCRYPTION BY PASSWORD = '!drJP9QXC&Vi%cs';
    GO
    -- Restore the certificate
    CREATE CERTIFICATE UestDBTDECert
        FROM FILE = 'D:SQL2012UestDBTDECert'
        WITH PRIVATE KEY ( FILE = 'D:SQL2012UestDBTDECertPrivateKey', 
        DECRYPTION BY PASSWORD = 'RISiS9Ul%CByEk6');
    View Code

    重启数据库服务后,UestDB数据库能正常访问(实际上创建mater_key使用其他密码也可以,总结来说就是证书一定要有备份),ERRORLOG日志如下所示:

    图4 重新创建master_key、还原证书
    4、还原master_key、还原证书+重启数据库服务

    -- Clean up
    USE master;
    GO
    DROP CERTIFICATE UestDBTDECert;
    GO
    DROP MASTER KEY;
    GO
    -- Restore the master_key
    RESTORE MASTER KEY FROM FILE='D:SQL2012MasterKey.bak'
    DECRYPTION BY PASSWORD ='pass'--备份数据库主密钥时指定的密码
    ENCRYPTION BY PASSWORD ='newpass'--数据库主密钥使用的新密码,除非重新应用Service Master Key的加密,否则需使用此密码显示打开和关闭数据库主密钥)
    GO
    --打开数据库主密钥
    OPEN MASTER KEY DECRYPTION BY PASSWORD = 'newpass'
    -- Restore the certificate
    CREATE CERTIFICATE UestDBTDECert
        FROM FILE = 'D:SQL2012UestDBTDECert'
        WITH PRIVATE KEY ( FILE = 'D:SQL2012UestDBTDECertPrivateKey', 
        DECRYPTION BY PASSWORD = 'RISiS9Ul%CByEk6');
    --关闭数据库主密钥
    CLOSE MASTER KEY
    View Code

    ERRORLOG日志如下所示:

    图5 还原master_key、还原证书(未应用Service Master Key的加密)
    “在执行此操作之前,请在数据库中创建一个主密钥或在会话中打开该主密钥。”此时UestDB数据库不能访问,想想在我们创建证书的时候如果没有用密码打开master key也会报这样的错,这是由于还原出来master key只使用了密码加密,而没有使用Service Master Key加密。因此对于相关的密钥、证书操作都要先使用OPEN MASTER KEY。下面我们在还原master key之后,重新应用Service Master Key的加密

    -- Clean up
    USE master;
    GO
    DROP CERTIFICATE UestDBTDECert;
    GO
    DROP MASTER KEY;
    GO
    -- Restore the master_key
    RESTORE MASTER KEY FROM FILE='D:SQL2012MasterKey.bak'
    DECRYPTION BY PASSWORD ='pass'--备份数据库主密钥时指定的密码
    ENCRYPTION BY PASSWORD ='newpass'--数据库主密钥使用的新密码,除非重新应用Service Master Key的加密,否则需使用此密码显示打开和关闭数据库主密钥)
    GO
    --打开数据库主密钥
    OPEN MASTER KEY DECRYPTION BY PASSWORD = 'newpass'
    --重新应用Service Master Key的加密
    ALTER MASTER KEY ADD ENCRYPTION BY SERVICE MASTER KEY--执行后,数据库主密钥不再需要被显式打开或关闭,拥有足够许可(如sysadmin)的用户自动使用数据库主密钥解密
    --关闭数据库主密钥
    CLOSE MASTER KEY
    -- Restore the certificate
    CREATE CERTIFICATE UestDBTDECert
        FROM FILE = 'D:SQL2012UestDBTDECert'
        WITH PRIVATE KEY ( FILE = 'D:SQL2012UestDBTDECertPrivateKey', 
        DECRYPTION BY PASSWORD = 'RISiS9Ul%CByEk6');
    View Code

    ERRORLOG日志如下所示:

    图6 还原master_key、还原证书(重新应用Service Master Key的加密)
    意外收获:在自己电脑上测试,频繁重启数据库服务,导致SSMS卡死,相关代码却没有保存。等待一段时候SSMS还是未响应:

    图7 SSMS未响应
    到相关目录寻找是否有临时文件保存了代码

    图8 C:UsersAdministratorDocumentsSQL Server Management StudioBackup FilesSolution1
    第二天打开SSMS提示

    图9
    点击恢复选定的文件,到相应目录查找C:UsersAdministratorAppDataLocalTemp

    图10
    算是幸运,文件在当时已经找到。还是要养成随时保存脚本的习惯!
    二、列数据加密
    此部分内容扩展SQL Server安全系列的第八篇:SQL Server安全数据加密。列数据加密的详细步骤请参考原文。本节重点关注列数据加密迁移及非对称密钥和对称密钥的修改。
    首先,我们继续使用本篇第一部分创建的UestDB数据库,创建测试使用的表:

    USE UestDB
    GO
    IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[LoginsInfo]') AND type in (N'U'))
    DROP TABLE [dbo].[LoginsInfo]
    GO
    CREATE TABLE [LoginsInfo](
        [Id] [int] IDENTITY(1,1) NOT NULL,
        [Item] [varchar](20) NULL,
        [LoginName] [varchar](30) NULL,
        [PassWords] [varbinary](1000) NULL,
        [Notes] [varbinary](1000) NULL,--alter(varchar->varbinary)
        [BindingMail] [varchar](50) NULL,--add column
        [ULR] [varchar](50) NULL,
        [CType] [tinyint] NULL,
        [InsertTime] [datetime] NULL,
     CONSTRAINT [PK_LoginsInfo] PRIMARY KEY CLUSTERED([Id] ASC)
    ) 
    GO
    ALTER TABLE [dbo].[LoginsInfo] ADD CONSTRAINT [DF_LoginsInfo_InserTime] DEFAULT (getdate()) FOR [InsertTime]
    GO
    View Code

    创建Database Master Key,并备份master_key

    USE UestDB;
    GO
    --数据库主密钥创建时默认使用Service Master Key和CREATE MASTER KEY中的密码加密
    CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'gK#3hbQKDFQY0oF';
    GO
    --Backup the DatabaseMasterKey
    BACKUP MASTER KEY TO FILE = 'D:SQL2012UestDBMasterKey.bak' ENCRYPTION BY PASSWORD = 'masterkeybakpwd';
    GO
    View Code

    创建非对称密钥,只指定了算法,没有指定PASSWORD子句,默认会使用Database Master Key加密私钥,这也是前面要创建Database Master Key的原因。接着创建对称密钥,使用前面的非对称密钥来加密,注意指定KEY_SOURCE和IDENTITY_VALUE

    -- Create an asymmetric key to protect the new symmetric key
    CREATE ASYMMETRIC KEY UestAsymmetricKey --名称
        --AUTHORIZATION Uest --所有者(数据库用户、数据库角色)
        WITH ALGORITHM = RSA_2048 --算法
    -- 没有指定PASSWORD子句,则用数据库master key加密私钥                                        
    -- Create a symmetric key, protected by the asymmetric key
    CREATE SYMMETRIC KEY UestSymmetricKey --名称
        WITH KEY_SOURCE ='pass_phrase', --derive the key
        ALGORITHM = TRIPLE_DES, --算法
        IDENTITY_VALUE = 'identity_phrase' --generate a GUID
        ENCRYPTION BY ASYMMETRIC KEY UestAsymmetricKey;--加密机制
    View Code

    使用对称密钥对数据进行加密

    -- 打开对称密钥
    OPEN SYMMETRIC KEY UestSymmetricKey
        DECRYPTION BY ASYMMETRIC KEY UestAsymmetricKey
    INSERT INTO LoginsInfo(Item,LoginName,PassWords,Notes,BindingMail,ULR,CType) 
    VALUES ('QQ', '1234567',EncryptByKey(Key_GUID('UestSymmetricKey'), 'Pass1')
    ,EncryptByKey(Key_GUID('UestSymmetricKey') ,'The first and the last letter is capitalized')
    ,'1234567@qq.com','http://qzone.qq.com/',1);
    -- 关闭对称密钥
    CLOSE SYMMETRIC KEY UestSymmetricKey;
    View Code

    查看原始数据和解密数据

    -- 查看数据
    OPEN SYMMETRIC KEY UestSymmetricKey
        DECRYPTION BY ASYMMETRIC KEY UestAsymmetricKey
    SELECT Id, Item, LoginName,
        CONVERT(VARCHAR, DecryptByKey(PassWords)) AS PassWords,
        CONVERT(VARCHAR, DecryptByKey(Notes)) AS Notes,
        BindingMail,ULR,Ctype
    FROM LoginsInfo;
    CLOSE SYMMETRIC KEY UestSymmetricKey;
    View Code


    从结果可以看到存储在表中的PassWords字段已加密,需使用对应的密钥解密才能看到真实数据。
    列数据加密如何迁移
    假如现在需要将LoginsInfo表中的数据导入到另一个库/另一个实例下的一张数据表中,导过去后如何查看真实数据?

    DROP TABLE DBA_Monitor.dbo.LoginsInfo
    SELECT * 
    INTO DBA_Monitor.dbo.LoginsInfo
    FROM LoginsInfo
    View Code

    可以通过导入/导出、select...into...等多种方式将数据转移到其他表。用源代码在目标数据库创建相同的非对称密钥和对称密钥

    USE DBA_Monitor;
    GO
    --数据库主密钥创建时默认使用Service Master Key和CREATE MASTER KEY中的密码加密
    CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'gK#3hbQKDFQY0oF';
    GO
    -- Create an asymmetric key to protect the new symmetric key
    CREATE ASYMMETRIC KEY UestAsymmetricKey --名称
        --AUTHORIZATION Uest --所有者(数据库用户、数据库角色)
        WITH ALGORITHM = RSA_2048 --算法
    -- 没有指定PASSWORD子句,则用数据库master key加密私钥                                        
    -- Create a symmetric key, protected by the asymmetric key
    CREATE SYMMETRIC KEY UestSymmetricKey --名称
        WITH KEY_SOURCE ='pass_phrase', --derive the key
        ALGORITHM = TRIPLE_DES, --算法
        IDENTITY_VALUE = 'identity_phrase' --generate a GUID
        ENCRYPTION BY ASYMMETRIC KEY UestAsymmetricKey;--加密机制
    View Code

    MASTER KEY中的PASSWORD不一定要和原来的一样,但是对称密钥中的KEY_SOURCE和IDENTITY_VALUE必须与原来的保持一样。查看目标表中的数据

    USE DBA_Monitor;
    GO
    -- 查看数据
    OPEN SYMMETRIC KEY UestSymmetricKey
        DECRYPTION BY ASYMMETRIC KEY UestAsymmetricKey
    SELECT Id, Item, LoginName,
        CONVERT(VARCHAR, DecryptByKey(PassWords)) AS PassWords,
        CONVERT(VARCHAR, DecryptByKey(Notes)) AS Notes,
        BindingMail,ULR,Ctype
    FROM LoginsInfo;
    CLOSE SYMMETRIC KEY UestSymmetricKey;
    View Code


    至此在新环境中已经能够正常查看加密数据。
    修改Database Master Key、非对称密钥和对称密钥
    Database Master Key的修改和还原

    --重新生成数据库主密钥
    ALTER MASTER KEY REGENERATE WITH ENCRYPTION BY PASSWORD ='password'
    GO
    --删除Service Master Key的加密
    ALTER MASTER KEY DROP ENCRYPTION BY SERVICE MASTER KEY--执行后,任何数据库主密钥的修改需要使用OPEN MASTER KEY访问
    --使用密码打开数据库主密钥
    OPEN MASTER KEY DECRYPTION BY PASSWORD = 'password'
    --重新应用Service Master Key的加密
    ALTER MASTER KEY ADD ENCRYPTION BY SERVICE MASTER KEY--执行后,数据库主密钥不再需要被显式打开或关闭,拥有足够许可(如sysadmin)的用户自动使用数据库主密钥解密
    --关闭数据库主密钥
    CLOSE MASTER KEY
    
    -- Restore the DatabaseMasterKey
    RESTORE MASTER KEY FROM FILE='D:SQL2012UestDBMasterKey.bak'
    DECRYPTION BY PASSWORD ='masterkeybakpwd'--备份数据库主密钥时指定的密码
    ENCRYPTION BY PASSWORD ='openpassword'--还原后数据库主密钥使用的密码(如果删除Service Master Key,则需使用此密码打开数据库主密钥)
    GO
    View Code

    修改非对称密钥

    /****修改非对称密钥****/
    --修改私钥加密方式
    ALTER ASYMMETRIC KEY UestAsymmetricKey--要修改的密钥名称 
    WITH PRIVATE KEY --私钥 
    (ENCRYPTION BY PASSWORD = 'AsymPass!')--指定密码加密私钥;执行后,与数据库master key就没有关联,此时drop master key不会报错
    
    -- 查看数据
    OPEN SYMMETRIC KEY UestSymmetricKey
        DECRYPTION BY ASYMMETRIC KEY UestAsymmetricKey
        WITH PASSWORD ='AsymPass!';--先用私钥密码打开对称密钥
    SELECT Id, Item, LoginName,
        CONVERT(VARCHAR, DecryptByKey(PassWords)) AS PassWords,
        Notes,ULR,Ctype
    FROM LoginsInfo;
    CLOSE SYMMETRIC KEY UestSymmetricKey;
                       
    --修改私钥密码 
    ALTER ASYMMETRIC KEY UestAsymmetricKey--要修改的密钥名称 
    WITH PRIVATE KEY --私钥 
    (ENCRYPTION BY PASSWORD = 'NewAsymPass',--指定新密码 
    DECRYPTION BY PASSWORD = 'AsymPass!')--旧密码是用来解密的                                    
    
    -- 查看数据
    OPEN SYMMETRIC KEY UestSymmetricKey
        DECRYPTION BY ASYMMETRIC KEY UestAsymmetricKey
        WITH PASSWORD ='NewAsymPass';--先用私钥密码打开对称密钥
    SELECT Id, Item, LoginName,
        CONVERT(VARCHAR, DecryptByKey(PassWords)) AS PassWords,
        Notes,ULR,Ctype
    FROM LoginsInfo;
    CLOSE SYMMETRIC KEY UestSymmetricKey;
    View Code

    修改对称密钥

    /****修改对称密钥的加密方式****/
    --先用私钥密码打开对称密钥
    OPEN SYMMETRIC KEY UestSymmetricKey
        DECRYPTION BY ASYMMETRIC KEY UestAsymmetricKey
        WITH PASSWORD ='NewAsymPass';
    --打开之后,先增加密码加密,取代原密钥
    ALTER SYMMETRIC KEY UestSymmetricKey
    ADD ENCRYPTION BY PASSWORD ='SysPass!'
    --再删除非对称密钥加密
    ALTER SYMMETRIC KEY UestSymmetricKey
    DROP ENCRYPTION BY ASYMMETRIC KEY UestAsymmetricKey --执行后,与非对称密钥没有关联,此时DROP ASYMMETRIC KEY不会报错
    --完成操作后,关闭对称密钥
    CLOSE SYMMETRIC KEY UestSymmetricKey
    
    -- 查看数据
    OPEN SYMMETRIC KEY UestSymmetricKey
        DECRYPTION BY PASSWORD ='SysPass!';--直接用密码打开对称密钥
    SELECT Id, Item, LoginName,
        CONVERT(VARCHAR, DecryptByKey(PassWords)) AS PassWords,
        Notes,ULR,Ctype
    FROM LoginsInfo;
    CLOSE SYMMETRIC KEY UestSymmetricKey;
    View Code
    -- *** Clean up ***
    -- ****************
    USE DBA_Monitor
    GO
    DROP SYMMETRIC KEY UestSymmetricKey
    DROP ASYMMETRIC KEY UestAsymmetricKey
    DROP MASTER KEY    
    GO
    USE master;
    GO
    IF DB_ID('UestDB') IS NOT NULL DROP DATABASE UestDB;
    GO
    -- Can't turn off TDE in tempdb once it is on
    DROP CERTIFICATE UestDBTDECert;
    GO
    DROP MASTER KEY;
    GO
    View Code

    此部分主要是查看Database Master Key、非对称密钥和对称密钥的加密方式

  • 相关阅读:
    温故知新-多线程-深入刨析park、unpark
    温故知新-多线程-forkjoin、CountDownLatch、CyclicBarrier、Semaphore用法
    温故知新-多线程-Cache Line存在验证
    CSS3动画基础
    通过DataSourceTransactionManager实现Spring事务
    MAC终端SSL_ERROR_SYSCALL in connection to XX
    磨刀不误砍柴工——ubuntu、mac终端美化
    k8s可视化工具kubernetes-dashboard部署——小白教程
    阿里云ECS(Ubuntu)单节点Kubernetes部署——小白教程
    Vue时间线组件
  • 原文地址:https://www.cnblogs.com/Uest/p/4975301.html
Copyright © 2011-2022 走看看