You are on page 1of 29

Introduction .

NET
The .NET Framework (Software framework) is Microsoft's application development platform that enables developers to easily create Windows applications, web applications, and web services using a myriad of different programming languages, and without having to worry about low-level details like memory management and processor-specific instructions. What is needed for application development? .net framework SDK 3.5 IDE ( Optional );third party or VS 2008, SQL Server 2005 or 2008

Components of .net framework: CLR ( common language runtime) CTS ( Common type system) CLS ( common language specification) MSIL or CIL

CLR
If define execution environment CLR runs on bytecodes called CIL( MSIL) It executes and manages all the running codes like virtual machine. (Qui. To JVM) Work as layer between OS and application written on it. Main function is to convert managed code into native code and then execute program. JIT compiler ( Jitter) converts managed code into native code. During runtime CLR manages exception , security etc memory, garbage collection, thread,

CTS
Common Type System (CTS) describes a set of types that can be used in different .Net languages in common That is, the Common Type System (CTS) ensure that objects written in different .Net languages can interact with each other. . For Communicating between programs written in any .NET complaint language, the types have to be compatible on the basic level. Common Type System (CTS) provides base set of Data Types which is responsible for cross language integration. The Common Language Runtime (CLR) can load and execute the source code written in any .Net language, only if the type is described in the Common Type System (CTS)

CLS
Common Language Specification (CLS) is a set of basic language features that .Net Languages needed to develop Applications and Services , which are compatible with the .Net Framework. When there is a situation to communicate Objects written in different .Net Complaint languages , those objects must expose the features that are common to all the languages . (CLS) ensures complete interoperability among applications, regardless of the language used to create the application. Common Language Specification (CLS) defines a subset of Common Type System (CTS) Most of the members defined by types in the .NET Framework Class Library (FCL) are Common Language Specification (CLS) compliant Types. Moreover Common Language Specification (CLS) standardized by ECMA .( European computer manufacturer association)

MSIL ( CIL)
During the compile time , the compiler convert the source code into Microsoft Intermediate Language (MSIL) .Microsoft Intermediate Language (MSIL) is a CPU-independent set of instructions that can be efficiently converted to the native code. During the runtime the Common Language Runtime (CLR)'s Just In Time (JIT) compiler converts the Microsoft Intermediate Language (MSIL) code into native code to the Operating System. When a compiler produces Microsoft Intermediate Language (MSIL), it also produces Metadata. The Microsoft Intermediate Language (MSIL) and Metadata are contained in a portable executable (PE) file . Microsoft Intermediate Language (MSIL) includes instructions for loading, storing, initializing, and calling methods on objects, as well as instructions for arithmetic and logical operations, control flow, direct memory access, exception handling, and other operations

FCL
The .Net Framework class library (FCL) provides the core functionality of .Net Framework architecture . The .Net Framework Class Library (FCL) includes a huge collection of reusable classes , interfaces, and value types that expedite and optimize the development process and provide access to system functionality. The .Net Framework class library (FCL) organized in a hierarchical tree structure and it is divided into Namespaces. Namespaces is a logical grouping of types for the purpose of identification. Framework class library (FCL) provides the consistent base types that are used across all .NET enabled languages. The Classes are accessed by namespaces, which reside within Assemblies. The System Namespace is the root for types in the .NET Framework. The .Net Framework class library (FCL) classes are managed classes that provide access to System Services . The .Net Framework class library (FCL) classes are object oriented and easy to use in program developments. Moreover, third-party components can integrate with the classes in the .NET Framework.

Assembly
Microsoft .Net Assembly is a logical unit of code, it contains code that the Common Language Runtime (CLR) executes. Assembly is really a collection of types and resource information that are built to work together and form a logical unit of functionality. During the compile time Metadata is created, with Microsoft Intermediate Language (MSIL), and stored in a file called a Manifest . Both Metadata and Microsoft Intermediate Language (MSIL) together wrapped in a Portable Executable (PE) file. Manifest contains information about itself. This information is called Assembly Manifest, it contains information about the members, types, references and all the other data that the runtime needs for execution. Every Assembly you create contains one or more program files and a Manifest. There are two types program files : Process Assemblies (EXE) and Library Assemblies (DLL). Each Assembly can have only one entry point (that is, DllMain, WinMain, or Main). We can create two types of Assembly, private Assembly and shared Assembly . A private Assembly is used only by a single application, and

