c# - 在 SQL Server 2014 中为不安全的程序集创建非对称 key

标签 c# sql-server assemblies sqlclr encryption-asymmetric

我在 Visual Studio (VS) 2015 中签署了 2 个 DLL。一名前雇员创建了一个非对称 key 并登录,我在 UNSAFE 模式下正确运行了其中一个程序集。

第二个出现以下错误:

Msg 10327, Level 14, State 1, Line 27
CREATE ASSEMBLY for assembly 'TableFile' failed because assembly 'TableFile' is not authorized for PERMISSION_SET = UNSAFE. The assembly is authorized when either of the following is true: the database owner (DBO) has UNSAFE ASSEMBLY permission and the database has the TRUSTWORTHY database property on; or the assembly is signed with a certificate or an asymmetric key that has a corresponding login with UNSAFE ASSEMBLY permission.

我不能问前雇员,所以我如何才能知道如何让它运行?我也试过这个:

USE master; 
GO  

CREATE ASYMMETRIC KEY AProjectKey FROM EXECUTABLE FILE = 'E:\sqldlls\TableFile.dll' 
CREATE LOGIN AProjectLogin FROM ASYMMETRIC KEY AProjectKey ;  
GRANT UNSAFE ASSEMBLY TO AProjectLogin ;
GO

这会产生以下错误:

Msg 15396, Level 16, State 1, Line 9
An asymmetric key with name 'AProjectKey' already exists or this asymmetric key already has been added to the database.

Msg 15151, Level 16, State 1, Line 10
Cannot find the asymmetric key 'AProjectKey', because it does not exist or you do not have permission.

Msg 15151, Level 16, State 1, Line 11
Cannot find the login 'AProjectLogin', because it does not exist or you do not have permission.

如何让这两个程序集在不安全模式下运行?提前致谢。

最佳答案

关于这 3 条错误消息:

  1. 第一个可能是由于非对称 key 已经存在,但名称不同。 key 和证书在其公钥方面需要是唯一的,而不仅仅是名称(尽管这显然也需要是唯一的)。每个 key 和证书都有一个公钥散列,称为“指纹”。创建新 key /证书时会检查现有 key /证书的指纹,如果指纹已经存在,将阻止创建,即使是名称不同的 key /证书。这就是错误消息“或此非对称 key 已添加到数据库”的含义。

    或者:

    这可能意味着 master 中存在不同的非对称 key (即不同的“指纹”),但名称为 AProjectKey

  2. 因为您无法以不同的名称创建相同的 key ,所以不存在具有该新名称的非对称 key ,因此您无法从中创建登录(同样,CREATE ASYMMETRIC KEY语句失败)。
  3. 因为您无法创建登录名,所以它不存在,无法授予任何权限。

错误 # 2 有助于缩小问题范围。如果错误 # 1 是由具有相同名称但不同“指纹”的现有非对称 key 引起的,那么您要么能够创建登录名(如果它尚不存在),要么您会收到一条错误消息,指出登录名(即“服务器主体”)已经存在。但错误是无法找到该名称 的非对称 key 。这应该意味着非对称 key 本身确实已经存在,但名称不同。您可以通过执行以下命令查看已创建的非对称 key :

SELECT * FROM sys.asymmetric_keys;

但这并没有告诉您哪一个来自该程序集(或使用相同强名称 key 签名的程序集用于签署此程序集)。为此,您需要知道“指纹”,为此您需要打开命令提示符(最好是 Visual Studio 在安装时设置的“开发人员命令提示符”,因为它在打开时设置了正确的路径)。然后,运行以下命令:

CD /D E:\sqldlls\
sn -T TableFile.dll

你应该看到:

Public key token is XXXXXXXXXXXXXXXX

将该 XXXXX“ token ”(即指纹)复制并粘贴到以下查询中:

SELECT ak.[name], ak.[sid]
FROM   sys.asymmetric_keys ak
WHERE  ak.[thumbprint] = 0x{XXXXXXXXXXXXXXXX}; -- remove the { and }

假设您返回一行,我们需要查看登录名是否存在。简单地尝试从非对称 key 创建登录名不会让我们获得登录名(如果它确实存在),因为每个 key /证书只能创建 1 个登录名,并且错误消息仅报告您尝试创建的名称已经存在的那个,即使它可以是同一个 key 的不同名称。因此,从返回的行中获取 SID 并将其粘贴到以下查询中:

SELECT sp.*
FROM   sys.server_principals sp
WHERE  sp.[sid] = 0x{SID_from_sys_asymmetric_keys}; -- remove the { and }

如果没有返回任何行,那么您应该从该非对称 key 创建一个登录名。

此时应该存在一个登录名,因此授予它UNSAFE ASSEMBLY权限。

现在再次尝试创建程序集。

关于c# - 在 SQL Server 2014 中为不安全的程序集创建非对称 key ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47300062/

相关文章:

c# - 使用 protobuf-net 序列化不可变集合

c# - 了解.NET中的垃圾收集

c# - 如何创建一个对象的实例?

sql-server - 执行批处理时发生错误。错误消息是: Exception of type 'System.OutOfMemoryException' was thrown.“

sql - 为什么 SQL Server 突然决定使用这么可怕的执行计划?

sql - 从 C# 中的 SQL CLR 过程调用 WCF 服务

c# - 为什么在着色器中顺序很重要?

php - 在 Zend Framework 2 中生成具有多个数据库连接的 Doctrine 2 实体

c# - 在 C# 中序列化和反序列化外部程序集

c# - 错误 : add a reference to assembly 'System.ServiceModel, Version=3.0.0.0'