SQLCLR - 如何在不设置 TRUSTWORTHY ON 的情况下注册我的 CLR 程序集的引用程序集?

SQLCLR - How can I register referenced assemblies of my CLR assembly without setting TRUSTWORTHY ON?

我在注册 SQL CLR 程序集中使用的引用程序集时遇到问题。例如,我有 SQL 个名为 Something.dll 的 CLR 程序集。此 Something.dll 引用 Newtonsoft.dll。

我签署 Something.dll 然后创建非对称密钥以将其注册到 PERMISSION_SET = EXTERNAL_ACCESS。但是,我无法签署引用的程序集,因此 SQL 服务器不允许我在未设置 TRUSTWORTHY ON.

的情况下使用 UNSAFEEXTERNAL_ACCESS 权限注册它

有没有什么办法不用设置TRUSTWORTHY ON就可以注册Newtonsoft.dll?

您可以使用证书代替非对称密钥。请参阅我的博客-post here 了解更多信息。

/尼尔斯

您可以使用您创建的证书对引用的程序集进行签名,将该证书加载到 SQL 服务器中,然后再尝试在 SQL 服务器中创建程序集,从证书,并授予该登录所需的权限,EXTERNAL ACCESS ASSEMBLYUNSAFE ASSEMBLY。事实上,为您自己的程序集使用相同的证书将允许它从 VARBINARY 文字/十六进制字节字符串加载,而不需要文件系统上的 DLL,这意味着该解决方案将在 SQL 服务器 2017 及更新版本。

应按以下步骤完成:

  1. 通过命令提示符创建证书:

    MAKECERT -r -pe -n "CN=some name,O=your company,C=US" ^
    -e "12/31/2099" -sv private_key_file.pvk ^
    public_key_file.cer
    

    系统将通过模态弹出窗口提示您输入密码。你应该得到 2 个提示。两次使用相同的密码。

  2. 通过命令提示符将 public 密钥和私钥文件合并到一个 PFX 文件中:

    PVK2PFX -pvk private_key_file.pvk -pi password ^
    -spc public_key_file.cer ^
    -pfx signing_certificate.pfx
    
  3. 通过命令提示符签署 DLL:

    signtool.EXE sign /v /p password ^
    /f signing_certificate.pfx ^
    NewtonSoft.dll
    
    signtool.EXE sign /v /p password ^
    /f signing_certificate.pfx ^
    MyProject.dll
    
  4. 将 public 密钥转换为 VARBINARY 文字,以便可以从 SQL 脚本创建它,而不依赖于文件系统,通过命令提示符(BinaryFormatter 是我编写的一个开源实用程序,可在 GitHub 上使用,它将二进制文件转换为十六进制字节字符串,包括每行 80 个字符换行,这样你就没有一个愚蠢的-长行):

    BinaryFormatter.exe public_key_file.cer ^
    create_certificate_script.sql 40
    
  5. 将每个 DLL 转换为 VARBINARY 文字,以便可以通过命令提示符从 SQL 脚本创建它,而不依赖于文件系统:

    BinaryFormatter.exe Newtonsoft.DLL ^
    create_Newtonsoft_script.sql 40
    
    BinaryFormatter.exe MyProject.DLL ^
    create_MyProject_script.sql 40
    
  6. 在 SQL 服务器中,创建证书、关联的登录名,并授予其所需的权限:

    USE [master];
    
    CREATE CERTIFICATE [MySqlclrStuff]
    FROM BINARY = 0x{contents_of_create_certificate_script.sql};
    
    CREATE LOGIN [MySqlclrStuff]
    FROM CERTIFICATE [MySqlclrStuff];
    
    GRANT UNSAFE ASSEMBLY TO [MySqlclrStuff];
    
  7. 在 SQL 服务器中,在您的目标数据库中(不在 master 中),创建两个程序集:

    USE [SomeDB];
    
    CREATE ASSEMBLY [Newtonsoft]
    FROM 0x{contents_of_create_Newtonsoft_script.sql}
    WITH PERMISSION_SET = UNSAFE;
    
    CREATE ASSEMBLY [MyProject]
    FROM 0x{contents_of_create_MyProject_script.sql}
    WITH PERMISSION_SET = UNSAFE;
    

如果您想知道如何在 Visual Studio / SSDT 中自动执行此操作,请参阅我的以下博客 post,其中详细介绍了如何执行此操作:

SQLCLR vs. SQL Server 2017, Part 3: “CLR strict security” – Solution 2