usually it is stored in that application's install directory. A shared Assembly is one that can be referenced by more than one application. If multiple applications need to access an Assembly, we should add the Assembly to the Global Assembly Cache (GAC).

Metadata

Metadata in .Net is binary information which describes the characteristics of a resource . This information include Description of the Assembly , Data Types and members with their declarations and implementations, references to other types and members , Security permissions etc. A module's metadata contains everything that needed to interact with another module. During the compile time Metadata created with Microsoft Intermediate Language (MSIL) and stored in a file called a Manifest . Both Metadata and Microsoft Intermediate Language (MSIL) together wrapped in a Portable Executable (PE) file. During the runtime of a program Just In Time (JIT) compiler of the Common Language Runtime (CLR) uses the Metadata and converts Microsoft Intermediate Language (MSIL) into native code. When code is executed, the runtime loads metadata into memory and references it to discover information about your code's classes, members, inheritance, and so on. Moreover Metadata eliminating the need for Interface Definition Language (IDL) files, header files, or any external method of component reference.

Manifest

An Assembly Manifest is a file that containing Metadata about .NET Assemblies. Assembly Manifest contains a collection of data that describes how the elements in the assembly relate to each other. It describes the relationship and dependencies of the components in the Assembly, versioning information, scope information and the security permissions required by the Assembly. The Assembly Manifest can be stored in Portable Executable (PE) file with Microsoft Intermediate Language (MSIL) code. You can add or change some information in the Assembly Manifest by using assembly attributes in your code. The Assembly Manifest can be stored in either a PE file (an .exe or .dll) with Microsoft Intermediate Language (MSIL) code or in a standalone PE file that contains only assembly manifest information. Using ILDasm, you can view the manifest information for any managed DLL.

Namespace
Namespaces are the way to organize .NET Framework Class Library into a logical grouping according to their functionality, usability as well as category they should

belong to, or we can say Namespaces are logical grouping of types for the purpose of identification. The .NET Framework Class Library (FCL ) is a large collection of thousands of Classes. These Classes are organized in a hierarchical tree. The System Namespaces is the root for types in the .NET Framework. We can uniquely identify any Class in the .NET Framework Class Library (FCL ) by using the full Namespaces of the class .In .Net languages every program is created with a default Namespaces . Programmers can also create their own Namespaces in .Net languages.

Assembly
In general, a static assembly can consist of four elements:

types.

The assembly manifest, which contains assembly metadata. Type metadata. Microsoft intermediate language (MSIL) code that implements the A set of resources.

Only the assembly manifest is required, but either types or resources are needed to give the assembly any meaningful functionality. There are several ways to group these elements in an assembly. You can group all elements in a single physical file, which is shown in the following illustration. Single-file assembly

Alternatively, the elements of an assembly can be contained in several files. These files can be modules of compiled code (.netmodule), resources (such as .bmp or .jpg files), or other files required by the application. Create a multifile assembly when you want to combine modules written in different languages and to optimize downloading an application by putting seldom used types in a module that is downloaded only when needed. In the following illustration, the developer of a hypothetical application has chosen to separate some utility code into a different module and to keep a large resource file (in this case a .bmp image) in its original file. The .NET Framework downloads a file only when it is referenced; keeping infrequently referenced code in a separate file from the application optimizes code download. Multifile assembly

Note:

The files that make up a multifile assembly are not physically linked by the file system. Rather, they are linked through the assembly manifest and the common language runtime manages them as a unit. In this illustration, all three files belong to an assembly, as described in the assembly manifest contained in MyAssembly.dll. To the file system, they are three separate files. Note that the file Util.netmodule was compiled as a module because it contains no assembly information. When the assembly was created, the assembly manifest was added to MyAssembly.dll, indicating its relationship with Util.netmodule and Graphic.bmp. As you currently design your source code, you make explicit decisions about how to partition the functionality of your application into one or more files. When designing .NET Framework code, you will make similar decisions about how to partition the functionality into one or more assemblies.

