具有安全記憶體保護區的 Always Encrypted

適用于:SQL Server 2019 (15.x) 和更新版本 - 僅限 Windows Azure SQL Database

具有安全記憶體保護區的Always Encrypted藉由啟用就地加密和更豐富的機密查詢,擴充Always Encrypted的機密運算功能。 SQL Server 2019 (15.x) 及更新版本以及 Azure SQL Database 中提供具有安全記憶體保護區的Always Encrypted。

在 2015 年 Azure SQL 資料庫和 SQL Server 2016 (13.x) 中引進,Always Encrypted保護敏感性資料的機密性,避免惡意程式碼和高許可權未經授權的使用者:資料庫系統管理員 (DBA) 、電腦系統管理員、雲端系統管理員,或有權存取伺服器實例、硬體等其他人,但不應該能夠存取 部分或全部的實際資料。

如果沒有本文中討論的增強功能,Always Encrypted透過在用戶端加密資料來保護資料,且永遠不會允許資料或對應的密碼編譯金鑰以純文字出現在 Database Engine 內。 因此,資料庫內部的加密資料行功能受到嚴格限制。 Database Engine 在加密資料上可執行檔唯一作業是相等比較, (只有 具決定性加密) 才能使用。 所有其他作業,包括密碼編譯作業 (初始資料加密或金鑰輪替) 和更豐富的查詢 (,例如,資料庫內不支援模式比對) 。 使用者需要將資料移出資料庫以在用戶端執行這些作業。

「具有安全記憶體保護區」的 Always Encrypted 允許在伺服器端對安全記憶體保護區內的純文字資料進行一些計算,藉以因應這些限制。 安全記憶體保護區是 Database Engine 進程內的受保護記憶體區域。 安全記憶體保護區會顯示為資料庫引擎的其餘部分和其他主機電腦上的不透明方塊。 即使使用偵錯工具,也無法從外部檢視記憶體保護區內的任何資料或程式碼。 這些屬性會讓安全記憶體保護區成為「信任的執行環境」,可安全存取純文字的密碼編譯金鑰和機密資料,卻不會破壞資料機密性。

Always Encrypted 會使用安全記憶體保護區,如下圖所示:

資料流程

剖析應用程式所提交的 Transact-SQL 語句時,Database Engine 會判斷語句是否包含加密資料上需要使用安全記憶體保護區的任何作業。 針對這類陳述式:

  • 用戶端驅動程式會將作業所需的資料行加密金鑰 (透過安全通道) 傳送至安全記憶體保護區,並提交陳述式以供執行。

  • 處理 語句時,Database Engine 會將加密資料行上的密碼編譯作業或計算委派給安全記憶體保護區。 如有需要,記憶體保護區會解密資料,並對純文字執行計算。

在語句處理期間,資料與資料行加密金鑰都不會在安全記憶體保護區外部的 Database Engine 中以純文字公開。

支援的記憶體保護區技術

Always Encrypted會根據裝載資料庫的環境,使用兩種記憶體保護區技術之一:

  • 在 SQL Server 2019 (15.x) 和更新版本中,具有安全記憶體保護區的Always Encrypted使用虛擬化型安全性 (VBS) 安全記憶體保護區 (也稱為虛擬安全模式或 VSM 記憶體保護區) - 依賴 Windows Hypervisor 且不需要任何特殊硬體的軟體型技術。

  • 在 Azure SQL 資料庫中,具有安全記憶體保護區的Always Encrypted會使用Intel Software Guard Extensions (Intel SGX) 記憶體保護區 - 硬體型信任的執行環境技術。 Intel SGX 僅適用于使用 DC 系列 硬體設定的資料庫。

安全記憶體保護區證明

記憶體保護區證明是一種工作流程,可讓用戶端應用程式在共用密碼編譯金鑰並使用記憶體保護區來處理敏感性資料之前,使用安全記憶體保護區建立資料庫及其連線的應用程式的信任。 證明工作流程會驗證記憶體保護區是正版 VBS 或 Intel SGX 記憶體保護區,且其內部執行的程式碼是適用于 Always Encrypted 的正版 Microsoft 簽署記憶體保護區程式庫。 記憶體保護區證明有助於偵測惡意系統管理員竄改記憶體保護區程式碼或其環境的攻擊。

若要證明記憶體保護區,應用程式內的用戶端驅動程式和 Database Engine,其所連線的應用程式會使用用戶端指定的端點與外部證明服務通訊。

有效的證明服務取決於記憶體保護區類型和資料庫環境:

