【发布时间】:2017-10-04 18:14:45
【问题描述】:
所以我在网上搜索了很多答案。我已经成功创建了一个模板,用于以编程方式使用简单的强名称和证书将CLR Assemblies 部署到多个(超过 100 个)SQL Server 实例和服务器......甚至不需要使用像 VISUAL STUDIO 这样的 IDE,除了语法和检查程序集。 :)
唯一的问题似乎是我用来签名的公钥,因为 C# 编译器 csc.exe 使用 SHA-1 哈希对程序集进行签名。所以唯一的解决方法是使用Enhanced Strong Naming 或MSBuild(这里不是真正的选择)。
增强的强命名是一个非常简单的过程:
-
创建强名称密钥 (
snk) 文件:sn.exe -k [RSA_Length] CLR_IdentityKey.snk -
发布公钥并使用
SHA-2对其进行哈希处理sn.exe -p CLR_IdentityKey.snk CLR_PubKey.snk sha256 -
延迟使用公钥对您的程序集进行签名(csc.exe 的来源决定了您程序集的 .NetFramework 兼容性)
csc.exe /target:library /keyfile:CLR_PubKey.snk /out:CLR_Assembly.dll "YourCSFiles.cs" "YourCSFiles2.cs" "YourCSFiles3.cs" /DelaySign+ -
然后使用 StrongName 工具使用原始密钥对程序集进行签名。
sn.exe -Ra CLR_Assembly.dll CLR_IdentityKey.snk
想要使用增强型强名称方法签署我的程序集的主要原因有两个:
- 避免在多台服务器上长时间暴露私钥。
- 在创建
ASYMMETRIC KEY时提供发布散列公共 snk 的替代方法以及设置加密密码的选项。
请注意,虽然我可以同时使用pfx 和简单的 snk 文件来完成此操作,但这里的程序集是一个简单的 HTTP POST 操作,并且证书的成本是令人望而却步的,因为它在 Intranet 环境中的用途很小.
现在检查已签名的程序集,我在清单中看到以下内容:
公钥(哈希算法:sha256): 002400000c80000014010000060200...
公钥令牌是 b8ee775aa5bfbc5b
显然 sn.exe 已经成功地使用 SHA-2 方法对程序集进行了签名。
不幸的是,当我尝试在 SQL Server 中基于此签名程序集创建我的非对称密钥时,似乎公钥关联不正确。
消息 10327,第 14 级,状态 1,第 14 行
为程序集创建程序集 “CLR_Assembly”失败,因为程序集“CLR_Assembly”未被授权 PERMISSION_SET = 不安全。大会被授权时 以下情况属实:数据库所有者 (DBO) 具有 UNSAFE ASSEMBLY 权限并且数据库具有 TRUSTWORTHY 数据库属性; 或程序集使用证书或非对称密钥签名 具有相应的具有 UNSAFE ASSEMBLY 权限的登录名。
示例代码: 请注意,命名实例和默认名称在位置和安全权限方面存在差异。选择的文件夹可能没有足够的权限,因此您可能必须添加它。
Powershell:
# The version of csc.exe dictates the version of .NetFramework your assembly is created.
$csc_path="C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe"
$sn_path="C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.2 Tools\sn.exe"
$CLR_path="C:\Program Files\Microsoft SQL Server\MSSQL13.TESTSQL\MSSQL\JOBS\"
$CLR_Assembly_SNK=$CLR_path + "CLR_SNK.dll"
$CLR_Assembly_DelaySign=$CLR_path + "CLR_DelaySign.dll"
$cs_BackComp="C:\Program Files\Microsoft SQL Server\MSSQL13.TESTSQL\MSSQL\JOBS\BackwardsCompatibility.cs "
$cs_MyMethods="C:\Program Files\Microsoft SQL Server\MSSQL13.TESTSQL\MSSQL\JOBS\MyMethods.cs "
$cs_Main="C:\Program Files\Microsoft SQL Server\MSSQL13.TESTSQL\MSSQL\JOBS\CLR_JSON_Program.cs"
$CLR_IdentityKey=$CLR_path + "CLR_IdentityKey.snk"
$CLR_IdentityKey1=$CLR_path + "CLR_IdentityKey1.snk"
$CLR_PubKey=$CLR_path + "CLR_PubKey.snk"
#using SNK method
& $sn_path -k 2048 $CLR_IdentityKey
& $csc_path /target:library /out:$CLR_Assembly_SNK /keyfile:$CLR_IdentityKey $cs_BackComp $cs_MyMethods $cs_Main
& $sn_path -Tp $CLR_Assembly_SNK
# using delaySign+ method version
& $sn_path -k 2048 $CLR_IdentityKey1
& $sn_path -p $CLR_IdentityKey $CLR_PubKey sha256
& $csc_path /target:library /out:$CLR_Assembly_DelaySign /keyfile:$CLR_PubKey $cs_BackComp $cs_MyMethods $cs_Main /DelaySign+
& $sn_path -Ra $CLR_Assembly_DelaySign $CLR_IdentityKey
& $sn_path -Tp $CLR_Assembly_DelaySign
T-SQL 代码:
USE MASTER
GO
CREATE ASYMMETRIC KEY CLR_SNK_KEY
FROM EXECUTABLE FILE = 'C:\Program Files\Microsoft SQL Server\MSSQL13.TESTSQL\MSSQL\JOBS\CLR_SNK.dll'
CREATE LOGIN CLR_SNK
FROM ASYMMETRIC KEY CLR_SNK_KEY
GRANT UNSAFE ASSEMBLY TO CLR_SNK
GO
CREATE ASSEMBLY CLR_SNK_ASSEMBLY
AUTHORIZATION [dbo]
FROM 'C:\Program Files\Microsoft SQL Server\MSSQL13.TESTSQL\MSSQL\JOBS\CLR_SNK.dll'
WITH PERMISSION_SET = UNSAFE
GO
DROP LOGIN CLR_SNK
DROP ASYMMETRIC KEY CLR_SNK_KEY
DROP ASSEMBLY CLR_SNK_ASSEMBLY
GO
/*DelaySign+ Version*/
CREATE ASYMMETRIC KEY CLR_Delay_KEY
FROM EXECUTABLE FILE = 'C:\Program Files\Microsoft SQL Server\MSSQL13.TESTSQL\MSSQL\JOBS\CLR_DelaySign.dll'
CREATE LOGIN CLR_Delay
FROM ASYMMETRIC KEY CLR_Delay_KEY
GRANT UNSAFE ASSEMBLY TO CLR_Delay
GO
-- fails here due to the ASYMMETRIC key not matching the assembly
CREATE ASSEMBLY CLR_Delay_Assembly
AUTHORIZATION [dbo]
FROM 'C:\Program Files\Microsoft SQL Server\MSSQL13.TESTSQL\MSSQL\JOBS\CLR_DelaySign.dll'
WITH PERMISSION_SET = UNSAFE
我的 C# 程序集使用 var postRequest = (HttpWebRequest)WebRequest.Create(uri);,这不是一种安全的方法,至少需要 EXTERNAL_ACCESS。
但是,SQL Server 2017 将放弃对 CAS 安全方法的支持,并引入了快速修复 sp_configure 'clr strict security` 设置。使用 UNSAFE 创建未来的 CLR。 Microsoft (April 19, 2017): CLR String Security
为什么 SQL Server 无法找到正确的公钥,而它们应该是相同的?
有人知道在 SQL Server 中获取延迟程序集的工作示例吗?
【问题讨论】:
-
请注意,
ALTER DATABASE [DB_Name] SET TRUSTWORTHY ON是管理程序集的一种糟糕且可能是懒惰的方法。 -
所以你完成了程序集的所有签名。但是您是否告诉 SQL Server 您信任任何用于 UNSAFE 程序集的关键材料?也就是说,您是否创建了基于密钥或证书的登录名/用户并授予它不安全的组装权限?如果是这样,您能否也发布该代码(请从您的实际密钥材料中编辑)。
-
@BenThul 添加了示例代码
标签: sql-server .net-assembly sqlclr encryption-asymmetric strongname