SQL Server 2016新特性: Always Encrypted (始终加密)
时间:2016-06-05 21:31 来源:linux.it.net.cn 作者:IT
数据,尤其是机密数据的安全性,是我们设计和开发系统所要考虑的。SQL Server 2016引入了加密数据列的新方式,即始终加密(Always Encrypted)。有了始终加密,数据就可以通过ADO.NET在应用层进行加密,这意味着,在数据通过网络发送到SQL Server之前,你可以通过.NET应用程序来加密你的机密数据。这个过程中,网络传输的是密文,存储在DB里的数据也是密文,对我们的数据起到了一定程度的保护作用。下面看看如何使用这一功能(Framework4.6及其以上版本支持该功能)
1、新建列主密钥(Column Master Key)
2、 新建列加密密钥(Column Encryption Key)
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、导出服务器端的证书
6、在客户端导入该证书
7. 测试SP,直接在SSMS里执行是失败的
8、 准备测试的应用程式(注意这里的连接字符串里增加了选项:Column Encryption Setting = Enabled;)
最后附上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();
-
}
-
}
-
}
-
}
-
(责任编辑:IT)
数据,尤其是机密数据的安全性,是我们设计和开发系统所要考虑的。SQL Server 2016引入了加密数据列的新方式,即始终加密(Always Encrypted)。有了始终加密,数据就可以通过ADO.NET在应用层进行加密,这意味着,在数据通过网络发送到SQL Server之前,你可以通过.NET应用程序来加密你的机密数据。这个过程中,网络传输的是密文,存储在DB里的数据也是密文,对我们的数据起到了一定程度的保护作用。下面看看如何使用这一功能(Framework4.6及其以上版本支持该功能)
1、新建列主密钥(Column Master Key)
2、 新建列加密密钥(Column Encryption Key)
3、新建测试表,注意这里指定了机密类型、算法及加密密钥。
4、新建SP,用于Insert数据
5、导出服务器端的证书
6、在客户端导入该证书
7. 测试SP,直接在SSMS里执行是失败的
8、 准备测试的应用程式(注意这里的连接字符串里增加了选项:Column Encryption Setting = Enabled;)
最后附上C#测试源码:
(责任编辑:IT) |