Sql-Server

在數據庫和實例之間共享密碼加密的證書

  • September 26, 2017

題:

我正在嘗試創建一個(自簽名)證書並跨多個數據庫和實例進行部署。

我創建和備份證書:

USE MASTER
CREATE CERTIFICATE DavesCert ENCRYPTION BY PASSWORD ='S3creT!' WITH SUBJECT = 'The master cert'

BACKUP CERTIFICATE DavesCert TO FILE = 'd:\DavesCert.cer' 
WITH PRIVATE KEY ( DECRYPTION BY PASSWORD = 'S3creT!' ,
FILE = 'd:\DavesCert.pvk' , 
ENCRYPTION BY PASSWORD = 'S3creT!' );

我恢復

USE FOO
GO

CREATE CERTIFICATE ERecruitStatsGatheringCert       
FROM FILE = 'd:\DavesCert.cer'      
WITH PRIVATE KEY (FILE = 'd:\DavesCert.pvk', 
DECRYPTION BY PASSWORD = 'S3creT!')

並得到以下錯誤:“請在執行此操作之前在數據庫中創建主密鑰或在會話中打開主密鑰。”

我不想創建數據庫主密鑰。我很樂意根據需要通過密碼解密證書。

背景: SaaS 應用程序。數據庫和實例之間的多對多關係。

我需要每個數據庫能夠通過執行一個儲存過程來查詢它自己的統計資訊,該儲存過程包含對 DMV 的一些呼叫以返回統計資訊。

應用程序在低權限帳戶下執行。DMV 需要 VIEW SERVER STATE 權限,因此,我正在使用證書實現對儲存過程的簽名。

設置它的基本方法是:

  1. 在使用者數據庫中創建一個證書。
  2. 將該證書備份/恢復到主控。
  3. 在 master 中創建登錄名,分配該權限等。
  4. 將證書添加到儲存過程。

我有上面的測試程式碼,它執行良好,但是該模型不能很好地擴展到跨多個實例/數據庫的部署。

因此,我我想在所有數據庫/實例中使用相同的證書。

對其他建議​​/方法感到高興。

– 最初發佈到 Stack Exchange,然後根據其他用途提出建議

您只需指定用於解密私鑰文件的密碼。您需要添加密碼來儲存證書:

CREATE CERTIFICATE ERecruitStatsGatheringCert        
ENCRYPTION BY PASSWORD = 'S3creT!
FROM FILE = 'd:\DavesCert.cer'       
WITH PRIVATE KEY (
   FILE = 'd:\DavesCert.pvk',  
   DECRYPTION BY PASSWORD = 'S3creT!');

但是您的背景資訊使整個練習徒勞無功。你這樣做是錯的。正確的動作順序是:

  1. 在使用者數據庫中創建證書
  2. 將簽名添加到儲存過程
  3. 刪除證書的私鑰
  4. 將該證書備份/恢復到master(僅限公鑰!)
  5. 創建登錄名master,分配該權限等。

請注意,不僅私鑰永遠不會離開數據庫,而且實際上在簽署過程後立即顯式刪除。這是必需的,以防止進一步使用此證書籤署其他程序並濫用在步驟 5 中創建的登錄權限。您在每個數據庫上重複這些步驟並在每個數據庫上使用不同的證書。每次修改任何簽名過程並生成新證書時,都重複這些步驟。

作為一般規則,任何需要私鑰副本的簽名/加密公鑰/私鑰 (RSA) 方案都會被破壞。這就是為什麼被稱為私有的,這就是賦予簽名價值的原因:知道世界上只存在這個私鑰的一個實例,因此任何被它簽名的東西都證明它來自唯一的所有者/持有者的唯一私鑰。


我知道有些人拒絕我的建議,即在用於簽署程序後立即刪除私鑰。我支持我的建議,但對您的問題而言,重要的**是不需要將私鑰複製到其中[master]**以利用您想要的程式碼簽名權限。您可以(並且應該)僅使用公鑰創建從證書派生的登錄名。

關於自動化:在我看來,基本上它是一個接受兩個輸入的工具(腳本、應用程序):一個安全的(過程、函式、模組)和一個權限(VIEW SERVER STATE)。其他一切都是一個自動化過程(創建一次性使用的一次性證書、簽名、導出證書、導入證書[master]、創建登錄、授予權限)。隱含的名稱(證書名稱、登錄名)都可以生成。

名稱的擴散是一個合理的問題。一種替代方法是僅使用一個證書和相關的私鑰,並且簽名工具可以在需要時添加私鑰(在對過程進行簽名時),然後在簽名後將其刪除。這實際上取決於您如何經營您的商店以及您所保護的資產有多重要。但重要的是您不需要將私鑰導入[master].

我在生產中使用的證書和密鑰不多,但我理解這個概念的方式是使用私鑰創建證書,意味著使用數據庫主密鑰來加密證書的私鑰。

我在 technet 上找到了這篇文章:http ://technet.microsoft.com/en-us/library/bb964742.aspx

數據庫主密鑰是一種對稱密鑰,用於保護數據庫中存在的證書和非對稱密鑰的私鑰。

為了查看我是否可以在另一台伺服器上使用您的證書,我在沒有私鑰的情況下創建了您的證書。

CREATE CERTIFICATE DavesCert WITH SUBJECT = 'The master cert'

然後我備份了它

BACKUP CERTIFICATE DavesCert TO FILE = 'D:\MSSQL\davescert.cer'

我將證書移動到另一台伺服器並恢復了它。

CREATE CERTIFICATE davescert FROM FILE = 'd:\mssql\davescert.cer'

查看證書

SELECT name, certificate_id, pvt_key_encryption_type_desc from sys.certificates


name    certificate_id  pvt_key_encryption_type_desc
davescert   257 NO_PRIVATE_KEY

如果您不使用私鑰來加密您的證書,則您不需要數據庫主密鑰。如果您確實使用了私鑰,那麼您必須在使用您的證書的每個數據庫上創建一個主密鑰。

引用自:https://dba.stackexchange.com/questions/21439