所以我已经在互联网上搜索了很多答案。我已成功创建了一个模板,用于以编程方式使用简单的强名称和证书将CLR Assemblies
部署到多个(超过100个)SQL Server
个实例和服务器...甚至不需要使用类似IDE的IDE VISUAL STUDIO除语法和检查程序集外。 :)
唯一的问题似乎是我签署的公钥,因为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中基于此签名程序集创建我的非对称密钥时,似乎公钥密钥关联不正确。
Msg 10327,Level 14,State 1,Line 14
为装配创建装配 'CLR_Assembly'失败,因为未授权程序集'CLR_Assembly' PERMISSION_SET = UNSAFE。任何一个组件都被授权 以下情况属实:数据库所有者(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中获取延迟程序集的工作示例?
答案 0 :(得分:1)
为什么SQL Server在它们被认为是同一个时无法找到正确的公钥?
如果暂时将数据库设置为TRUSTWORTHY ON
,以便您可以加载程序集,那么您应该能够看到问题。
SELECT * FROM sys.asymmetric_keys;
SELECT * FROM sys.assemblies;
运行之后你应该看到"指纹" sys.asymmetric_keys
的列与" publickeytoken"不匹配属性显示在" clr_name" sys.assemblies
的列。这很可能是因为在运行sn -p
时使用SHA-256,但您没有选择,因为SHA-1不适用于增强型强命名。 "指纹"非对称密钥是SHA-1,你无法控制它,因此无法使它们匹配。
有没有人知道在SQL Server中获取延迟程序集的工作示例?
幸运的是,Enhanced Strong Naming的文档提到使用AssemblySignatureKeyAttribute属性来允许一些遗留场景工作,这当然可以是一个。事实上,使用该属性确实允许增强强命名工作。
使用SQLCLR获得增强型强命名的步骤(在SQL Server 2016 SP1上测试):
创建身份和签名密钥对:
sn -k 2048 IdentityKey.snk
sn -k 2048 SignatureKey.snk
从两个密钥对中提取公钥:
sn -p IdentityKey.snk IdentityPubKey.snk
sn -p SignatureKey.snk SignaturePubKey.snk sha256
请注意,Identity密钥不使用sha256
,因此使用默认sha1
,而签名密钥 使用{{1} }}
生成sha256
属性所需的publicKey
和counterSignature
值:
AssemblySignatureKey
将前一步骤中生成的两个值复制到一个源文件中(即通常为sn -a IdentityPubKey.snk IdentityKey.snk SignaturePubKey.snk
):
AssemblyInfo.cs
使用延迟签名编译程序集:
[assembly:System.Reflection.AssemblySignatureKey(
"public" +
"key" +
"value",
"counter" +
"Signature" +
"value"
)]
重新签署大会:
csc /target:library /out:MyAssembly.dll SqlStoredProcedure.cs
/keyfile:IdentityPubKey.snk /delaySign+
在SQL Server中,从DLL中创建sn -Ra MyAssembly.dll SignatureKey.snk
中的非对称密钥:
master
从该非对称密钥创建登录并授予其USE [master];
CREATE ASYMMETRIC KEY [MyAsymKey]
FROM EXECUTABLE FILE = N'C:\path\to\MyAssembly.dll';
或EXTERNAL ACCESS ASSEMBLY
:
UNSAFE ASSEMBLY
您只需要授予其中一个CREATE LOGIN [MyAsymKeyLogin]
FROM ASYMMETRIC KEY [MyAsymKey];
GRANT UNSAFE ASSEMBLY TO [MyAsymKeyLogin];
隐含UNSAFE
,但从SQL Server 2017开始,如果您使用的是EXTERNAL ACCESS
的默认配置,则需要是clr strict
。
更改为目标数据库并创建程序集:
UNSAFE ASSEMBLY
P.S。您的其他问题主要是非问题:
USE [Test];
ALTER DATABASE CURRENT SET TRUSTWORTHY OFF; -- Just to be sure!
CREATE ASSEMBLY [MyAssembly]
FROM N'C:\path\to\MyAssembly.dll'
WITH PERMISSION_SET = UNSAFE;
的一部分(因为它是从程序集创建的),因此没有潜力。ASYMMETRIC KEY
设置密码不是一个选项,因为私钥不存在(因为它是从程序集创建的)。CREATE ASYMMETRIC KEY
或PowerShell)是可以的,特别是对于这是一个小型的内部项目。使用证书的一个好处是您可以从十六进制字节而不是文件或程序集创建它,并且因为您也可以从十六进制字节创建程序集,您的安装脚本可以完全可移植,因为它不会有任何文件系统引用: - )。