Ошибка: «Сертификат не может быть удален, потому что один или несколько объектов подписаны или зашифрованы с использованием его».

8

У меня есть сертификат, который я хотел бы удалить из базы данных.

Если я дам команду

DROP CERTIFICATE <FooCert>

Я получаю ошибку

The certificate cannot be dropped because one or more entities are either signed or encrypted using it

По словам Джейсона Стрита, я должен быть в состоянии выяснить, что подписано сертификатом.

Следующий запрос возвращает 0 строк:

SELECT OBJECT_SCHEMA_NAME(co.major_id) + '.' + OBJECT_NAME(co.major_id)
FROM sys.certificates c 
INNER JOIN sys.crypt_properties co ON c.thumbprint = co.thumbprint
WHERE co.crypt_type_desc = 'SIGNATURE BY CERTIFICATE' 
AND c.name = 'FooCert'

Я также попытался отделить сущности по этому такому вопросу. /programming/52460/how-do-i-find-and-decouple-entities-from-a-certificate-when-upgrading-ms-sqlserv

Как я могу удалить зависимости от этого сертификата, чтобы я мог удалить его?

Джефф Доуди
источник
Можете ли вы попробовать запрос, который я разместил здесь: Найти подписанные процедуры, функции, триггеры, сборки и какие сертификаты / асимметричные ключи . Это что-нибудь находит? Если это так, я могу опубликовать его или просто ссылку на него здесь. Если нет, то я предполагаю, что это логин / пользователь на основе сертификатов, и я могу отправить запрос на это.
Соломон Руцкий
0 строк возвращено.
Джефф Доуди
Включено ли в вашей базе данных «Прозрачное шифрование данных» (TDE)?
SQLPRODDBA
1
@SQLPRODDBA Спасибо за упоминание TDE :-). Я не думал об этом, но добавил запрос к своему ответу, чтобы найти это также (и проверил это и подтвердил, что это работает).
Соломон Руцкий,
1
@srutzky Спасибо за внимание! Ваш сценарий потрясающий!
SQLPRODDBA

Ответы:

6

Чтобы найти элементы, связанные с сертификатами и асимметричными ключами, сначала попробуйте запрос, опубликованный в этом DBA.SE Ответ:

Найти подписанные процедуры, функции, триггеры, сборки и по каким сертификатам / асимметричным ключам

Если это не возвращает никаких объектов, попробуйте следующие запросы, которые ищут:

  • Логины
  • пользователей
  • Конечные точки сервис-брокера
  • Конечные точки зеркального отображения базы данных
  • Симметричные ключи
  • Ключи шифрования базы данных (используются для TDE)

Обратите внимание, что логины находятся на уровне сервера / экземпляра, а все остальное - на уровне базы данных. Кроме того, ключи шифрования базы данных, находясь на уровне базы данных, передаются в DMV, который возвращает данные для всех баз данных и поэтому не изменяется в зависимости от «текущей» базы данных.

-- Server / Instance Logins (results not sensitive to local / current Database)
;WITH certs_n_keys AS
(
  SELECT 'Certifcate' AS [Type], crts.name, crts.certificate_id AS [cert_or_asymkey_id],
         crts.principal_id, crts.pvt_key_encryption_type_desc, crts.[sid],
         crts.thumbprint
  FROM   [master].sys.certificates crts
  UNION ALL
  SELECT 'Asymmetric Key' AS [Type], asym.name, asym.asymmetric_key_id AS
         [cert_or_asymkey_id], asym.principal_id, asym.pvt_key_encryption_type_desc,
         asym.[sid], asym.thumbprint
  FROM   [master].sys.asymmetric_keys asym
)
SELECT cnk.*, '---' AS [---],
       sp.[name] AS [PrincipalName], sp.principal_id, sp.type_desc,
       sp.create_date, sp.modify_date
FROM   certs_n_keys cnk
INNER JOIN sys.server_principals sp
        ON sp.[sid] = cnk.[sid];


-- Database Users
;WITH certs_n_keys AS
(
  SELECT 'Certifcate' AS [Type], crts.name, crts.certificate_id AS [cert_or_asymkey_id],
         crts.principal_id, crts.pvt_key_encryption_type_desc, crts.[sid],
         crts.thumbprint
  FROM   sys.certificates crts
  UNION ALL
  SELECT 'Asymmetric Key' AS [Type], asym.name, asym.asymmetric_key_id AS
         [cert_or_asymkey_id], asym.principal_id, asym.pvt_key_encryption_type_desc,
         asym.[sid], asym.thumbprint
  FROM   sys.asymmetric_keys asym
)
SELECT cnk.*, '---' AS [---],
       dp.[name] AS [PrincipalName], dp.principal_id, dp.type_desc,
       dp.create_date, dp.modify_date