支援的用戶端驅動程式

若要使用具有安全記憶體保護區的 Always Encrypted,應用程式必須使用支援此功能的用戶端驅動程式。 請設定應用程式和用戶端驅動程式,以啟用記憶體保護區計算和記憶體保護區證明。 如需詳細資料 (包括支援的用戶端驅動程式清單),請參閱使用 Always Encrypted 開發應用程式

術語

已啟用記憶體保護區的金鑰

具有安全記憶體保護區的 Always Encrypted 引入了已啟用記憶體保護區的金鑰概念:

  • 已啟用記憶體保護區的資料行主要金鑰 - 在資料庫內部資料行主要金鑰中繼資料物件中指定 ENCLAVE_COMPUTATIONS 屬性的資料行主要金鑰。 資料行主要金鑰中繼資料物件也必須包含中繼資料屬性的有效簽章。 如需詳細資訊,請參閱 CREATE COLUMN MASTER KEY (Transact-SQL)
  • 已啟用記憶體保護區的資料行加密金鑰 - 以已啟用記憶體保護區的資料行主要金鑰進行加密的資料行加密金鑰。 安全記憶體保護區內只能使用已啟用記憶體保護區的資料行加密金鑰執行計算。

如需詳細資訊,請參閱為具有安全記憶體保護區的 Always Encrypted 管理金鑰

已啟用記憶體保護區的資料行

已啟用記憶體保護區的資料行是以已啟用記憶體保護區資料行加密金鑰進行加密的資料庫資料行。

已啟用記憶體保護區的資料行機密計算功能

具有安全記憶體保護區的 Always Encrypted 其兩大優點為就地加密和豐富機密查詢。

就地加密

就地加密允許對安全記憶體保護區內的資料庫資料行進行密碼編譯作業,而無需將資料移出資料庫。 就地加密可改善密碼編譯作業的效能和可靠性。 您可使用 ALTER TABLE (Transact-SQL) 陳述式執行就地加密。

可就地執行的密碼編譯作業如下:

  • 使用已啟用記憶體保護區的資料行加密金鑰加密純文字資料行。
  • 重新加密已啟用記憶體保護區的加密資料行,以:
    • 輪替資料行加密金鑰 - 使用已啟用記憶體保護區的新資料行加密金鑰重新加密資料行。
    • 例如,將已啟用記憶體保護區的資料行加密類型從確定性變更為隨機。
  • 解密儲存在加密資料行中的資料 (將資料行轉換成純文字資料行)。

只要與密碼編譯作業有關的資料行加密金鑰已啟用記憶體保護區,確定性和隨機加密就都可以就地加密。

機密查詢

注意

SQL Server 2022 (16.x) 新增對加密資料行上具有 JOIN、GROUP BY 和 ORDER BY 作業之機密查詢的額外支援。

機密查詢是在安全記憶體保護區內對已啟用記憶體保護區資料行執行作業的 DML 查詢

安全記憶體保護區內支援的作業包括:

作業 Azure SQL Database SQL Server 2022 (16.x) SQL Server 2019 (15.x)
比較運算子 支援 支援 支援
BETWEEN (Transact-SQL) 支援 支援 支援
IN (Transact-SQL) 支援 支援 支援
LIKE (Transact-SQL) 支援 支援 支援
DISTINCT 支援 支援 支援
聯結 支援 支援 僅支援巢狀的迴圈聯結
SELECT - ORDER BY 子句 (Transact-SQL) 支援 支援 不支援
SELECT - GROUP BY- Transact-SQL 支援 支援 不支援

注意

安全記憶體保護區內的上述作業需要隨機加密。 不支援確定性加密。 相等比較仍然是使用決定性加密的資料行可用的作業。

在 Azure SQL Database 和 SQL Server 2022 (16.x) 中,在字元字串資料行 (char 上使用記憶體保護區的機密查詢, nchar) 要求資料行使用二進位碼點 (_BIN2) 定序或 UTF-8 定序。 在 SQL Server 2019 (15.x) 中,需要a_BIN2定序。

如需詳細資訊,請參閱 使用安全記憶體保護區執行 Transact-SQL 語句

已啟用記憶體保護區的資料行上索引

您可在使用隨機加密的已啟用記憶體保護區資料行中建立非叢集索引,讓使用安全記憶體保護區的機密 DML 查詢執行得更快。

