pavanarya – Pavan Kumar Aryasomayajulu

Contact Email : pavan.aryasomayajulu@gmail.com

Global Assembly Cache(GAC) And Signing Of A Dll

with one comment

Hi In this post i want to write about Global Assembly Cache and signing of a dll with strong name.

What is Global assembly cache(GAC)

When ever we install .net framework or Common Language Runtime(CLR) then a cache will be created and that cache consists of assembly’s that were used by all the applications. This cache is called as Global Assembly Cache(Gac)

Gac was designed to store assemblies that were commonly used by number of applications.

Gac generally consists of most important dll’s from the framework.

Physical location of Gac:C:\Windows\assembly

Why do we use Global assembly cache(GAC)

Gac was used to place assemblies that were shared by number of projects.
Gac allows us to have assemblies with same name but different versions

For example i wrote a library application that performs some basic tasks on strings, that were not provided by framework.(Just is just an example)

Suppose let us assume that i am having n number of projects and i want to make use of that dll in all my projects. In that case i can place the dll in the gac.

Why do we 2 Global assembly cache(GAC) in Framework 4.0

With .Net framework 4.0 the GAC was split into 2 parts.

With previous versions ie either with framework 3.5 or 2.0 we are having only 1 global assembly cache and that is located at “C:\Windows\assembly”.

But with framework 4.0 a new Gac was introduced and it is found at “C:\Windows\Microsoft.NET\assembly”.

Note From Microsoft:

The CLR version used for both .NET Framework 2.0 and .NET Framework 3.5 is CLR 2.0. As a result of this, there was no need in the previous two framework releases to split the GAC. The problem of breaking older (in this case, .NET 2.0) applications resurfaces in Net Framework 4.0 at which point CLR 4.0 released. Hence, to avoid interference issues between CLR 2.0 and CLR 4.0, the GAC is now split into private GACs for each runtime.

So from the above comments from microdoft we can understand that in order to avoid conflicts between framework 3.5 dlls and framework 4.0 dll another gac was introduced.

Framework 3.5 and below will use “C:|windows\Assembly” where as framework 4.0 uses new Gac “C:\Windows\Microsoft.NET\assembly”.

Installing a dll into Global assembly cache(GAC)

Step1:
First of all let me create a simple library application with single class.

So the above project consist of a single class called as Class1. I am just create a simple function that returns a string.Please don’t worry about class we are much concerned about installing the dll into Gac 🙂

Class1.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestIngGac
{
    public class Class1
    {
        String pavan = "This is just an example of My Gac post";

        public string ReturnString()
        {
            return pavan;
        }
    }
}

Step2:

Build the project. Now open the folder where the project is present in windows explorer. Now search for the dll either in Bin folder or obj folder.

We can see a dll with the name of the project and a pdb file.

Step3:

Copy the location of the dll.

Now open visual studio command prompt. We can find that in
program files—>Microsoft Visual Studio—>Visual Studio Tools—>Visual studio command prompt.

Step4:

now use the command Gacutil to install the dll into the gac.

After executing this command we can see an error message 🙂

“Failure adding assembly to the cache: Attempt to install an assembly without a s
trong name”

So the error message says that we cannot install a dll into gac if it is not signed with strong name. So how do we sign a dll.

Signing a dll with strong name

There are number of ways to sign a dll with strong name

1.Using Assembly Linker.exe provided by the windows sdk

2.Using assembly attributes like AssemblyKeyFileAttribute in our code.

3.Delay signing of an assembly.

4.Using visual studio to sign the assembly.

In order to sign an assembly it is must to have a cryptographic key pair.

Using visual studio to sign the assembly

i. Right click on the project name and click on properties.

ii.Now check the box “Sign the assembly”. It will ask us to “Choose a strong name key file”.

There we can add a new file or use an existing snk file.
If we want to create a new strong name file specify the name in the box and if we want to protect the file with password we can provide that.
Now a file with the extension snk is created.

Now build the project and the dll obtained now is signed dll.

Using Assembly Linker.exe provided by the windows sdk

i.First of all we are supposed to create an strong name key value pair file using command prompt.

sn -k "F:\My Code\TestIngGac\TestIngGac\bin\Debug\TestSigning.snk"

This will create a snk(Strong name key value pair file) file the location specified.

ii.Create a netmodule for the class file present in the project and this should be linked to the dll in next step

csc /out:"F:\My Code\TestIngGac
\TestIngGac\bin\Debug\Class1.netmodule" /t:module "F:\My Code\TestIngGac\TestIng
Gac\Class1.cs"

This will create a file called Class1.netmodule the path specified.

iii. Now use the al command to sign the dll

al /out:<assembly name> <module name> /keyfile:<file name>

