故障转移组辅助实例上 Azure SQL 托管实例 CLE 的解密问题

Decryption issue with Azure SQL Managed Instance CLE on secondary instance of a failover group

我们有一个带有主实例和辅助实例的 Azure SQL 托管实例故障转移组设置——我遇到的问题是我们对某些数据库使用了单元(列)级加密 (CLE) table 列。我有限的理解是这些的解密取决于服务主密钥。我认为问题在于数据库主密钥使用服务主密钥加密,然后数据库在实例之间同步,但同步不会执行服务器(实例)级别的数据,即服务主密钥……等等数据可以在主实例上解密,但在故障转移实例上不能。因此你会得到这样的错误:

Please create a master key in the database or open the master key in the session before performing this operation.

如果我 运行 我的用户数据库中的以下 SQL 它将解决问题,直到我进行故障转移,此时我需要再次 运行 它。所以从故障转移的角度来看并不理想,也意味着我不能将辅助实例用作只读实例。

OPEN MASTER KEY DECRYPTION BY PASSWORD = ‘XXX’ 
ALTER MASTER KEY DROP ENCRYPTION BY SERVICE MASTER KEY
OPEN MASTER KEY DECRYPTION BY PASSWORD = ‘XXX'
ALTER MASTER KEY ADD ENCRYPTION BY SERVICE MASTER KEY

下面是我能找到的唯一一篇描述该问题的文章(滚动到末尾,上面写着“在新的主副本中解密数据”),它通过从主实例备份服务主密钥解决了这个问题并将其恢复到辅助实例,但与我们的 Azure 设置相比,它是一个本地设置,问题是 我不知道如何(或者如果可能的话)备份和恢复Azure 中的服务主密钥.

https://www.sqlshack.com/column-level-sql-server-encryption-with-sql-server-always-on-availability-groups/

我确实尝试从主实例备份服务主密钥,这样我就可以将它恢复到辅助实例,但我看不到在 Azure SQL 托管实例中执行此导出的方法 - https://docs.microsoft.com/en-us/sql/t-sql/statements/backup-service-master-key-transact-sql?view=sql-server-ver15 …我试着给它 blob 存储位置,这有点牵强,但它不喜欢它:

BACKUP SERVICE MASTER KEY TO FILE = 'https://ourstorage.blob.core.windows.net/database-backups/service_master_key.key' ENCRYPTION BY PASSWORD = 'YYYY';

Msg 3078, Level 16, State 2, Line 69 The file name "https://pptefsaaseprd.blob.core.windows.net/database-backups/ase_prod_service_master_key" is invalid as a backup device name for the specified device type. Reissue the BACKUP statement with a valid file name and device type.

我听说过可能改用 Azure Key Vault,但找不到任何示例,理想情况下不希望对 code/sql 造成任何重大更改。

为了提供更多上下文,我们当前的存储过程执行如下操作:

       OPEN SYMMETRIC KEY SSN_Key_Surname
          DECRYPTION BY CERTIFICATE Surname;
 
       /* SQL making use of the decrypted column */
 
       CLOSE SYMMETRIC KEY SSN_Key_Surname;

这就是我所在的位置。希望我只是错过了一个简单的步骤——这肯定不是一种罕见的情况吧?即 如果您在故障转移组中有 Azure SQL 托管实例,使用列级加密,其中数据库主密钥由服务主密钥加密,您如何配置才能解密数据主要和次要实例?

我认为要实现这一点,您需要能够从主实例备份服务主密钥并将其还原到辅助实例——这在 Azure 中可能吗?

不出所料,我只是错过了这里描述的一个简单步骤

The Database Master Key (DMK) is encrypted with the Service Master Key (SMK) which is unique to each SQL Service instance and you want it this way.

SQL Server has an alternate way of decrypting the DMK. If the DMK cannot be decrypted with the SMK, it searches the credential store for a password that matches the same family GUID. If it finds a family GUID that matches your database it will attempt to decrypt the DMK with the stored password. If that succeeds then it will use the DMK to encrypt or decrypt credentials or keys within the database.

So the use of sp_control_dbmasterkey_password will store a family GUID based on the database name and the password decrypting the DMK in the master database.

To ensure that the DMK works when a AG fails from the primary to a secondary, run the sp_control_dbmasterkey_password on the secondary as part of your process to join an database to an AG.

所以在 辅助实例 上,我不得不 运行 在 master DB

上 运行
EXEC sp_control_dbmasterkey_password @db_name = N'MyDatabaseWithCLE',   
    @password = N'XX MY MASTER KEY PASSWORD XX’, @action = N'add';  
GO