如何对assembly_bits/十六进制字节创建的SQL Server程序集签名?
SQL Server 2019 十六进制字节形式CLR程序集签名方案
直接对数据库中存储的assembly_bits原始十六进制字节做签名是不可行的,CLR程序集签名包含完整的哈希校验逻辑,直接修改存储的字节会导致程序集加载校验失败,正确操作流程如下:
具体操作步骤
- 导出数据库中现有程序集为本地DLL文件
首先执行T-SQL查询获取目标程序集的完整二进制值:
将查询返回的0x开头的长十六进制串,通过PowerShell转存为本地DLL文件,注意转换前先去掉字符串开头的SELECT content FROM sys.assembly_files WHERE assembly_id = ASSEMBLY_ID('HelloWorld')0x前缀:# 替换为你查询到的、去掉0x前缀的完整十六进制内容 $hexContent = "4D5A900000000000......" $byteArray = [byte[]]::new($hexContent.Length / 2) for ($i = 0; $i -lt $byteArray.Length; $i++) { $byteArray[$i] = [Convert]::ToByte($hexContent.Substring($i * 2, 2), 16) } [IO.File]::WriteAllBytes("C:\temp\HelloWorld_unsigned.dll", $byteArray) - 对导出的DLL文件完成签名
如果你使用强名称签名,先准备好签名密钥(没有密钥可通过sn.exe工具生成),对已编译的无源码DLL签名需要加-R参数执行重签名:
如果使用代码签名证书做Authenticode签名,直接用:: 首次生成密钥对时执行,已有密钥可跳过 sn -k C:\temp\clr_sign_key.snk :: 对导出的DLL重签名 sn -R C:\temp\HelloWorld_unsigned.dll C:\temp\clr_sign_key.snksigntool.exe操作即可:signtool sign /f C:\temp\your_code_sign_cert.pfx /p 证书密码 C:\temp\HelloWorld_unsigned.dll - 将签名后的DLL转回十六进制格式,更新数据库中的程序集
用PowerShell读取签名后DLL的二进制内容,转回SQL可识别的0x开头十六进制串:
可以选择两种方式更新数据库内的程序集,优先用$signedBytes = [IO.File]::ReadAllBytes("C:\temp\HelloWorld_unsigned.dll") $signedHex = "0x" + ($signedBytes | ForEach-Object { $_.ToString("X2") }) -join '' $signedHex | Out-File C:\temp\signed_assembly_hex.txtALTER ASSEMBLY避免删除重建带来的依赖问题:-- 方式1:直接更新现有程序集,无需删除依赖对象 ALTER ASSEMBLY HelloWorld FROM 0x4D5A9000...... -- 替换为上一步生成的签名后程序集完整十六进制串 WITH PERMISSION_SET = UNSAFE; -- 方式2:如果ALTER更新失败,先删除所有依赖该程序集的CLR对象(存储过程、函数、类型等),再删除重建 -- DROP ASSEMBLY HelloWorld; -- CREATE ASSEMBLY HelloWorld FROM 0x4D5A9000...... WITH PERMISSION_SET = UNSAFE;
注意事项
- SQL Server 2019默认启用
clr strict security配置,签名完成后需要将签名对应的公钥(强名称密钥/代码签名证书)导入master数据库,创建对应登录并授予UNSAFE ASSEMBLY权限,程序集才能正常加载,不建议直接关闭严格安全配置规避校验,会引入安全风险。 - 签名前后程序集的版本、元数据不要做其他修改,否则会导致依赖对象绑定失败。
内容的提问来源于stack exchange,提问作者Russ960
相关产品推荐
相关产品推荐

