> 数据库 > SQL Server 2016 >

SQL Server 2016新特性: Always Encrypted (始终加密)

 数据,尤其是机密数据的安全性,是我们设计和开发系统所要考虑的。SQL Server 2016引入了加密数据列的新方式,即始终加密(Always Encrypted)。有了始终加密,数据就可以通过ADO.NET在应用层进行加密,这意味着,在数据通过网络发送到SQL Server之前,你可以通过.NET应用程序来加密你的机密数据。这个过程中,网络传输的是密文,存储在DB里的数据也是密文,对我们的数据起到了一定程度的保护作用。下面看看如何使用这一功能(Framework4.6及其以上版本支持该功能)

 

1新建列主密钥(Column Master Key

 

2 新建列加密密钥(Column Encryption Key

 

3新建测试表,注意这里指定了机密类型、算法及加密密钥。

 

 

[sql] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. CREATE TABLE [dbo].[Patients](  
  2. [PatientId] [int] IDENTITY(1,1),   
  3.  [SSN] [nvarchar](11) COLLATE Latin1_General_BIN2   
  4.  ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC,   
  5.  ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256',   
  6.  COLUMN_ENCRYPTION_KEY = CEK1) NOT NULL,  
  7. [FirstName] [nvarchar](50) NULL,  
  8. [LastName] [nvarchar](50) NULL,   
  9.  [MiddleName] [nvarchar](50) NULL,  
  10. [StreetAddress] [nvarchar](50) NULL,  
  11. [City] [nvarchar](50) NULL,  
  12. [ZipCode] [char](5) NULL,  
  13. [State] [char](2) NULL,  
  14. [BirthDate] [date]   
  15.  ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED,   
  16.  ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256',   
  17.  COLUMN_ENCRYPTION_KEY = CEK1) NOT NULL  
  18. PRIMARY KEY CLUSTERED ([PatientId] ASCON [PRIMARY] )  

 

 

4新建SP,用于Insert数据

 

[sql] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. CREATE PROCEDURE Insert_Always_Encrypted (  
  2. @SSN NVARCHAR(11),  
  3. @FirstName varchar(50),  
  4. @LastName varchar(50),  
  5. @BirthDate date   
  6. )  
  7. AS   
  8. INSERT INTO dbo.Patients  
  9.    (SSN, FirstName,LastName, BirthDate)  
  10. VALUES (@SSN,@FirstName,@LastName,@BirthDate);  

 

 

5导出服务器端的证书


 

6在客户端导入该证书

7. 测试SP,直接在SSMS里执行是失败的

 

8 准备测试的应用程式(注意这里的连接字符串里增加了选项:Column Encryption Setting = Enabled;

 

最后附上C#测试源码:

 

 
  1. using System.Data;  
  2. using System.Data.SqlClient;  
  3. using System.Windows.Forms;  
  4.   
  5. // Demo of using Always Encrypted Columns  
  6. class AlwaysEncryptedDemo  
  7. {  
  8.     SqlConnection conn;  
  9.     public AlwaysEncryptedDemo()  
  10.     {  
  11.         // Instantiate the connection  
  12.         conn = new SqlConnection(  
  13.           "data source=172.19.121.150;initial catalog=imoltp;integrated security = False; Column Encryption Setting = Enabled; User ID = sa; Password = sa9; ");  
  14.     }  
  15.   
  16.     // call methods that demo Always Encrypted  
  17.     static void Main()  
  18.     {  
  19.         AlwaysEncryptedDemo scd = new AlwaysEncryptedDemo();  
  20.         scd.Insertdata();  
  21.         scd.Selectdata();  
  22.     }  
  23.   
  24.     public void Insertdata()  
  25.     {  
  26.         try  
  27.         {  
  28.             // Open the connection for Insertion   
  29.             conn.Open();  
  30.   
  31.             // Constructed command to execute stored proceudre  
  32.             string insertString = @"dbo.Insert_Always_Encrypted";  
  33.   
  34.             // Declare variable tho hold insdert command  
  35.             SqlCommand icmd = new SqlCommand(insertString, conn);  
  36.   
  37.             //set command type to stored procedure  
  38.             icmd.CommandType = CommandType.StoredProcedure;  
  39.   
  40.             // Set value of SSN  
  41.             SqlParameter  
  42.             paramSSN = icmd.CreateParameter();  
  43.             paramSSN.ParameterName = @"@SSN";  
  44.             paramSSN.DbType = DbType.String;  
  45.             paramSSN.Direction = ParameterDirection.Input;  
  46.             paramSSN.Value = "555-55-5555";  
  47.             paramSSN.Size = 11;  
  48.             icmd.Parameters.Add(paramSSN);  
  49.   
  50.             // Set value of FirstName  
  51.             SqlParameter paramFirstName = icmd.CreateParameter();  
  52.             paramFirstName.ParameterName = @"@FirstName";  
  53.             paramFirstName.DbType = DbType.AnsiStringFixedLength; ;  
  54.             paramFirstName.Direction = ParameterDirection.Input;  
  55.             paramFirstName.Value = "Greg";  
  56.             icmd.Parameters.Add(paramFirstName);  
  57.   
  58.             // Set value of LastName  
  59.             SqlParameter paramLastName = icmd.CreateParameter();  
  60.             paramLastName.ParameterName = @"@LastName";  
  61.             paramLastName.DbType = DbType.AnsiStringFixedLength; ;  
  62.             paramLastName.Direction = ParameterDirection.Input;  
  63.             paramLastName.Value = "Larsen";  
  64.             icmd.Parameters.Add(paramLastName);  
  65.   
  66.             // Set value of Birth Date  
  67.             SqlParameter  
  68.             paramBirthdate = icmd.CreateParameter();  
  69.             paramBirthdate.ParameterName = @"@BirthDate";  
  70.             paramBirthdate.SqlDbType = SqlDbType.Date;  
  71.             paramBirthdate.Direction = ParameterDirection.Input;  
  72.             paramBirthdate.Value = "2015-01-02";  
  73.             icmd.Parameters.Add(paramBirthdate);  
  74.   
  75.             // Exexute Insert   
  76.             icmd.ExecuteNonQuery();  
  77.             MessageBox.Show("Inserted Demo Record With BirthDate=" + paramBirthdate.Value + "SSN=" + paramSSN.Value);  
  78.   
  79.         }  
  80.         finally  
  81.         {  
  82.             // Close the connection  
  83.             if (conn != null)  
  84.             {  
  85.                 conn.Close();  
  86.             }  
  87.         }  
  88.     }  
  89.     public void Selectdata()  
  90.     {  
  91.         try  
  92.         {  
  93.             // Open the connection for Selection   
  94.             conn.Open();  
  95.   
  96.             // Read Encrypted data   
  97.             string selectString = @"SELECT PatientId, LastName, FirstName, BirthDate, SSN FROM [dbo].[Patients] ";  
  98.             SqlCommand scmd = new SqlCommand(selectString, conn);  
  99.             SqlDataReader dataRead = scmd.ExecuteReader();  
  100.             while (dataRead.Read())  
  101.             {  
  102.                 MessageBox.Show("Selected Data with ID=" + dataRead["PatientId"].ToString() +  
  103.                                 " LastName=" + dataRead["LastName"] +  
  104.                                 " FirstName=" + dataRead["FirstName"] +  
  105.                                 " BirthDate =" + dataRead["BirthDate"].ToString() +  
  106.                                 " SSN=" + dataRead["SSN"].ToString());  
  107.             }  
  108.         }  
  109.         finally  
  110.         {  
  111.             // Close the connection  
  112.             if (conn != null)  
  113.             {  
  114.                 conn.Close();  
  115.             }  
  116.         }  
  117.     }  
  118. }  
  119.  



(责任编辑:IT)