Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you programmatically (re)sign a .NET assembly with a strong name?

Aside from invoking the command line to add a strong name to an assembly, is there any APIs out there that let you resign an assembly once it has been stripped of its strong name?

like image 951
plaureano Avatar asked Mar 28 '09 10:03

plaureano


People also ask

How do I digitally sign a .NET assembly?

You sign an application or component by using the Signing tab of the project properties window (right-click the project node in Solution Explorer and select Properties). Select the Signing tab, then select the Sign the assembly check box.

How do you fix referenced assembly does not have a strong name error?

The solution was to install StrongNamer from NuGet, which automatically adds a strong name to all referenced assemblies. Just simply having it referenced in the project fixed my issue.

What is strong name in .NET assembly?

A strong name consists of the assembly's identity—its simple text name, version number, and culture information (if provided)—plus a public key and a digital signature. It is generated from an assembly file using the corresponding private key.

Can I register my assembly in GAC with out strong name?

In order to deploy an assembly in GAC, we have to create a strong name for an assembly. Kindly Note : We cannot deploy an assembly in GAC without a strong name, Each and every assembly need to have a strong name for an assembly in order to deploy it in GAC.


2 Answers

It depends on what you mean by an assembly being "stripped of its strong name". If an assembly is not strongly named, nothing (not even sn.exe) can resign the assembly until it has been re-built with a strong name.

But to answer your question: all of the strong naming functionality is exposed through the CLR's unmanaged strong naming API. Specifically, you want StrongNameSignatureGenerationEx, which, as you'll notice, is functionally equivalent to the sn -R[a] command.

That being said, it is much simpler and easier to just invoke sn.exe itself. Accessing the unmanaged strong name APIs is not for the faint of heart, since (as of .NET 4) you are forced to go through the CLR's metahosting APIs first. For this reason, you're also pretty much stuck with having to do this entirely in unmanaged code. (I did find a managed wrapper from Microsoft on CodePlex, but I couldn't get StrongNameSignatureGenerationEx to work properly through it.)

If you have to, though, here's a rough outline of how to access the strong naming APIs from unmanaged code:

  • Obtain an instance of ICLRMetaHost or ICLRMetaHostPolicy by calling CLRCreateInstance.
  • With that instance, obtain an instance of the current runtime (i.e. an ICLRRuntimeInfo instance). There are numerous ways to do this; see MSDN for the gory details.
  • Once you have an instance of ICLRRuntimeInfo, obtain an instance of ICLRStrongName by calling ICLRRuntime's GetInterface method, passing in CLSID_CLRStrongName and IID_ICLRStrongName for the class/interface identifiers.

Now that you have an instance of ICLRStrongName, you can finally call StrongNameSignatureGenerationEx using it:

// This is the ICLRStrongName instance you'll need. Assume GetStrongNameAPI
// corresponds to an implementation of the rough process I outlined above.
ICLRStrongName *snAPI = GetStrongNameAPI();

// You'll have to load the .snk file into memory yourself using the Win32
// file APIs, the details of which I've omitted for the sake of brevity.
BYTE *keyPairBlob = NULL;
DWORD keyPairBlobSize = 0;
LoadKeyPair(&keyPairBlob, &keyPairBlobSize);

// Once you've got the key pair blob, you can now (re-)sign the assembly
HRESULT hr = snAPI->StrongNameSignatureGenerationEx(
    L"path\\to\\your\\assembly.dll", 
    NULL,
    keyPairBlob,
    keyPairBlobSize,
    NULL,
    NULL,
    0
);

// Do whatever error handling needs to be done with the given HRESULT

(Optionally, if you want to sign with a key container instead of a .snk key pair, you can pass in the name of the key container as the second argument and leave the key pair blob/size arguments as NULL.)

Bottom Line: As you can see, unless you really have to go through the strong naming API, it is much easier to (re-)sign an assembly by just invoking sn.exe itself.

like image 184
hbw Avatar answered Sep 23 '22 17:09

hbw


You could look into mscoree's strong name APIs, but I wouldn't recommend it.

like image 40
Anton Tykhyy Avatar answered Sep 24 '22 17:09

Anton Tykhyy