错误:“无法删除该证书,因为一个或多个实体使用该证书进行了签名或加密。”


8

我有一个要从数据库中删除的证书。

如果我发出命令

DROP CERTIFICATE <FooCert>

我得到错误

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

根据Jason Strate的说法,我应该能够找出证书所签名的内容。

以下查询返回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'

我还尝试根据此SO问题将实体分离。 /programming/52460/how-do-i-find-and-decouple-entities-from-a-certificate-when-upgrading-ms-sqlserv

如何删除此证书上的依赖项,以便可以删除它?


能否请您尝试我在此处发布的查询:查找已签名的过程,函数,触发器,程序集以及使用哪种证书/不对称密钥。有什么发现吗?如果是这样,我可以发布它,或者只是在此处链接。如果不是,我猜它是基于证书的登录名/用户,我可以为此发布查询。
所罗门·鲁茨基

返回0行。
Geoff Dawdy '16年

您是否在任何数据库上启用了“透明数据加密”(TDE)?
SQLPRODDBA

1
@SQLPRODDBA感谢您提及TDE :-)。我没有考虑过,但是在我的答案中添加了一个查询以找到它(并对其进行了测试并确认它可以工作)。
所罗门·鲁兹基

1
@srutzky感谢您考虑!您的脚本很棒!
SQLPRODDBA 2016年

Answers:


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行。对称密钥加密返回一行,这似乎是我的证书。但是,我仍然不清楚此证书签名或加密的内容以及如何删除它。
Geoff Dawdy

1
@GeoffDawdy好吧,走得更远:-)。它应该是对称密钥本身。我也可以将查询更新为该表中的JOIN。坚持,稍等。
所罗门·

@GeoffDawdy我已经更新了该查询。请尝试新版本。当然,如果正在使用一个或多个对称密钥,那是另一个问题;-)。并确保在删除之前具有证书及其私钥的备份文件:-)
Solomon Rutzky

是的,显示了相同的证书。那么这是否意味着证书是自己签名的?如果收到错误消息说无法删除它,该如何删除它。
Geoff Dawdy

1
我只是想通了。需要删除由证书签名的我的密钥。删除对称密钥后,我也可以删除证书。感谢你的帮助!
Geoff Dawdy '16年

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.