Assemblies can be private or shared. Private assemblies are available only to clients in the same directory structure as the assembly; shared assemblies are available to any local COM application. All assemblies and type libraries must be registered in the Windows registry so COM clients can use the managed types transparently. Private Assemblies You deploy an application into an application directory and subdirectories if it is to be private. The following illustration shows the Loanlib.dll installed in two separate application directories. To run a private assembly from the Visual Basic 6.0 development environment, the assembly must be in the application directory of the Visual Basic executable (Vb6.exe). Directory structure and registry entries for private deployment

Shared Assemblies You install the assemblies for an application into the global assembly cache if they are to be shared. All shared assemblies must be strong-named (signed by the publisher). Any COM application that references a type in the assembly encounters Mscoree.dll, which in turn locates the assembly. Use the Global Assembly Cache tool (Gacutil.exe) to add an assembly to the global assembly cache. For example > sn k mykey.snk > csc /t:library /keyfile:mykey.snk nng.cs (now share library is created)

Copy Code gacutil /i nng.dll (now added to shared library)

We can also add using graphical wizard: goto control panel -> administrative tools -> Microsoft framework 2.o configuration -> right click on assembly cache -> add

Creating single-file assembly


To create an assembly with an .exe extension At the command prompt, type the following command: <compiler command> <module name> In this command, compiler command is the compiler command for the language used in your code module, and module name is the name of the code module to compile into the assembly.

The following example creates an assembly named myCode.exe from a code module called myCode. C# csc myCode.cs Visual Basic vbc myCode.vb To create an assembly with an .exe extension and specify the output file name At the command prompt, type the following command: <compiler command> /out:<file name> <module name> In this command, compiler command is the compiler command for the language used in your code module, file name is the output file name, and module name is the name of the code module to compile into the assembly.

Copy Code

Copy Code

The following example creates an assembly named myAssembly.exe from a code module called myCode. C# csc /out:myAssembly.exe myCode.cs Visual Basic vbc /out:myAssembly.exe myCode.vb Copy Code Copy Code

Creating Library Assemblies A library assembly is similar to a class library. It contains types that will be referenced by other assemblies, but it has no entry point to begin execution. To create a library assembly At the command prompt, type the following command: <compiler command> /t:library <module name> In this command, compiler command is the compiler command for the language used in your code module, and module name is the name of the code module to compile into the assembly. You can also use other compiler options, such as the /out: option.

The following example creates a library assembly named myCodeAssembly.dll from a code module called myCode. C# Copy Code

csc /out:myCodeLibrary.dll /t:library myCode.cs

To create a multifile assembly


1. Compile all files that contain namespaces referenced by other modules in the assembly into code modules. The default extension for code modules is .netmodule. For example, if a file called Stringer creates a namespace called myStringer that is referenced in the Client file code, Stringer should be compiled into a code module first. 2. Compile all other modules, using the necessary compiler options to indicate the other modules that are referenced in the code. 3. Use the Assembly Linker (Al.exe) to create the output file that contains the assembly manifest. This file contains reference information for all modules or resources that are part of the assembly. Note: The Visual Studio 2005 IDE for C# and Visual Basic can only be used to create single-file assemblies. If you want to create multifile assemblies, you must use the command-line compilers or Visual Studio 2005 with Visual C++. The following example illustrates step 1 of the procedure above, by compiling files with namespaces referenced by other files. This example starts with some simple code for the Stringer file. Stringer has a namespace called myStringer with a class called Stringer. The Stringer class contains a method called StringerMethod that writes a single line to the console. Visual Basic Copy Code

' Assembly building example in the .NET Framework. Imports System Namespace myStringer Public Class Stringer Public Sub StringerMethod() Console.WriteLine("This is a line from StringerMethod.") End Sub End Class End Namespace C# Copy Code

// Assembly building example in the .NET Framework. using System; namespace myStringer { public class Stringer { public void StringerMethod() { System.Console.WriteLine("This is a line from StringerMethod.");

} }