FROM   certs_n_keys cnk
INNER JOIN sys.database_principals dp
        ON dp.[sid] = cnk.[sid];


-- Service Broker Endpoints
SELECT crts.name, crts.certificate_id, crts.principal_id,
       crts.pvt_key_encryption_type_desc, crts.[sid], crts.thumbprint, '---' AS [---],
       endpts.*
FROM   sys.certificates crts
INNER JOIN sys.service_broker_endpoints endpts
        ON endpts.certificate_id = crts.certificate_id;


-- Database Mirroring Endpoints
SELECT crts.name, crts.certificate_id, crts.principal_id,
       crts.pvt_key_encryption_type_desc, crts.[sid], crts.thumbprint, '---' AS [---],
       endpts.*
FROM   sys.certificates crts
INNER JOIN sys.database_mirroring_endpoints endpts
        ON endpts.certificate_id = crts.certificate_id;


-- Symmetric Keys (scroll results to the right to see Key name)
SELECT crts.name, crts.certificate_id, crts.principal_id,
       crts.pvt_key_encryption_type_desc, crts.[sid], crts.thumbprint, '---' AS [---],
       ncrptns.*, '---' AS [---], symkys.*
FROM   sys.certificates crts
INNER JOIN sys.key_encryptions ncrptns
        ON ncrptns.[thumbprint] = crts.[thumbprint]
INNER JOIN sys.symmetric_keys symkys
        ON symkys.[symmetric_key_id] = ncrptns.[key_id];


-- Database Encryption Keys (for TDE; results not sensitive to local / current Database)
SELECT crts.name, crts.certificate_id, crts.principal_id,
       crts.pvt_key_encryption_type_desc, crts.[sid], crts.thumbprint, '---' AS [---],
       DB_NAME(dbkeys.[database_id]) AS [DatabaseName], dbkeys.*
FROM   [master].sys.certificates crts
INNER JOIN sys.dm_database_encryption_keys dbkeys
        ON dbkeys.[encryptor_thumbprint] = crts.[thumbprint];
Соломон Руцкий
источник
Спасибо за предоставление запросов. Большинство запросов вернули 0 строк. Шифрование симметричного ключа вернуло одну строку, которая выглядит как мой сертификат. Однако мне все еще неясно, что подписано или зашифровано этим сертификатом и как его удалить.
Джефф Доуди
1
@ GeoffDawdy Ну, все дальше :-). Это должен быть сам Симметричный Ключ. Я также могу обновить запрос до JOIN в этой таблице. Оставайтесь на линии.
Соломон Руцки
@GeoffDawdy Я обновил этот один запрос. Пожалуйста, попробуйте новую версию. Конечно, если используется один или несколько симметричных ключей, это другая проблема ;-). И обязательно удалите файл резервной копии сертификата и его
закрытого
Да, тот же сертификат появился. Значит ли это, что сертификат подписан сам по себе? Как я могу удалить его, если получаю сообщение о том, что его нельзя удалить.
Джефф Дауди
1
Я просто понял это. Мой ключ, который был подписан сертификатом, должен быть удален. После того, как я сбросил симметричный ключ, я смог также сбросить сертификат. Спасибо за вашу помощь!
Джефф Доуди
1

Обнаружена похожая проблема, для меня этот запрос помог мне найти подписанный объект:

SELECT OBJECT_SCHEMA_NAME(co.major_id) + '.' + OBJECT_NAME(co.major_id), c.name 
FROM sys.certificates c 
INNER JOIN sys.crypt_properties co ON c.thumbprint = co.thumbprint
WHERE co.crypt_type_desc = 'SIGNATURE BY CERTIFICATE'

Источник

Затем я просто использовал следующую команду в качестве примера, где dbo.sp_nameнаходится подписанный объект и STOREDPROCEDURESIGNINGCERTсертификат подписи.

DROP SIGNATURE FROM OBJECT::dbo.sp_name BY CERTIFICATE STOREDPROCEDURESIGNINGCERT
MichaelChan
источник