In this command, assembly name is the name of the assembly that should be signed.
Module name is the name of the module associated with assembly.
File name is the path of the snk file.


al /out:"F:\My Code\TestIngGac\TestIngGac\bin\Debug\TestIngGac.dll" /t:library "F:\My Code\TestIngGac\TestIngGac\bin\Debug\Class1.netmodule" /keyfile:"F:\My Code\TestIngGac\TestIngGac\bin\Debug\TestSigning.snk"

iv. Now use gacutil command to place the dll inside the gac

gacutil /i "F:\My Code\TestIngGac\TestIngGac\bin\Debug\TestIngGac.dll"

Using assembly attributes like AssemblyKeyFileAttribute in our code
i.First of all we are supposed to create an strong name key value pair file using command prompt.

sn -k "F:\My Code\TestIngGac\TestIngGac\bin\Debug\TestSigning.snk"

This will create a snk(Strong name key value pair file) file the location specified.

ii.using the attribute AssemblyKeyFileAttribute inside the AssemblyInfo.Cs file.

[assembly: AssemblyKeyFileAttribute(@"F:\My Code\TestIngGac\TestIngGac\bin\Debug\TestSigning.snk")]

When using this attribute specify the key file(snk file) created in step i.

iii. Now compile the project and the dll now obtained is signed.

iv.Install it into Gac using gacutil command

gacutil /i "F:\My Code\TestIngGac\TestIngGac\bin\Debug\TestIngGac.dll"

Delay Signing

Suppose let us assume that there is a strong name file which is to be secured. And only a few people in the organization are having access for the strong name file.

So how does a developer who don’t have access to the strong name file sign the dll. So in order to overcome this process, the concept of delay signing came into picture.

There are multiple steps involved in delay signing a dll.
I.There will be a strong name file(snk file) with the high level organization.
II.Distribute the public key file associated with the strong name file for delay signing to all the developers.
III.Delay sign the assembly

I.Creating the strong name file

First of all we are supposed to create an strong name key value pair file using command prompt.

sn -k "F:\My Code\TestIngGac\TestIngGac\bin\Debug\TestSigning.snk"

This will create a strong name file called TestSigning.snk. This file should be protected from access to others.

II.Creating a public key from TestSigning.snk for delay signing

For getting the public key from a strong name file using sn.exe with option -p

sn -p "F:\My Code\TestIngGac\TestIngGac\bin\Debug\TestSigning.snk" "F:\My Code\TestIngGac\TestIngGac\bin\Debug\Publickey.snk"

III.Add AssemblyKeyFileAttribute and AssemblyDelaySignAttribute to the AssemblyInfo.cs file

[assembly: AssemblyKeyFileAttribute(@"F:\My Code\TestIngGac\TestIngGac\bin\Debug\Publickey.snk")]
[assembly:AssemblyDelaySignAttribute(true)]

IV.Now build the project. Now compiler will create a dll signed using public key that we got in step II.

Note: A delay signed project will not run and cannot be debugged.

V.we can use the Strong Name tool (Sn.exe) with the -Vr option to skip verification during development.
The delay signing process and the absence of an assembly signature means that the assembly will fail verification at load time. This should be used on Test Computers or development computers.

VI.To disable verification for an assembly, use the following command.

sn –Vr "F:\My Code\TestIngGac\TestIngGac\bin\Debug\TestIngGac.dll"

VII. Now send the dll that is signed with public key of original strong name file(TestSigning.snk file) to the person who is having access to the original strong name file (TestSigning.snk) and ask him to resign the file using following command.

sn -R "F:\My Code\TestIngGac\TestIngGac\bin\Debug\TestIngGac.dll" "F:\My Code\TestIngGac\TestIngGac\bin\Debug\T
estSigning.snk"

Now the file is completely signed and now it can be placed in the gac.

VIII. Now use the gacutil command to install the dll in the gac.

gacutil /i "F:\My Code\TestIngGac\TestIngGac\bin\Debug\TestIngGac.dll"

These are the different methods associated with signing a dll.

Summary

In this post we saw what is meant by gac and how to install a dll into gac.
So in order to install a dll into gac it should be signed with strong name and we saw different ways of signing a dll with strong name.

Written by pavanarya

September 2, 2012 at 9:13 pm

Posted in c#

One Response

Subscribe to comments with RSS.

  1. Now, copy the resulting EXE in any other folder and run it. It will display “Hello World” indicating that it is using our shared assembly. This article describes how to generate a strong name for an assembly and to install a .dll file in the Global Assembly Cache. The Global Assembly Cache (GAC) enables you to share assemblies across numerous applications. The GAC is automatically installed with the .NET runtime. Components are stored in C:\WINNT\Assembly.

    silver account

    September 16, 2012 at 9:00 pm


Leave a comment