Use the following command to compile this code: Visual Basic vbc /t:module Stringer.vb C# csc /t:module Stringer.cs Specifying the module parameter with the /t: compiler option indicates that the file should be compiled as a module rather than as an assembly. The compiler produces a module called Stringer.netmodule, which can be added to an assembly. In step two of the procedure above, you must compile modules with references to other modules. This step uses the /addmodule compiler option. In the following example, a code module called Client has an entry point Main method that references a method in the Stringer.dll module created in Step 1. The following example shows the code for Client. Visual Basic Copy Code Copy Code Copy Code

Imports System Imports myStringer 'The namespace created in Stringer.netmodule. Class MainClientApp ' Shared method Main is the entry point method. Public Shared Sub Main() Dim myStringInstance As New Stringer() Console.WriteLine("Client code executes") 'myStringComp.Stringer() myStringInstance.StringerMethod() End Sub End Class C# Copy Code

using System; using myStringer; //The namespace created in Stringer.netmodule. class MainClientApp { // Static method Main is the entry point method. public static void Main() { Stringer myStringInstance = new Stringer(); Console.WriteLine("Client code executes"); //myStringComp.Stringer(); myStringInstance.StringerMethod();

Use the following command to compile this code: Visual Basic Copy Code

vbc /addmodule:Stringer.netmodule /t:module Client.vb C# Copy Code

csc /addmodule:Stringer.netmodule /t:module Client.cs Specify the /t:module option because this module will be added to an assembly in a future step. Specify the /addmodule option because the code in Client references a namespace created by the code in Stringer.netmodule. The compiler produces a module called Client.netmodule that contains a reference to another module, Stringer.netmodule. Note: The C# and Visual Basic compilers support directly creating multifile assemblies using the following two different syntaxes.

Two compilations create a two-file assembly: Copy Code

Visual Basic

vbc /t:module Stringer.vb vbc Client.vb /addmodule:Stringer.netmodule C# Copy Code

csc /t:module Stringer.cs csc Client.cs /addmodule:Stringer.netmodule

One compilation creates a two-file assembly: Copy Code

Visual Basic

vbc /out:Stringer.netmodule Stringer.vb /out:Client.exe Client.vb C# Copy Code

csc /out:Client.exe Client.cs /out:Stringer.netmodule Stringer.cs You can use the Assembly Linker (Al.exe) to create an assembly from a collection of compiled code modules. To create a multifile assembly using the Assembly Linker At the command prompt, type the following command: al <module name> <module name> /main:<method name> /out:<file name> /target:<assembly file type>

In this command, the module name arguments specify the name of each module to include in the assembly. The /main: option specifies the method name that is the assembly's entry point. The /out: option specifies the name of the output file, which contains assembly metadata. The /target: option specifies that the assembly is a console application executable (.exe) file, a Windows executable (.win) file, or a library (.lib) file. In the following example, Al.exe creates an assembly that is a console application executable called myAssembly.exe. The application consists of two modules called Client.netmodule and Stringer.netmodule, and the executable file called myAssembly.exe, which contains only assembly metadata . The entry point of the assembly is the Main method in the class MainClientApp, which is located in Client.dll. Copy Code al Client.netmodule Stringer.netmodule /main:MainClientApp.Main /out:myAssembly.exe /target:exe

Introduction
Strong Name (further referred to as "SN") is a technology introduced with the .NET platform and it brings many possibilities into .NET applications. But many .NET developers still see Strong Names as security enablers (which is very wrong!) and not as a technology uniquely identifying assemblies. There is a lot of misunderstanding about SNs (as we could see in the article "Building Security Awareness in .NET Assemblies : Part 3 - Learn to break Strong Name .NET Assemblies ") and this article attempts to clear those up. Now let's see what SNs are, what we can use them for and how they work. Strong Name is a technology based on cryptographic principles, primary digital signatures; basic idea is presented in the figure below:

At the heart of digital signatures is asymmetric cryptography (RSA, EL Gamal), together with hashing functions (MD5, SHA). So what happens when we want to sign any data? I'll try to explain what happens in the figure above.