為確保使用隨機加密所加密資料行上索引不會外洩機密資料,索引資料結構 (B 型樹狀結構) 中的索引鍵值會加密,並根據其純文字值排序。 按純文字值排序也適用於在記憶體保護區內處理查詢。 當 Database Engine 中的查詢執行程式在加密資料行上使用索引進行記憶體保護區內的計算時,它會搜尋索引來查閱儲存在資料行中的特定值。 每個搜尋都可能會涉及多次比較。 查詢執行程式會將每一次的比較委派給記憶體保護區,記憶體保護區則會解密儲存在資料行中的值,以及要比較的加密索引鍵值;它接著會在純文字上執行比較,然後將比較的結果傳回執行程式。

在使用隨機化加密且未啟用記憶體保護區的資料行上建立索引仍不受支援。

使用確定性加密的資料行上索引,會根據加密文字 (而非純文字) 排序,無論資料行是否啟用記憶體保護區。

如需詳細資訊,請參閱使用具有安全記憶體保護區的 Always Encrypted 在資料行上建立及使用索引。 如需 Database Engine 中索引編制運作方式的一般資訊,請參閱 說明叢集和非叢集索引一文。

資料庫復原

若 SQL Server 的執行個體失敗,其資料庫可能會處於資料檔案仍包含交易中修改項目未完成的狀態。 執行個體啟動時,它會執行稱為資料庫復原的處理序,該處理序會涉及復原交易記錄中所找到的每個未完成交易,確保資料庫的完整性能獲得保留。 若未完成的交易更動了索引,那些變更也必須要復原。 例如,索引中的某些索引鍵值可能需要移除或重新插入。

重要

Microsoft 強烈建議先為您的資料庫啟用高速資料庫復原 (ADR)使用隨機加密進行加密,以在啟用記憶體保護區的資料行上建立第一個索引。 ADR 預設會在 Azure SQL Database 中啟用,但在 SQL Server 2019 (15.x) 和更新版本中則不會啟用。

若透過傳統式資料庫復原處理序 (遵循 ARIES) 復原對索引進行的變更,SQL Server 必須等待應用程式將資料行的資料行加密金鑰提供給記憶體保護區,這可能會花費很長的時間。 加速資料庫復原 (ADR) 大幅減少必須延遲的復原作業數目,因為記憶體保護區內的快取中無法使用資料行加密金鑰。 因此,它可以透過將封鎖新交易的機會降至最低,來大幅增加資料庫的可用性。 啟用 ADR 後,SQL Server仍然需要資料行加密金鑰才能完成清除舊資料版本,但它會做為不會影響資料庫或使用者交易可用性的背景工作。 您可能會在錯誤記錄檔中看到錯誤訊息,指出因為遺漏資料行加密金鑰而失敗的清除作業。

安全性考量

下列安全性考量事項適用於具備安全記憶體保護區的 Always Encrypted。

  • 您記憶體保護區中資料的安全性取決於證明通訊協定和證明服務。 因此,您必須確保證明服務及證明服務強制執行的證明原則,都是由信任的管理員管理。 此外,證明服務通常支援不同的原則和證明通訊協定,其中有些只會執行最小的記憶體保護區及環境驗證,並且旨在用於測試及開發。 請密切遵循證明服務特有的指導方針,以確保您使用生產部署的建議設定和原則。
  • 以啟用記憶體保護區資料行加密金鑰的隨機加密來加密資料行,可能會因為這類資料行支援範圍比較,而造成資料行中的資料儲存順序外洩。 例如,如果包含員工薪資的加密資料行具有索引,惡意 DBA 可能會掃描索引來尋找最大加密薪資值,並識別薪資上限的人員, (假設該人員的名稱未加密) 。
  • 如果您使用 Always Encrypted 來保護敏感性資料,避免 DBA 未經授權存取,請勿與 DBA 共用資料行主要金鑰或資料行加密金鑰。 DBA 可以管理加密資料行上的索引,而不需要直接存取金鑰,方法是使用記憶體保護區內的資料行加密金鑰快取。

商務持續性、災害復原和資料移轉的考量

為使用具有安全記憶體保護區之 Always Encrypted 的資料庫設定高可用性或災害復原解決方案時,請確定所有資料庫複本都可以使用安全的記憶體保護區。 如果記憶體保護區適用於主要複本,但不適用於次要複本,則嘗試使用具有安全記憶體保護區的 Always Encrypted 功能其所有陳述式在容錯移轉後都會失敗。

當使用具有安全記憶體保護區的 Always Encrypted 複製或遷移資料庫時,請確定目標環境一律支援記憶體保護區。 否則,使用記憶體保護區的語句將無法在複製或移轉的資料庫上運作。

