Is it possible to create an asymmetric key for a .NET framework assembly in SQL Server 2014?

梦想的初衷 提交于 2019-11-30 18:47:26

No, I have never found a way to accomplish this. The key used to sign the .NET Framework Assembly is internal / private to Microsoft. The options tried:

  • Extract Private Key / load into SQL Server: not possible, else the key wouldn't be "private". The signature / strong naming system is effective because outsiders cannot claim that they signed the code.

  • Add a signature: I tried adding a new one using the sn utility. Doesn't work due to:

    Failed to re-sign the assembly -- Public key of assembly did not match signing public key.

    But, even if this did work, that might not mean that loading it into SQL Server would work since it is not the same Assembly that you added as a resource to your project. Other .NET Framework DLLs, if there are any other dependencies, would only know of the original signature.

  • Remove current signature and add a new one: I tried using ILDASM to disassemble System.Runtime.Serialization.dll, and then add a new private key created from sn -k and then relink using ILASM, but that failed on the ILASM step (and I don't have time to investigate further).

    But just like the option above, even if this did work, you would have to change the Json.NET project reference for System.Runtime.Serialization to be this new DLL, recompile it, then change your project reference to be the new DLL, and then recompile that. But this would only get you the ability to load the DLLs cleanly, it would not guarantee that they would work if they have external dependencies that are expecting the original Microsoft signature.

Essentially, if you are loading DLLs that you don't have control of in terms of the signature, then the only hope is to decompile using ILDASM and recompile using ILASM, specifying a new snk file, but that won't work if other Assemblies are linked to what is being recompiled. And certainly .NET Framework DLLs fall into this category.

Simply put: if you are loading unsupported .NET Framework DLLs, then you pretty much need to set TRUSTWORTHY ON.

BUT: Keep in mind that even if this did work to load everything via an Asymmetric Key or Certificate, that does not mean that you won't run into functional problems. There is a reason why these libraries have not been approved / validated. There is code in them doing things that could work in ways that you are not expecting, such as storing data to static fields. In Windows and Console apps this is not an issue as it is one use per App Domain. But SQLCLR employs a shared App Domain, so multiple SQL Server Sessions will share those static variables. It might be that the methods called by the Json.NET library don't use those unsafe things, but there is no way of knowing, and even if we did know, not much we can do about it now :-(.


One thing that I have been contemplating is tracing through the methods called in the unsupported .NET Framework DLL, and assuming that it is not doing anything unsafe, copying that code directly into the project. Theoretically that should work, as long as the calls into System.Runtime.Serialization do not call other unsupported DLLs or do "unsafe" things, etc. But, I haven't had time to test this out.

I managed to do this on SQL Server 2014 (version 11.0.6248.0) for the .Net Framework 4 Systen.Drawing.dll, using the following script

USE MASTER
GO

CREATE 
    ASYMMETRIC KEY SystemDrawingKey 
    FROM EXECUTABLE FILE = N'C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Drawing.dll'   

CREATE 
    LOGIN SystemDrawingKeyLogin 
    FROM ASYMMETRIC KEY SystemDrawingKey   

GRANT UNSAFE ASSEMBLY TO SystemDrawingKeyLogin

USE MY_DATABASE
GO 

CREATE ASSEMBLY [SystemDrawing]
FROM N'C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Drawing.dll' WITH PERMISSION_SET = UNSAFE
GO 

SQL Server accepts this assembly, but gives a warning:

Warning: The Microsoft .NET Framework assembly 'system.drawing, version=4.0.0.0, culture=neutral, publickeytoken=b03f5f7f11d50a3a, processorarchitecture=msil.' you are registering is not fully tested in the SQL Server hosted environment and is not supported. In the future, if you upgrade or service this assembly or the .NET Framework, your CLR integration routine may stop working. Please refer SQL Server Books Online for more details.

To verify that the thustworthy setting is off, I ran the following query from A warning about the TRUSTWORTHY database option:

SELECT name, is_trustworthy_on
FROM sys.databases
WHERE name <> 'msdb'
AND is_trustworthy_on = 1

Which gave no results. Of course, now I have WITH PERMISSION_SET = UNSAFE, but that seems less problematic.

System.Drawning.dll is a dependency I need for a third party assembly. I am pretty sure the methods I call do not invoke anything in System.Drawing, so for now, I keep things this way.

Also, I got an error when creating my own custom assemby. I have lost the exact error, but mentioned Synchonization and it referenced System.Diagnostics, which helped me find a call to Debug.WriteLine. After remvoing that, the assembly could be created and all worked fine.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!