Details First we must get a public/private key pair (from our administrator, certification authority, bank, application etc.) that we will use for encryption/decryption. Then DATA (term DATA represents general data we want to sign) is taken and run through some hashing algorithm (like MD5 or SHA - however, MD5 is not recommended) and hash of DATA is produced. The hash is encrypted by private key of user A and attached to plaintext data. The DATA and attached signature are sent to user B who takes public key of user A and decrypts attached signature where hash of DATA is stored and encrypted. Finally user B runs DATA through the same hashing algorithm as user A and if both hashes are the same then user B can be pretty sure that the DATA has not been tampered with and also identity of user A is proven. But this is a naive scenario because it's hard to securely deliver public keys over insecure communication channels like Internet. That is why certificates were introduced but I will not cover it here because certificates aren't used in SNs and delivery of public key is a matter of publisher's policy (maybe I can cover distribution of public keys, certificates and certification authorities in another article). Now let's assume that public key was delivered to user B securely. This process is used in the creation of SN for .NET applications. You can translate term DATA as assemblies and apply the same steps to them when SNs are used. But what is the purpose and usage of this SN technology? Simple - there is the only one reason to uniquely identify each assembly. See section 24.3.3.4 of CLI ECMA specification where SNs are defined: This header entry points to the strong name hash for an image that can be used to deterministically identify a module from a referencing point (Section 6.2.1.3). SNs are not any security enhancement; they enable unique identification and side-by-side code execution. Now we know that SNs are not security enablers. Where to use them then? We can see two scenarios where SNs can be used:

Versioning Authentication

Versioning solves known problem called as "DLL hell". Signed assemblies are unique and SN solves problem with namespace collisions (developers can distribute their assemblies even with the same file names as shown of figure below). Assemblies signed with SNs are uniquely identified and are protected and stored in different spaces.

In addition to collision protection, SN should help developers to uniquely identify versions of their .NET assemblies. That is why when developers want to use GAC (Global Assembly Cache) assemblies must be signed to separate each publisher's namespace and to separate each version. The second important feature of Strong Names is authentication; a process where we want to ensure ourselves about the code's origin. This can be used in many situations, such as assigning higher permissions for chosen publishers (as will be shown later) or ensuring that code is provided by a specific supplier.

It has been shown that signatures and public keys can be easily removed from assemblies. Yes, that is right but it is correct behavior even when we use digital signatures in emails or anywhere else! Let's see how it works! We can use some analogy from our real life. Let's assume you are a boss of your company and you are sending an email to your employees where new prices of your products are proposed. This email is a plaintext and you use some non-trusted outsourcing mailing services. Your communication can be easily monitored and your email can be easily accessed by unauthorized persons who can change its content, for instance your prices proposed in email. How to solve that? The answer is cryptography, again digital signatures that you can use to authenticate to your employees and to verify content of your email. Simply you have to add a digital signature to your email and then require your employees will trust just verified emails that have your valid digital signature. Let's assume that all PKI infrastructure is set up and working correctly. Now, when an intruder removes the digital signature from your email, his employees will not trust them because they can't be verified and application will alert users about this insecure state. The same situation is when SNs are used. You can remove SNs from assemblies , but this makes no sense because just as in the case of emails, assemblies without SNs can't be trusted when environment is set up to require those digital signatures or SNs. This is also related to another very important point in .NET Code Groups & Policy Levels. As in the case of emails, when PKI is setup in a company and security policy is defined that employees can't trust and verify emails which are not signed or where the encrypted hash value is different from hashed plaintext content. The same can be done with .NET Framework using the .NET Configuration tool on each machine or by group policy for large networks.

This tool provides configuration options for .NET Framework including Runtime Security where policy levels and code groups can be set. Policy levels work on intersection principle as shown in the figure below

Code groups (inside of those policy levels) provide permission sets for applications that belong to them according to their evidence (origin, publisher, strong name etc.). The assembly will get those permissions based on the intersection of code groups from each policy level applicable to it. This is a very important improvement in security architecture and improves the traditional Windows security model that is process centric (see figure below).

.NET introduces Code Access Security (CAS) which is used to identify the origin of code and assign to it specific restrictions and then make security policy more granular and protecting against attacks such as luring attacks.