請務必牢記下列特定考量:

  • SQL Server

    • 設定 Always On 可用性群組時,請確保可用性群組中裝載資料庫的每個 SQL Server 執行個體都支援具有安全記憶體保護區的 Always Encrypted,並設定了記憶體保護區和證明。
    • 當將使用具有安全記憶體保護區 Always Encrypted 功能的資料庫備份檔案還原到未設定記憶體保護區上 SQL Server 執行個體時,還原作業會成功,並可使用所有不依賴記憶體保護區的功能。 但是,所有使用記憶體保護區功能的後續陳述式都會失敗,且使用隨機加密的已啟用記憶體保護區資料行上索引都會失效。 當將使用資料庫 (其具有安全記憶體保護區 Always Encrypted) 連結到未設定記憶體保護區的執行個體時,也會發生相同情況。
    • 如果資料庫在使用隨機加密的啟用記憶體保護區資料行上包含索引,請務必先在資料庫中啟用加速資料庫復原 (ADR),再建立資料庫備份。 ADR 將會確保資料庫 (包含索引) 在還原資料庫後立即開放使用。 如需詳細資訊,請參閱資料庫復原
  • Azure SQL Database

    • 設定主動式異地複寫時,如果主要資料庫支援安全記憶體保護區,請確定次要資料庫也支援。

在 SQL Server 和 Azure SQL Database 中,當使用 bacpac 檔案遷移資料庫時,您必須確定在建立 bacpac 檔案前,已卸除所有使用隨機加密的啟用索引記憶體保護區資料行其索引。

已知的限制

具有安全記憶體保護區的 Always Encrypted 可利用索引支援就地加密和更豐富機密查詢,因應 Always Encrypted 的一些限制,如已啟用記憶體保護區的資料行機密計算功能所述。

限制中列出的Always Encrypted所有其他限制也適用于具有安全記憶體保護區的Always Encrypted。

下列限制僅適用於具備安全記憶體保護區的 Always Encrypted:

  • 無法在使用隨機加密啟用記憶體保護區的資料行上建立叢集索引。
  • 使用隨機加密啟用記憶體保護區的資料行不能是主鍵資料行,而且無法由外鍵條件約束或唯一索引鍵條件約束參考。
  • 在 SQL Server 2019 (15.x) (這項限制不適用於 Azure SQL Database 或 SQL Server 2022 (16.x) ) 僅使用索引 (巢狀迴圈聯結,如果已啟用記憶體保護區的資料行支援) 使用隨機加密。 如需不同產品間其他差異的資訊,請參閱機密查詢
  • 就地密碼編譯作業無法與資料行中繼資料的任何其他變更結合,不同之處在于變更相同字碼頁內的定序和可為 Null 性。 例如,您無法在單 ALTER TABLE/ALTER COLUMN 一 Transact-SQL 語句中加密、重新加密或解密資料行 AND 變更資料行的資料類型。 請使用兩個個別的陳述式。
  • 不支援對記憶體內部資料表中的資料行使用已啟用記憶體保護區的金鑰。
  • 定義計算資料行的運算式無法使用隨機化加密在已啟用記憶體保護區的資料行上執行任何計算 (即使計算是在 機密查詢 中所列出的支援作業) 。
  • 使用隨機加密啟用記憶體保護區的資料行上的 LIKE 運算子參數不支援逸出字元。
  • 透過使用 LIKE 運算子或具有使用下列任一資料類型 (在加密之後會成為大型物件) 查詢參數的比較運算子所進行的查詢會忽略索引,並執行資料表掃描。
    • nchar[n]nvarchar[n],如果 n 大於 3967。
    • char[n]varchar[n]binary[n]varbinary[n],如果 n 大於 7935。
  • 工具限制:
    • 若要儲存已啟用記憶體保護區的資料行主要金鑰,唯一支援的金鑰存放區是 Windows 憑證存放區和 Azure Key Vault。
    • 若要透過 ALTER TABLE/ALTER COLUMN 觸發就地密碼編譯作業,您必須使用 SSMS 或 Azure Data Studio 中的查詢視窗發出語句,或者您可以撰寫發出語句的程式。 目前, Set-SqlColumnEncryption SqlServer PowerShell 模組中的 Cmdlet 和 SQL Server Management Studio 中的Always Encrypted精靈不支援就地加密。 將資料移出資料庫以進行密碼編譯作業,即使用於作業的資料行加密金鑰已啟用記憶體保護區也一樣。

後續步驟

另請參閱