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



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


1新建列主密钥(Column Master Key

SQL Server 2016新特性: Always Encrypted (始终加密)_第1张图片

SQL Server 2016新特性: Always Encrypted (始终加密)_第2张图片


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

SQL Server 2016新特性: Always Encrypted (始终加密)_第3张图片

SQL Server 2016新特性: Always Encrypted (始终加密)_第4张图片


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


CREATE TABLE [dbo].[Patients](
[PatientId] [int] IDENTITY(1,1), 
 [SSN] [nvarchar](11) COLLATE Latin1_General_BIN2 
 ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, 
 ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', 
 COLUMN_ENCRYPTION_KEY = CEK1) NOT NULL,
[FirstName] [nvarchar](50) NULL,
[LastName] [nvarchar](50) NULL, 
 [MiddleName] [nvarchar](50) NULL,
[StreetAddress] [nvarchar](50) NULL,
[City] [nvarchar](50) NULL,
[ZipCode] [char](5) NULL,
[State] [char](2) NULL,
[BirthDate] [date] 
 ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, 
 ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', 
 COLUMN_ENCRYPTION_KEY = CEK1) NOT NULL
PRIMARY KEY CLUSTERED ([PatientId] ASC) ON [PRIMARY] )

4新建SP,用于Insert数据

CREATE PROCEDURE Insert_Always_Encrypted (
@SSN NVARCHAR(11),
@FirstName varchar(50),
@LastName varchar(50),
@BirthDate date 
)
AS 
INSERT INTO dbo.Patients
   (SSN, FirstName,LastName, BirthDate)
VALUES (@SSN,@FirstName,@LastName,@BirthDate);

5导出服务器端的证书

SQL Server 2016新特性: Always Encrypted (始终加密)_第5张图片
SQL Server 2016新特性: Always Encrypted (始终加密)_第6张图片

SQL Server 2016新特性: Always Encrypted (始终加密)_第7张图片

SQL Server 2016新特性: Always Encrypted (始终加密)_第8张图片


6在客户端导入该证书

SQL Server 2016新特性: Always Encrypted (始终加密)_第9张图片

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

SQL Server 2016新特性: Always Encrypted (始终加密)_第10张图片


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

SQL Server 2016新特性: Always Encrypted (始终加密)_第11张图片

SQL Server 2016新特性: Always Encrypted (始终加密)_第12张图片

SQL Server 2016新特性: Always Encrypted (始终加密)_第13张图片

SQL Server 2016新特性: Always Encrypted (始终加密)_第14张图片

SQL Server 2016新特性: Always Encrypted (始终加密)_第15张图片

SQL Server 2016新特性: Always Encrypted (始终加密)_第16张图片


最后附上C#测试源码:

using System.Data;
using System.Data.SqlClient;
using System.Windows.Forms;

// Demo of using Always Encrypted Columns
class AlwaysEncryptedDemo
{
    SqlConnection conn;
    public AlwaysEncryptedDemo()
    {
        // Instantiate the connection
        conn = new SqlConnection(
          "data source=172.19.121.150;initial catalog=imoltp;integrated security = False; Column Encryption Setting = Enabled; User ID = sa; Password = sa9; ");
    }

    // call methods that demo Always Encrypted
    static void Main()
    {
        AlwaysEncryptedDemo scd = new AlwaysEncryptedDemo();
        scd.Insertdata();
        scd.Selectdata();
    }

    public void Insertdata()
    {
        try
        {
            // Open the connection for Insertion 
            conn.Open();

            // Constructed command to execute stored proceudre
            string insertString = @"dbo.Insert_Always_Encrypted";

            // Declare variable tho hold insdert command
            SqlCommand icmd = new SqlCommand(insertString, conn);

            //set command type to stored procedure
            icmd.CommandType = CommandType.StoredProcedure;

            // Set value of SSN
            SqlParameter
            paramSSN = icmd.CreateParameter();
            paramSSN.ParameterName = @"@SSN";
            paramSSN.DbType = DbType.String;
            paramSSN.Direction = ParameterDirection.Input;
            paramSSN.Value = "555-55-5555";
            paramSSN.Size = 11;
            icmd.Parameters.Add(paramSSN);

            // Set value of FirstName
            SqlParameter paramFirstName = icmd.CreateParameter();
            paramFirstName.ParameterName = @"@FirstName";
            paramFirstName.DbType = DbType.AnsiStringFixedLength; ;
            paramFirstName.Direction = ParameterDirection.Input;
            paramFirstName.Value = "Greg";
            icmd.Parameters.Add(paramFirstName);

            // Set value of LastName
            SqlParameter paramLastName = icmd.CreateParameter();
            paramLastName.ParameterName = @"@LastName";
            paramLastName.DbType = DbType.AnsiStringFixedLength; ;
            paramLastName.Direction = ParameterDirection.Input;
            paramLastName.Value = "Larsen";
            icmd.Parameters.Add(paramLastName);

            // Set value of Birth Date
            SqlParameter
            paramBirthdate = icmd.CreateParameter();
            paramBirthdate.ParameterName = @"@BirthDate";
            paramBirthdate.SqlDbType = SqlDbType.Date;
            paramBirthdate.Direction = ParameterDirection.Input;
            paramBirthdate.Value = "2015-01-02";
            icmd.Parameters.Add(paramBirthdate);

            // Exexute Insert 
            icmd.ExecuteNonQuery();
            MessageBox.Show("Inserted Demo Record With BirthDate=" + paramBirthdate.Value + "SSN=" + paramSSN.Value);

        }
        finally
        {
            // Close the connection
            if (conn != null)
            {
                conn.Close();
            }
        }
    }
    public void Selectdata()
    {
        try
        {
            // Open the connection for Selection 
            conn.Open();

            // Read Encrypted data 
            string selectString = @"SELECT PatientId, LastName, FirstName, BirthDate, SSN FROM [dbo].[Patients] ";
            SqlCommand scmd = new SqlCommand(selectString, conn);
            SqlDataReader dataRead = scmd.ExecuteReader();
            while (dataRead.Read())
            {
                MessageBox.Show("Selected Data with ID=" + dataRead["PatientId"].ToString() +
                                " LastName=" + dataRead["LastName"] +
                                " FirstName=" + dataRead["FirstName"] +
                                " BirthDate =" + dataRead["BirthDate"].ToString() +
                                " SSN=" + dataRead["SSN"].ToString());
            }
        }
        finally
        {
            // Close the connection
            if (conn != null)
            {
                conn.Close();
            }
        }
    }
}


你可能感兴趣的:(SQL,SERVER,SQL,Server,2016新特性)