However my intention isn't to describe CAS or Windows security internals (I can write about it in other articles) but show SN principles. Let's move back to it!

Now we can move to the second use for SN - administrators and developers can use SNs together with code groups to provide assemblies with higher permissions (not the default ones that assembly will acquire according to default .NET Framework settings). Let's see an example! I must point out that this is just a simplified example how SN can identify publisher, this is NOT a way to obey CLR security or how to use it in enterprise environment. That is why please try to understand the example as a general principle available with SNs but NOT as a design pattern! Usage of SNs as authentication is a more complex problem and there are many non-trivial issues when SNs are involved. But it's out of scope of this article, so now back to the sample! Take my sample Windows Forms project and rebuild it and put .exe file on any share on your LAN. Then try to start this application from this share and click on button what happens? A security exception is raised because application doesn't have enough privileges. Now go to .NET Configuration tool and add a new code group

add new code group called Test

and in the second dialog choose Strong name, click on Import button and locate the .exe file in Debug folder of project folder and finally assign full trust for this application

Now you have created a new code group containing just your sample application. Now go to your network share and try to start sample application again. And it works! Why? Because it belongs to our new code group Test with full trust permissions. Now remove SN from sample application (as described in his article or just simply remove attribute [assembly: AssemblyKeyFile("KeyFile.snk")] from AssemblyInfo.cs file), recompile and publish it on share. Try to run it and what happens? It's not working! Why? Because assembly can't show this strong name evidence and it belongs to the default code group (with limited privileges) now. It's not surprising, nothing special, no magic just correct usage of Strong Name technology. SNs are easy and powerful but we have to understand how and where to use them. That is why I want to outline some "issues" that are connected with SNs that will present all capabilities that we can expect from SNs. So what are the weaknesses of SNs? First we have to realize that SNs are a lightweight version of Authenticode and they provide fast and easily used technology to get enterprise features like versioning and authentication. But this ease of use must be paid by something and here goes a list of disadvantages:

It can be very hard to securely associate publisher with his public key when certification authorities are not involved. Publisher must ship his public key by himself and he must ensure that public key is not tampered. Without certification authorities it's impossible to do it securely when our products are distributed over insecure channels and there are no other ways to verify the publisher's public key. There is no way how to revoke public key when the private key has been compromised. As this is easily done in case of certificates (just publish revoked certificates on CRL, Certificate Revocation List) in case of SNs, revocation is a nightmare. Just imagine that you as a junior security engineer has lost USB key with your private key used to sign your assemblies. Then you'll have to call and email your clients with newly signed assemblies, give them your new public key and setup all environments again). There is no automatic way like CRL, everything must be done "by hand".

Authenticode can be considered as more powerful from an enterprise and architectural perspective. So why not use Authenticode instead of SNs? Here are the reasons:

SNs don't require any third party (such as Verisign) to create signatures and manage public keys. Any developer can easily create and manage his keys (see chapter "Generate key pair with sn.exe tool" in my free book ".NET in Samples") without payment to any third party. SNs can avoid network connections and PKI involvement so applications can run and be verified even when network connections are not available. Authenticode certificates are not a part of assembly names and that is why they can't separate publisher's namespaces like SNs do. Do you remember the statement from ECMA in the beginning? That SNs should "deterministically identify" modules and this is the most important reason. So not a security enabler but unique identification is the primary reason for SNs! And Authenticode is not designed for this purpose!

Conclusion

I hope this helps you understand the strong name technology in the .NET Framework, and helped you see that it is very powerful, but with defined limits. It is a technology that should be used appropriately. With SNs we can uniquely identify an assembly and run side-byside our assemblies. Security scenarios are not recommended to be used with Strong Names (even when it's supported by .NET Framework), just in case you are advanced in security and working with certificates and key management. There are many design patterns on how to use Strong Names and all this depends on application architecture, client requirements and infrastructure settings (Active Directory, PKI etc.). There could be much more written about it (like usage of SNs in large companies, problems with key distribution, etc.), but this was not intended for this article, it was just a reaction to some misinterpretation of this technology and the article is intended to put it right.

You might also like