錯誤1:請在數據庫中創建一個主密鑰或在會話中打開該主密鑰
執行 Transact-SQL 語句或批處理時發生了異常。在執行此操作之前,請在數據庫中創建一個主密鑰或在會話中打開該主密鑰。錯誤號: 15581
嚴重性: 16
狀態: 3
行號: 1
發生這個錯誤有三種情況:
-
確實沒有創建數據庫主祕鑰
-
創建了主祕鑰,但是有使用ALTER MASTER KEY DROP ENCRYPTION BY SERVICE MASTER KEY 刪除了服務器主祕鑰對數據庫主祕鑰的加密
-
使用 RESTORE MASTER KEY FROM FILE='File_Name' DECRYPTION BY PASSWORD='備份DEK時使用的密碼' ENCRYPTION BY PASSWORD='強密碼' 創建備份證書。
對於情況1,我們可以使用系統試圖 sys.symmetric_keys 確定是否創建數據庫主密鑰:
USE master
GO
SELECT * FROM sys.symmetric_keys
如果結果集中沒有##MS_DatabaseMasterKey## ,則說明未創建數據庫主密鑰,那麼我們需要重新創建數據庫主密鑰,再還原證書和私鑰;如果存在,則可能是2或者3的情況了,我們可以使用下面語句,確定數據庫主密鑰是否使用服務器主密鑰進行加密:
SELECT name, is_master_key_encrypted_by_server
FROM sys.databases
WHERE name = 'master'
開啓數據庫主密鑰的服務器主密鑰加密方式:
OPEN MASTER KEY DECRYPTION BY PASSWORD='創建DEK時使用的密碼或者還原主密鑰時使用的加密密碼'
ALTER MASTER KEY ADD ENCRYPTION BY SERVICE MASTER KEY
之後再進行還原就可以順利進行了。
警告1:證書過期
證書的默認過期日期爲1年
--證書默認過期日期爲一年
SELECT name, start_date, expiry_date
FROM sys.certificates
WHERE name = 'Test3Cert'
如果證書過期了,會對透明加密有什麼影響呢?下面我們講過剛剛還原的test3_Encrypted 數據庫透明加密關閉,並刪除其數據庫祕鑰,然後再刪除服務器證書Test3Cert:
USE master
GO
ALTER DATABASE test3_Encrypted SET ENCRYPTION OFF
GO
USE test3_Encrypted
GO
DROP DATABASE ENCRYPTION KEY
USE master
GO
DROP CERTIFICATE Test3Cert
重新創建證書,使得過期時間在幾分鐘後,方便我們測試:
USE master
GO
CREATE CERTIFICATE Test3Cert
WITH SUBJECT='Test3 Certificate for expirate date'
,EXPIRY_DATE='2020-2-19 14:20:00'
USE test3_Encrypted
GO
CREATE DATABASE ENCRYPTION KEY
WITH ALGORITHM=AES_128
ENCRYPTION BY SERVER CERTIFICATE Test3Cert
GO
USE master
GO
ALTER DATABASE test3_Encrypted SET ENCRYPTION ON
GO
我們先確認一下證書是否過期,查詢系統視圖 sys.certificates 結果如下:
顯然當前時間已經超過了證書過期時間,然後我們再備份數據庫test3_Encrypted。備份後時記事本打開備份文件,並搜索Jack,發現仍然找不到這個字符串,說明數據庫備份文件仍然處於加密狀態
BACKUP CERTIFICATE Test3Cert
TO FILE ='D:\Test3Cert.cer'
WITH PRIVATE KEY(FILE='D:\Test3Cert_Key.pvk',
ENCRYPTION BY PASSWORD='jC`T?]K,v`{voD<') --用於在將密鑰寫入備份文件之前對私鑰進行加密的密碼。該密碼需要進行複雜性檢查。
GO
然後刪除test3_Encrypted數據庫,刪除證書
USE master
GO
DROP DATABASE test3_Encrypted
GO
--刪除證書
DROP CERTIFICATE Test3Cert
使用證書和私鑰重新創建證書:
CREATE CERTIFICATE Test3Cert
FROM FILE = 'D:\Test3Cert.cer'
WITH PRIVATE KEY(FILE='D:\Test3Cert_Key.pvk',
DECRYPTION BY PASSWORD='jC`T?]K,v`{voD<');
GO
在還原證書的時候,會出現截圖的警告,我們先不理會這個警告,再次還原數據庫:
USE [master]
RESTORE DATABASE [test3_Encrypted_CertExpiry] FROM DISK = N'D:\test3_Encrypted_CertExpiry.bak'
WITH FILE = 1,
MOVE 'test3' to 'D:\DB\test3_Encrypted_CertExpiry.mdf',
MOVE 'test3_log' to 'D:\DB\test3_Encrypted_CertExpiry_Log.ldf',
NOUNLOAD, STATS = 5
GO
當證書過期後,使用證書和私鑰還原加密數據庫的備份文件,仍然可以成功,只是會提示證書過期。
解決證書過期的方案:
可惜的是ALTER CERTIFICATE中並未提到修改EXPIRY_DATE的方法,如果想要解決證書過期的問題,只能重新創建證書,使用ALTER DATABASE ENCRYPTION KEY 對數據庫再次加密:
ALTER DATABASE ENCRYPTION KEY TDEDEKeyName
WITH ALGORITHM=AES_128
ENCRYPTION BY SERVER CERTIFICATE NewCertName
當然,在重新加密數據庫後,我們還需要做的是歸檔原有的證書、私鑰備份文件,保存好新的證書、私鑰備份;需要防止原有證書、私鑰丟失造成歷史備份無法還原、數據丟失的問題。
過期證書、新證書備份、歸檔完畢後,可以刪除過期證書。
數據庫管理員移交管理內容時,要移交所有相關文檔,新的接收人要修改私鑰密碼或者對數據庫進行重新加密。