[EF6] Entity Framework 6 連接 SQL Server 2016 Always Encrypted

SQL Server 2016 新增 Always Encrypted 功能,對於機密資料的保護又多了一項選擇囉

本文連結

 

開發環境

  • VS 2017 15.9.11
  • .Net Framework 4.7.2
  • Sql Server 2016 Express Localdb,調用 sqllocaldb info mssqllocaldb 查看 instance 版本,如下圖

  • SSMS 17.9

建立自簽憑證

makecert -r -pe -n "CN=yao" -e 01/01/2030 -sky exchange -a sha256 -len 2048 -ss my -sr CurrentUser

 

設定 SQL Server Always  Encrypted Keys

建立 Master Key

 

選擇憑證

如果匯入憑證失敗,可能沒有權限,那就要賦予目前帳號權限,憑證要放在 本機電腦→個人
https://dotblogs.com.tw/yc421206/2019/05/23/enable_sql_server_ssl_connection_encrypt#賦予虛擬帳號存取憑證權限

 

建立 Encryption Key


 

加密欄位


 

選擇決定性加密或隨機加密

 

可以選擇直接執行或產生腳本(PS file),有了腳本下次就不需要操作 UI 了


 

匯入資料庫專案


有加密的欄位多了以下的描述

COLLATE Latin1_General_BIN2 ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = yao, ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256')

 

Master Key

 

Encryption Key

 

匯出憑證

Windows+Q→mmc.exe





匯出路徑選資料庫專案的位置

 

憑證加入方案總管並納入版控

我把憑證備份檔放進版控並設定好權限,你應該選擇適合團隊內的備份機制

 

匯入憑證

別台機器需要匯入憑證才能訪問加密資料表



 

SSMS 訪問加密資料

 

Column Encryption Setting=Enabled

 

再訪問一次就能看到被加密的資料了

 

EF 訪問加密資料

In order to create a new EntityDataModel:

  • go to Solution Explorer
  • right click on the project -> Add -> New Item…
  • choose ADO.NET Entity Data Model





 

試著讀取看看

[TestClass]
public class UnitTest1
{
    [TestMethod]
    public void EF_TEST()
    {
        using (var dbContext = new TestDbContext())
        {
            var employees = dbContext.Employees.AsNoTracking().ToList();
        }
    }
}

會得到以下例外

Test method EFTest.UnitTest1.EF_TEST threw exception:
System.InvalidOperationException: The 'Name' property on 'Employee' could not be set to a 'System.Byte[]' value. You must set this property to a non-null value of type 'System.String'.
Name 欄位,Entity Model 對應到的型別是 String,由於連線字串不正確,所以得到 Name 的型別是 Byte[],型別錯誤就報錯了

 

連線字串加上 Column Encryption Setting=Enabled,就可以正常的讀取囉

    <add name="TestDbContext"
         connectionString="data source=(localdb)\mssqllocaldb;initial catalog=AlwaysEncrypt;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework;Column Encryption Setting=Enabled"
         providerName="System.Data.SqlClient" />

 

使用限制

https://dotblogs.com.tw/yc421206/2019/05/31/ef6_connect_sql_server_2016_always_encrypted_limit_solution
 

參考資料

https://docs.microsoft.com/zh-tw/sql/relational-databases/security/encryption/always-encrypted-database-engine?view=sql-server-2017
https://docs.microsoft.com/zh-tw/sql/relational-databases/security/encryption/configure-always-encrypted-using-sql-server-management-studio?view=sql-server-2017

 

若有謬誤,煩請告知,新手發帖請多包涵


Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET

Image result for microsoft+mvp+logo