Examining the method body using Reflection in .NET C#

In this short post we saw how to extract the members of a class: constructors, properties, methods etc. Even more exciting is the fact that you can peek into the body of a method. Well, not the plain text C# or VB code, but the Intermediate Language – MSIL version of it.

The MethodBody object represents, as the name suggests, the body of a method including the local variables and the MSIL instructions. MethodBody is available on classes that derive from the MethodBase class, which are methods and constructors – MethodInfo and ConstructorInfo.

Consider the following Customer class:

public class Customer
{
	private string _name;

	public Customer(string name)
	{
		if (string.IsNullOrEmpty(name)) throw new ArgumentNullException("Customer name!");
		_name = name;
	}

	public string Name
	{
		get
		{
			return _name;
		}
	}
	public string Address { get; set; }
	public int SomeValue { get; set; }

	public int ImportantCalculation()
	{
		int variable = 2;
		string stringVar = string.Empty;
		if (variable == 2)
		{
			stringVar = "two";
		}
		else
		{
			stringVar = "hello";
		}

		ImportantVoidMethod();
		return 1000;
	}

	public void ImportantVoidMethod()
	{
		bool ok = false;
		SomeEnumeration enumeration = SomeEnumeration.ValueOne;
		switch (enumeration)
		{
			case SomeEnumeration.ValueOne:
				ok = true;
				break;
			case SomeEnumeration.ValueTwo:
				ok = false;
				break;
			default:
				ok = false;
				break;
		}
	}

	public enum SomeEnumeration
	{
		ValueOne = 1
		, ValueTwo = 2
	}

	public class SomeNestedClass
	{
		private string _someString;
	}
}

The following code shows you how you can extract the methods and inspect them:

Type customerType = typeof(Customer);

Console.WriteLine("Customer methods: ");
MethodInfo[] methods = customerType.GetMethods();

foreach (MethodInfo mi in methods)
{
	Console.WriteLine(mi.Name);
	MethodBody methodBody = mi.GetMethodBody();
	if (methodBody != null)
	{
		byte[] ilCode = methodBody.GetILAsByteArray();
		int maxStackSize = methodBody.MaxStackSize;
		IList<LocalVariableInfo> localVariables = methodBody.LocalVariables;
		Console.WriteLine("Max stack size: {0}", maxStackSize);

		Console.WriteLine("Local variables if any:");
		foreach (LocalVariableInfo lvi in localVariables)
		{
			Console.WriteLine("Type: {0}, index: {1}.", lvi.LocalType, lvi.LocalIndex);
		}

		Console.WriteLine("IL code:");
		StringBuilder stringifiedIlCode = new StringBuilder();
		foreach (byte b in ilCode)
		{
			stringifiedIlCode.Append(string.Format("{0:x2} ", b));
		}

		Console.WriteLine(stringifiedIlCode);
	}
}

The MethodInfo array will include the properties that are turned into methods, e.g. Name will become get_Name, and also the methods inherited from Object such as ToString(). Here’s the output for ImportantVoidMethod and ImportantCalculation:

MethodBody example code output

The LocalVariableInfo doesn’t contain the name of the variable because the metadata about a type doesn’t keep the variable name, only its order.

View all posts on Reflection here.

Using a Windows service in your .NET project part 1: foundations

Introduction

As the title suggests we’ll discuss Windows services in this new series and how they can be used in your .NET project. We’ll take up the following topics:

  • What is a Windows service?
  • How can it be (un)installed using scripts?
  • What’s the use of a Windows Service?
  • How can it be taken advantage of in a .NET project?
  • Simplified layered architecture with OOP principles: we’ll see a lot of abstractions and dependency injection

We’ll also build a small demo application with the following components:

  • A Windows service
  • A Console-based consumer with a simplified layered architecture
  • A MongoDb database

If you’re not familiar with MongoDb, don’t worry. You can read about it on this blog starting here. Just make sure you read at least the first 2 posts so that you know how to install MongoDb as a Windows service on your PC. Otherwise we won’t see much MongoDb related code in the demo project.

A warning: it’s not possible to create Windows services in the Express edition of Visual Studio. I’ll be building the project in VS 2013 Professional.

Windows services

Windows services are executable assemblies that run in the background without the user’s ability to interact with them directly. They are often used for long running or periodically recurring activities such as polling, monitoring, listening to network connections and the like. Windows services have no user interface and have their own user session. It’s possible to start a Windows service without the user logging on to the computer.

An average Windows PC has a large number of pre-installed Windows services, like:

…and many more. You can view the services by opening the Services window:

Windows services window

We’ll go through the different categories like “Name” and “Status” when we create the Windows service project.

There are some special considerations about Windows services:

  • A Windows service project cannot be started directly in Visual Studio and step through its code with F11
  • Instead the service must be installed and started in order to see it in action
  • An installer must be attached to the Windows service so that it can registered with the Windows registry
  • Windows services cannot communicate directly with the logged-on user. E.g. it cannot write to a Console that the user can read. Instead it must write messages to another source: a log file, the Windows event log, a web service, email etc.
  • A Windows service runs under a user context different from that of the logged-on user. It’s possible to give a different role to the Windows service than the role of the user. Normally you’ll run the service with roles limited to the tasks of the service

Demo project description

In the demo project we’ll simulate a service that analyses web sites for us: makes a HTTP call, takes note of the response time and also registers the contents of the web site. This operation could take a long time especially of the user is allowed to enter a range of URIs that should be carried out in succession. Think of a recorded session in Selenium where each step is carried out sequentially, like…

  • Go to login page
  • Log in
  • Search for a product
  • Reserve a product
  • Pay
  • Log out

It is not too wise to make these URL calls directly from a web page and present the results at the end. The HTTP communication may take far too much time to get the final status and the end user won’t see any intermediate results, such as “initialising”, “starting step 1”, “step 2 complete” etc. Websites are simply not designed to carry out long-running processes and wait for the response.

Instead it’s better to just create a “job” in some data storage that a continuous process, like a Windows service, is monitoring. This service can then carry out the job and update the data storage with information. The web site receives a correlation ID for the job which it can use to query the data store periodically. The most basic solution for the web page is to have a timer which automatically refreshes the window and runs the code that retrieves the latest status of the job using the correlation ID. An alternative here is web sockets.

You could even hide the data store and the Windows service setup behind a web service so that the web site only communicates with this web service using the correlation ID.

To keep this series short and concise I’ll skip the web page. I’m not exactly a client-side wizard and it would only create unnecessary noise to build a web side with all the elements to enter the URLs and show the job updates. Instead, we’ll replace it with a Console based consumer.

At the end we’ll have a console app where you can enter a series of URLs which are then entered in the MongoDb data store as a job. The Console will receive a job correlation ID. The Windows Service will monitor this data store and act upon every new job. It will call the URLs in succession and take note of the response time and string content of each URL. It will also update the status message of the job. The console will in turn monitor the job status and print the messages so that the user can track the status. We’ll also put in place a simple file-based logging system to see what the Windows service is actually doing.

Start: infrastructure

Open Visual Studio 2012/2013 Pro and create a blank solution called WindowsServiceDemo. Make sure to select .NET4.5 as the framework for all layers we create within this solution.

We’ll start from the very end of the project and create an abstraction for the planned HTTP calls. We’ve discussed a lot on this blog why it’s important to factor out dependencies such as file system operations, emailing, service calls etc. If you’re not sure why this is a good idea then go through the series on SOLID starting here, where especially Dependency Injection is most relevant.

We’ve also gone through a range of examples of cross cutting concerns in this series where we factored out the common concerns into an Infrastructure project. We’ll do it here as well and describe the HTTP communication service in an interface first.

Insert a new C# class library called Demo.Infrastructure into the blank solution. Add a folder called HttpCommunication to it. Making a HTTP call can require a large amount of inputs: the URI, the HTTP verb, a HTTP body, the headers etc. Instead of creating a long range of overloaded methods we’ll gather them in an object which will be used as the single input parameter. Let’s keep this simple and insert the following interface into the folder:

public interface IHttpService
{
    Task<MakeHttpCallResponse> MakeHttpCallAsync(MakeHttpCallRequest request);
}

The HTTP calls will be carried out asynchronously. If you’re not familiar with asynchronous method calls in .NET4.5 then start here. MakeHttpCallResponse and MakeHttpCallRequest have the following form:

public class MakeHttpCallResponse
{
        public int HttpResponseCode { get; set; }
        public string HttpResponse { get; set; }
        public bool Success { get; set; }
        public string ExceptionMessage { get; set; }
}
  • HttpResponseCode: the HTTP response code from the server, such as 200, 302, 400 etc.
  • HttpResponse: the string contents of the URL
  • Success: whether the HTTP call was successful
  • ExceptionMessage: any exception message in case Success was false
public class MakeHttpCallRequest
{
	public Uri Uri { get; set; }
	public HttpMethodType HttpMethod { get; set; }
	public string PostPutPayload { get; set; }
}
  • Uri: the URI to be called
  • HttpMethodType: the HTTP verb
  • PostPutPayload: the string HTTP body for POST and PUT operations

HttpMethodType is an enumeration which you can also insert into HttpCommunication:

public enum HttpMethodType
{
	Get
	, Post
	, Put
	, Delete
	, Head
	, Options
	, Trace
}

That should be straightforward.

Both MakeHttpCallRequest and MakeHttpCallResponse are admittedly oversimplified in their current forms but they suffice for the demo.

For the implementation we’ll use the HttpClient class in the System.Net library. Add the following .NET libraries to the Infrastructure layer:

  • System.Net version 4.0.0.0
  • System.Net.Http version 4.0.0.0

Insert a class called HttpClientService to the HttpCommunication folder, which will implement IHttpService as follows:

public class HttpClientService : IHttpService
{
	public async Task<MakeHttpCallResponse> MakeHttpCallAsync(MakeHttpCallRequest request)
	{
		MakeHttpCallResponse response = new MakeHttpCallResponse();
		using (HttpClient httpClient = new HttpClient())
		{
			httpClient.DefaultRequestHeaders.ExpectContinue = false;
			HttpRequestMessage requestMessage = new HttpRequestMessage(Translate(request.HttpMethod), request.Uri);
			if (!string.IsNullOrEmpty(request.PostPutPayload))
			{
				requestMessage.Content = new StringContent(request.PostPutPayload);
			}
			try
			{
				HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage, HttpCompletionOption.ResponseContentRead, CancellationToken.None);
				HttpStatusCode statusCode = responseMessage.StatusCode;
				response.HttpResponseCode = (int)statusCode;
				response.HttpResponse = await responseMessage.Content.ReadAsStringAsync();
				response.Success = true;
			}
			catch (Exception ex)
			{
				Exception inner = ex.InnerException;
				if (inner != null)
				{
					response.ExceptionMessage = inner.Message;
				}
				else
				{
					response.ExceptionMessage = ex.Message;
				}
			}
		}
		return response;
	}

	public HttpMethod Translate(HttpMethodType httpMethodType)
	{
		switch (httpMethodType)
		{
			case HttpMethodType.Delete:
				return HttpMethod.Delete;
			case HttpMethodType.Get:
				return HttpMethod.Get;
			case HttpMethodType.Head:
				return HttpMethod.Head;
			case HttpMethodType.Options:
				return HttpMethod.Options;
			case HttpMethodType.Post:
				return HttpMethod.Post;
			case HttpMethodType.Put:
				return HttpMethod.Put;
			case HttpMethodType.Trace:
				return HttpMethod.Trace;
		}
		return HttpMethod.Get;
	}
}

So we simply call the URI using the HttpClient and HttpRequestMessage objects. We get the HttpResponseMessage by awaiting the asynchronous SendAsync method of HttpClient. We save the Http status code as an integer and the string content of the URI in the MakeHttpCallResponse object. We also store any exception message in this response object to indicate that the HTTP call failed.

In the next part of the series we’ll build the domain and repository layer.

View the list of posts on Architecture and Patterns here.

Examining a .NET assembly through Reflection

We’ve gone through a couple of points about Reflection in .NET on this blog:

  • Inspecting assemblies
  • Inspecting types
  • Examining the members of a class

To recap we’ll see how to inspect the members of a .NET dll library built into the framework. The .NET 4 or 4.5 libraries are usually stored in the following location:

C:\Windows\Microsoft.NET\Framework64\v4.0.30319

Have a look into that folder and you’ll find the familiar libraries such as mscorlib, System.IO, System.Net etc. The following code will load the System.Net.Http assembly and print some basic information about those members which…

  • …are public
  • …are instance level, i.e. non-static
  • …are declared directly on the specific type

This last point means that we’ll ignore the inherited members of a Type. Without this flag we’d get all inherited members, such as ToString and GetType from Object:

string pathToAssembly = @"C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.Net.Http.dll";
BindingFlags bindingFlags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance;
Assembly assembly = Assembly.LoadFrom(pathToAssembly);

Console.WriteLine("Assembly full name: {0}", assembly.FullName);
Type[] typesInAssembly = assembly.GetTypes();

foreach (Type type in typesInAssembly)
{
	Console.WriteLine("Type name: {0}", type.Name);
	MemberInfo[] members = type.GetMembers(bindingFlags);
	foreach (MemberInfo mi in members)
	{
		Console.WriteLine("Member type: {0}, member name: {1}.", mi.MemberType, mi.Name);
	}
}

The assembly is quite large but here comes an excerpt:

Examining system.net.http through reflection

View all posts on Reflection here.

Externalising dependencies with Dependency Injection in .NET part 10: hashing and digital signatures

Introduction

In the previous post of this series we looked at how to hide the implementation of asymmetric encryption operations. In this post we’ll look at abstracting away hashing and digital signatures as they often go hand in hand. Refer back to this post on hashing and this on digital signatures if you are not familiar with those concepts.

We’ll continue directly from the previous post and extend the Infrastructure layer of our demo app we’ve been working on so far. So have it ready in Visual Studio and let’s get to it.

Preparation

Add two new subfolders called Hashing and DigitalSignature to the Cryptography folder of the Infrastructure.Common library. We’ll follow the same methodology as in the case of asymmetric encryption, i.e. we’ll communicate with proper objects as parameters and return types instead of writing a large amount of overloaded methods.

Recall that we had a common abstract class to all return types in the IAsymmetricCryptographyService interface: ResponseBase. We’ll reuse it here.

Hashing

In short hashing is a one way encryption. A plain text is hashed and there’s no key to decipher the hashed value. A common application of hashing is storing passwords. Any hashing algorithm should be able to hash plain string and that’s the only expectation we have. Add the below interface to the Hashing folder:

public interface IHashingService
{
	HashResult Hash(string message);
	string HashAlgorithmCode();
}

…where HashResult will hold the readable and byte array formats of the hashed value and has the following form:

public class HashResult : ResponseBase
{
	public string HexValueOfHash { get; set; }
	public byte[] HashedBytes { get; set; }
}

What is HashAlgorithmCode() doing there? The implementation if the interface will return a short description of itself, such as “SHA1” or “SHA512”. We’ll see later that it’s required by the digital signature implementation.

This can actually be seen as a violation of ‘L‘ in SOLID as we’re specifying the type of the implementation in some form. However, I think it serves a good purpose here and it will not be misused in some funny switch statement where we check the string returned by HashAlgorithmCode() in order to direct the logic. Let’s insert two implementations of IHashingService to the Hashing folder. Here comes SHA1:

public class Sha1ManagedHashingService : IHashingService
{
	public HashResult Hash(string message)
	{
		HashResult hashResult = new HashResult();
		try
		{
			SHA1Managed sha1 = new SHA1Managed();
			byte[] hashed = sha1.ComputeHash(Encoding.UTF8.GetBytes(message));
			string hex = Convert.ToBase64String(hashed);
			hashResult.HashedBytes = hashed;
			hashResult.HexValueOfHash = hex;
		}
		catch (Exception ex)
		{
			hashResult.ExceptionMessage = ex.Message;
		}
		return hashResult;
	}

	public string HashAlgorithmCode()
	{
		return "SHA1";
	}
}

…and here’s SHA512:

public class Sha512ManagedHashingService : IHashingService
{
	public HashResult Hash(string message)
	{
		HashResult hashResult = new HashResult();
		try
		{
			SHA512Managed sha512 = new SHA512Managed();
			byte[] hashed = sha512.ComputeHash(Encoding.UTF8.GetBytes(message));
			string hex = Convert.ToBase64String(hashed);
			hashResult.HashedBytes = hashed;
			hashResult.HexValueOfHash = hex;
		}
		catch (Exception ex)
		{
			hashResult.ExceptionMessage = ex.Message;
		}
		return hashResult;
	}

	public string HashAlgorithmCode()
	{
		return "SHA512";
	}
}

That’s enough for starters.

Digital signatures

Digital signatures in a nutshell are used to electronically sign the hash of a message. The receiver of the message can then check if the message has been tampered with in any way. Also, a digital signature can prove that it was the sender who sent a particular message. E.g. a receiver may only accept signed messages so that the sender cannot claim that it was someone else who sent the message.

It is not “compulsory” to encrypt a signed message. You can sign the hash of an unencrypted message. However, for extra safety the hash is also often encrypted. The process is the following:

  • The Sender encrypts a message with the Receiver’s public key
  • The Sender then hashes the cipher text
  • The Sender signs the hashed cipher with their private key
  • The Sender transmits the cipher text, the hash and the signature to the Receiver
  • The Receiver verifies the signature with the Sender’s public key
  • If the signature is correct then the Receiver deciphers the cipher text with their full asymmetric key

The following interface will reflect what we need from a digital signature service: sign a message and then verify the signature:

public interface IEncryptedDigitalSignatureService
{
	DigitalSignatureCreationResult Sign(DigitalSignatureCreationArguments arguments);
	DigitalSignatureVerificationResult VerifySignature(DigitalSignatureVerificationArguments arguments);
}

DigitalSignatureCreationResult will hold the signature and the cipher text:

public class DigitalSignatureCreationResult : ResponseBase
{
	public byte[] Signature { get; set; }
	public string CipherText { get; set; }
}

DigitalSignatureCreationArguments will carry the message to be encrypted, hashed and signed. It will also hold the the full key set for the signature and the public key of the receiver for encryption:

public class DigitalSignatureCreationArguments
{
	public string Message { get; set; }
	public XDocument FullKeyForSignature { get; set; }
	public XDocument PublicKeyForEncryption { get; set; }
}

Then we have DigitalSignatureVerificationResult which has properties to check if the signatures match and the decoded text:

public class DigitalSignatureVerificationResult : ResponseBase
{
	public bool SignaturesMatch { get; set; }
	public string DecodedText { get; set; }
}

…and finally we have DigitalSignatureVerificationArguments which holds the properties for the Sender’s public key for signature verification, the Receiver’s full key for decryption, the cipher text and the signature:

public class DigitalSignatureVerificationArguments
{
	public XDocument PublicKeyForSignatureVerification { get; set; }
	public XDocument FullKeyForDecryption { get; set; }
	public string CipherText { get; set; }
	public byte[] Signature { get; set; }
}

RsaPkcs1 digital signature provider

We’ll use the built-in RSA-based signature provider in .NET for the implementation. It will need to hash the cipher text so it’s good that we’ve prepared IHashingService in advance. Here comes the implementation where you’ll see how the HashAlgorithmCode() method is used in specifying the hash algorithm of the signature formatter and deformatter:

public class RsaPkcs1DigitalSignatureService : IEncryptedDigitalSignatureService
{
	private readonly IHashingService _hashingService;

	public RsaPkcs1DigitalSignatureService(IHashingService hashingService)
	{
		if (hashingService == null) throw new ArgumentNullException("Hashing service");
		_hashingService = hashingService;
	}

	public DigitalSignatureCreationResult Sign(DigitalSignatureCreationArguments arguments)
	{
		DigitalSignatureCreationResult res = new DigitalSignatureCreationResult();
		try
		{				
			RSACryptoServiceProvider rsaProviderReceiver = new RSACryptoServiceProvider();
			rsaProviderReceiver.FromXmlString(arguments.PublicKeyForEncryption.ToString());
			byte[] encryptionResult = rsaProviderReceiver.Encrypt(Encoding.UTF8.GetBytes(arguments.Message), false);
			HashResult hashed = _hashingService.Hash(Convert.ToBase64String(encryptionResult));

			RSACryptoServiceProvider rsaProviderSender = new RSACryptoServiceProvider();
			rsaProviderSender.FromXmlString(arguments.FullKeyForSignature.ToString());
			RSAPKCS1SignatureFormatter signatureFormatter = new RSAPKCS1SignatureFormatter(rsaProviderSender);
			signatureFormatter.SetHashAlgorithm(_hashingService.HashAlgorithmCode());
			byte[] signature = signatureFormatter.CreateSignature(hashed.HashedBytes);

			res.Signature = signature;
			res.CipherText = Convert.ToBase64String(encryptionResult);
			res.Success = true;
		}
		catch (Exception ex)
		{
			res.ExceptionMessage = ex.Message;
		}

		return res;
	}

	public DigitalSignatureVerificationResult VerifySignature(DigitalSignatureVerificationArguments arguments)
	{
		DigitalSignatureVerificationResult res = new DigitalSignatureVerificationResult();
		try
		{
			RSACryptoServiceProvider rsaProviderSender = new RSACryptoServiceProvider();
			rsaProviderSender.FromXmlString(arguments.PublicKeyForSignatureVerification.ToString());
			RSAPKCS1SignatureDeformatter deformatter = new RSAPKCS1SignatureDeformatter(rsaProviderSender);
			deformatter.SetHashAlgorithm(_hashingService.HashAlgorithmCode());				
			HashResult hashResult = _hashingService.Hash(arguments.CipherText);
			res.SignaturesMatch = deformatter.VerifySignature(hashResult.HashedBytes, arguments.Signature);
			if (res.SignaturesMatch)
	        	{
        			RSACryptoServiceProvider rsaProviderReceiver = new RSACryptoServiceProvider();
  	        		rsaProviderReceiver.FromXmlString(arguments.FullKeyForDecryption.ToString());
		        	byte[] decryptedBytes = rsaProviderReceiver.Decrypt(Convert.FromBase64String(arguments.CipherText), false);
				res.DecodedText = Encoding.UTF8.GetString(decryptedBytes);
			}

			res.Success = true;
		}
		catch (Exception ex)
		{
			res.ExceptionMessage = ex.Message;
		}

		return res;
	}
}

The whole chain can be tested as follows:

private static void TestDigitalSignatureService()
{
	IAsymmetricCryptographyService asymmetricService = new RsaAsymmetricCryptographyService();
	AsymmetricKeyPairGenerationResult keyPairGenerationResultReceiver = asymmetricService.GenerateAsymmetricKeys(1024);
	AsymmetricKeyPairGenerationResult keyPairGenerationResultSender = asymmetricService.GenerateAsymmetricKeys(1024);

	IEncryptedDigitalSignatureService digitalSignatureService = new RsaPkcs1DigitalSignatureService(new Sha1ManagedHashingService());

	DigitalSignatureCreationArguments signatureCreationArgumentsFromSender = new DigitalSignatureCreationArguments()
	{
		Message = "Text to be encrypted and signed"
		, FullKeyForSignature = keyPairGenerationResultSender.FullKeyPairXml
		, PublicKeyForEncryption = keyPairGenerationResultReceiver.PublicKeyOnlyXml
	};
	DigitalSignatureCreationResult signatureCreationResult = digitalSignatureService.Sign(signatureCreationArgumentsFromSender);
	if (signatureCreationResult.Success)
	{
		DigitalSignatureVerificationArguments verificationArgumentsFromReceiver = new DigitalSignatureVerificationArguments();
		verificationArgumentsFromReceiver.CipherText = signatureCreationResult.CipherText;
		verificationArgumentsFromReceiver.Signature = signatureCreationResult.Signature;
		verificationArgumentsFromReceiver.PublicKeyForSignatureVerification = keyPairGenerationResultSender.PublicKeyOnlyXml;
		verificationArgumentsFromReceiver.FullKeyForDecryption = keyPairGenerationResultReceiver.FullKeyPairXml;
		DigitalSignatureVerificationResult verificationResult = digitalSignatureService.VerifySignature(verificationArgumentsFromReceiver);
		if (verificationResult.Success)
		{
			if (verificationResult.SignaturesMatch)
			{
				Console.WriteLine("Signatures match, decoded text: {0}", verificationResult.DecodedText);
			}
			else
			{
				Console.WriteLine("Signature mismatch!!");
			}
		}
		else
		{
			Console.WriteLine("Signature verification failed: {0}", verificationResult.ExceptionMessage);
		}
	}
	else
	{
		Console.WriteLine("Signature creation failed: {0}", signatureCreationResult.ExceptionMessage);
	}
}

Check how the keys of each party in the messaging conversation are used for encrypting, signing, verifying and decrypting the message.

So that’s it for digital signatures.

This was the last post in the series on object dependencies. We could take up a number of other cross cutting concerns for the infrastructure layer, such as:

  • Http calls
  • User-level security, such as a role provider, a claims provider etc.
  • Session provider
  • Random password generation

…and possibly a lot more. By now you have a better understanding how to externalise tightly coupled object dependencies in your classes to make them more flexible and testable.

View the list of posts on Architecture and Patterns here.

Examining class members with Reflection and BindingFlags in .NET C#

In this post we saw a basic example of how to read the publicly available members of a class. Here we’ll look at how to refine our search and read other types of members, such as private and static members.

Consider the following, admittedly artificial Customer class:

public class Customer
{
	private string _name;
	protected int _age;
	public bool isPreferred;
	private static int maxRetries = 3;
}

We’ll concentrate on the fields to narrow down our focus. Check out the above link to see how to read methods, constructors, properties etc. of a class.

The most basic way of finding the fields of a class is the following:

Type customerType = typeof(Customer);
FieldInfo[] fields = customerType.GetFields();
Console.WriteLine("Fields: ");
foreach (FieldInfo fi in fields)
{
	Console.WriteLine(fi.Name);
}

This will only find the isPreferred variable as it is public. What if we want to get to the private fields as well? Use the BindingFlags enumeration like this:

BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Instance;
FieldInfo[] nonPublicFields = customerType.GetFields(flags);
Console.WriteLine("Non-public fields: ");
foreach (FieldInfo fi in nonPublicFields)
{
	Console.WriteLine(fi.Name);
}

…which results in the following:

Non-public fields with reflection

Note how the BindingFlags values can be chained together to widen your search. The NonPublic value will find the private, protected and internal variables. This value in itself is not enough to extract the non-public fields, we need to add that we’re interested in class-level fields.

The opposite of non-public is Public:

flags = BindingFlags.Public | BindingFlags.Instance;
FieldInfo[] publicFields = customerType.GetFields(flags);
Console.WriteLine("Public fields: ");
foreach (FieldInfo fi in publicFields)
{
	Console.WriteLine(string.Concat(fi.FieldType, ", ", fi.Name));
}

…which finds ‘isPreferred’ only as expected. We haven’t yet found the static field but it’s straightforward:

flags = BindingFlags.NonPublic | BindingFlags.Static;
FieldInfo[] staticFields = customerType.GetFields(flags);
Console.WriteLine("Private static fields: ");
foreach (FieldInfo fi in staticFields)
{
	Console.WriteLine(string.Concat(fi.FieldType, ", ", fi.Name));
}

…which finds ‘maxRetries’ only as it is the only non-public static field.

View all posts on Reflection here.

Examining class members through Types and Reflection in .NET C#

Here we saw different ways to get hold of a Type. You can use the Type object to extract different ingredients of a class such as methods, properties, events etc. through various methods. The name of the object that these methods return ends with “Info”, like FieldInfo, MethodInfo etc.

These Info classes all derive from the MemberInfo abstract base class. The Type object also derives from MemberInfo.

Say you have the following Customer class:

public class Customer
{
	private string _name;

	public Customer(string name)
	{
		if (string.IsNullOrEmpty(name)) throw new ArgumentNullException("Customer name!");
		_name = name;
	}

	public string Name
	{
		get
		{
			return _name;
		}
	}
	public string Address { get; set; }
	public int SomeValue { get; set; }

	public int ImportantCalculation()
	{
		return 1000;
	}

	public void ImportantVoidMethod()
	{
	}

        public enum SomeEnumeration
	{
		ValueOne = 1
		, ValueTwo = 2
	}

	public class SomeNestedClass
	{
		private string _someString;
	} 
}

Let’s see how we can find these elements:

Type customerType = typeof(Customer);

FieldInfo[] fields = customerType.GetFields();
Console.WriteLine("Fields: ");
foreach (FieldInfo fi in fields)
{
	Console.WriteLine(fi.Name);
}

Console.WriteLine("Constructors: ");
ConstructorInfo[] constructors = customerType.GetConstructors();
foreach (ConstructorInfo ci in constructors)
{
	Console.WriteLine(ci.Name);
}

Console.WriteLine("Methods: ");
MethodInfo[] methods = customerType.GetMethods();
foreach (MethodInfo mi in methods)
{
	Console.WriteLine(mi.Name);
}

Console.WriteLine("Nested types: ");
Type[] nestedTypes = customerType.GetNestedTypes();
foreach (Type t in nestedTypes)
{
	Console.WriteLine(t.Name);
}

Console.WriteLine("Properties: ");
PropertyInfo[] properties = customerType.GetProperties();
foreach (PropertyInfo pi in properties)
{
	Console.WriteLine(pi.Name);
}

Console.WriteLine("Members: ");
MemberInfo[] members = customerType.GetMembers();
foreach (MemberInfo mi in members)
{
	Console.WriteLine("Type: {0}, name: {1}", mi.Name, mi.MemberType);
}

This will produce the following output:

Inspect class members basic

You’ll notice a couple of things:

  • We have a field called _name but it wasn’t picked up by the GetFields method. That’s because it’s a private variable. If you want to extract private fields and members then the BindingFlags enumeration will come in handy – we’ll look at that in a separate post. The default behaviour is that you’ll only see the public members of a class. This is true for both static and instance members.
  • The get-set properties were translated into methods like get_Name and set_SomeValue
  • The methods inherited from Object were also included in the MethodInfo array – all public methods of the base class will be picked up by GetMethods()
  • GetMembers returns every public member of a class in a MemberInfo array. As noted above each Info class derives from MemberInfo. MemberInfo will contain some common functionality for all derived Info classes, like the Name property, but for anything specific to any derived Info class you’ll need to inspect the derived class of course

Another base class which is important to know of is MethodBase which also derives from MemberInfo. It represents any member that can contain a body: constructors and methods which in turn are represented by ConstructorInfo and MethodInfo.

View all posts on Reflection here.

Externalising dependencies with Dependency Injection in .NET part 9: cryptography part 2

Introduction

In the previous post of this series we looked at how to hide the implementation of symmetric encryption operations. In this post we’ll look at abstracting away asymmetric cryptography. Refer back to this post in case you are not familiar with asymmetric encryption in .NET.

We’ll continue directly from the previous post and extend the Infrastructure layer of our demo app we’ve been working on so far. So have it ready in Visual Studio and let’s get to it.

Preparation

Add a new subfolder called Asymmetric to the Cryptography folder of the Infrastructure.Common library. We’ll follow the same methodology as in the case of emailing and symmetric encryption, i.e. we’ll communicate with proper objects as parameters and return types instead of writing a large amount of overloaded methods.

Recall that we had a common abstract class to all return types in the ISymmetricCryptographyService interface: ResponseBase. We’ll reuse it here. There’s one more class we’ll use again here and that is CipherTextDecryptionResult.

Asymmetric encryption

In summary asymmetric encryption means that you have a pair of keys: a public and a private key. This is in contrast to symmetric encryption where there is only one key. The public key can be distributed to those who wish to send you an encrypted message. The private key will be used to decrypt the incoming cipher text. The public and private keys are in fact also symmetric: you can encrypt a message with the public key and decrypt with the private one and vice versa. As asymmetric encryption is considerably slower – but much more secure – than symmetric encryption it’s usually not used to encrypt large blocks of plain text. Instead, the sender encrypts the text with a symmetric key and then encrypts the symmetric key with the receiver’s public asymmetric key. The receiver will then decrypt the symmetric key using their asymmetric private key and decrypt the message with the decrypted symmetric key. If you want to see that in action I have a sample project which takes up this process starting here.

Our expectations from any reasonable asymmetric encryption mechanism are the same as for symmetric algorithms:

  • Create a valid key – actually a pair of keys – of a given size in bits
  • Encrypt a text
  • Decrypt a cipher text

Add the following interface to the Asymmetric folder to reflect these expectations:

public interface IAsymmetricCryptographyService
{
	AsymmetricKeyPairGenerationResult GenerateAsymmetricKeys(int keySizeInBits);
	AsymmetricEncryptionResult Encrypt(AsymmetricEncryptionArguments arguments);
	CipherTextDecryptionResult Decrypt(AsymmetricDecryptionArguments arguments);
}

We already know CipherTextDecryptionResult, here’s a reminder:

public class CipherTextDecryptionResult : ResponseBase
{
	public string DecodedText { get; set; }
}

AsymmetricKeyPairGenerationResult will represent the keys in XML format. We’ll need to represent the keys in two forms. The full representation is where the private key is included and should be kept with you. Another representation is where only the public key part of the pair is shown which can be used to distribute to your partners. Insert a class called AsymmetricKeyPairGenerationResult to the Asymmetric folder:

public class AsymmetricKeyPairGenerationResult : ResponseBase
{
	private XDocument _fullKeyPairXml;
	private XDocument _publicKeyOnlyXml;

	public AsymmetricKeyPairGenerationResult(XDocument fullKeyPairXml, XDocument publicKeyOnlyXml)
	{
		if (fullKeyPairXml == null) throw new ArgumentNullException("Full key pair XML");
		if (publicKeyOnlyXml == null) throw new ArgumentNullException("Public key only XML");
		_fullKeyPairXml = fullKeyPairXml;
		_publicKeyOnlyXml = publicKeyOnlyXml;
	}

	public XDocument FullKeyPairXml
	{
		get
		{
			return _fullKeyPairXml;
		}
	}

	public XDocument PublicKeyOnlyXml
	{
		get
		{
			return _publicKeyOnlyXml;
		}
	}
}

The keys are of type XDocument to make sure that they are in fact valid XML.

AsymmetricEncryptionResult will have two properties: the cipher text as a base64 string and as a byte array:

public class AsymmetricEncryptionResult : ResponseBase
{
	public string CipherText { get; set; }
	public byte[] CipherBytes { get; set; }
}

To encrypt a message we’ll need a plain text and the public-key-only part of the asymmetric keys:

public class AsymmetricEncryptionArguments
{
	public XDocument PublicKeyForEncryption { get; set; }
	public string PlainText { get; set; }		
}

Finally in order to decrypt a cipher text we’ll need the complete set of keys and the cipher text itself:

public class AsymmetricDecryptionArguments
{
	public XDocument FullAsymmetricKey { get; set; }
	public string CipherText { get; set; }
}

The project should compile at this stage.

The implementation: RSA

We’ll go for one of the most widely used implementation of asymmetric encryption, RSA. .NET has good support for it so the implementation if straightforward. Insert a class called RsaAsymmetricCryptographyService into the Asymmetric folder:

public class RsaAsymmetricCryptographyService : IAsymmetricCryptographyService
{
	public AsymmetricKeyPairGenerationResult GenerateAsymmetricKeys(int keySizeInBits)
	{
		try
		{
			RSACryptoServiceProvider myRSA = new RSACryptoServiceProvider(keySizeInBits);
			XDocument publicKeyXml = XDocument.Parse(myRSA.ToXmlString(false));
			XDocument fullKeyXml = XDocument.Parse(myRSA.ToXmlString(true));
			return new AsymmetricKeyPairGenerationResult(fullKeyXml, publicKeyXml) { Success = true };
		}
		catch (Exception ex)
		{
			return new AsymmetricKeyPairGenerationResult(new XDocument(), new XDocument()) { ExceptionMessage = ex.Message };
		}
	}

	public AsymmetricEncryptionResult Encrypt(AsymmetricEncryptionArguments arguments)
	{
		AsymmetricEncryptionResult encryptionResult = new AsymmetricEncryptionResult();
		try
		{
			RSACryptoServiceProvider myRSA = new RSACryptoServiceProvider();
			string rsaKeyForEncryption = arguments.PublicKeyForEncryption.ToString();
			myRSA.FromXmlString(rsaKeyForEncryption);
			byte[] data = Encoding.UTF8.GetBytes(arguments.PlainText);
			byte[] cipherText = myRSA.Encrypt(data, false);
			encryptionResult.CipherBytes = cipherText;
			encryptionResult.CipherText = Convert.ToBase64String(cipherText);
			encryptionResult.Success = true;
		}
		catch (Exception ex)
		{
			encryptionResult.ExceptionMessage = ex.Message;
		}
		return encryptionResult;
	}

	public CipherTextDecryptionResult Decrypt(AsymmetricDecryptionArguments arguments)
	{
		CipherTextDecryptionResult decryptionResult = new CipherTextDecryptionResult();
		try
		{
			RSACryptoServiceProvider cipher = new RSACryptoServiceProvider();
			cipher.FromXmlString(arguments.FullAsymmetricKey.ToString());
			byte[] original = cipher.Decrypt(Convert.FromBase64String(arguments.CipherText), false);
			decryptionResult.DecodedText = Encoding.UTF8.GetString(original);
			decryptionResult.Success = true;
		}
		catch (Exception ex)
		{
			decryptionResult.ExceptionMessage = ex.Message;
		}
		return decryptionResult;
	}
}

If you’re already familiar with asymmetric cryptography in .NET this should be straightforward. Otherwise consult the above link for the technical details, I won’t repeat them here.

The methods in the interface can be chained together in an example as follows:

private static void TestAsymmetricEncryptionService()
{
	IAsymmetricCryptographyService asymmetricSevice = new RsaAsymmetricCryptographyService();
	AsymmetricKeyPairGenerationResult keyPairGenerationResult = asymmetricSevice.GenerateAsymmetricKeys(1024);
	if (keyPairGenerationResult.Success)
	{
		AsymmetricEncryptionArguments encryptionArgs = new AsymmetricEncryptionArguments()
		{
			PlainText = "Text to be encrypted"
			, PublicKeyForEncryption = keyPairGenerationResult.PublicKeyOnlyXml
		};
		AsymmetricEncryptionResult encryptionResult = asymmetricSevice.Encrypt(encryptionArgs);
		if (encryptionResult.Success)
		{
			Console.WriteLine("Ciphertext: {0}", encryptionResult.CipherText);
			AsymmetricDecryptionArguments decryptionArguments = new AsymmetricDecryptionArguments()
			{
				CipherText = encryptionResult.CipherText
				, FullAsymmetricKey = keyPairGenerationResult.FullKeyPairXml
			};
			CipherTextDecryptionResult decryptionResult = asymmetricSevice.Decrypt(decryptionArguments);
			if (decryptionResult.Success)
			{
				Console.WriteLine("Decrypted text: {0}", decryptionResult.DecodedText);
			}
			else
			{
				Console.WriteLine("Decryption failure: {0}", decryptionResult.ExceptionMessage);
			}
		}
		else
		{
			Console.WriteLine("Encryption failure: {0}", encryptionResult.ExceptionMessage);
		}
	}
	else
	{
		Console.WriteLine("Asymmetric key generation failure: {0}", keyPairGenerationResult.ExceptionMessage);
	}
}

If you run this code you’ll see that the keys are generated, the plain text is encrypted and then decrypted again.

In the next post, which will be last post of this series on dependencies, we’ll look at two other aspects in cryptography: hashing and digital signatures.

View the list of posts on Architecture and Patterns here.

Getting the type of an object in .NET C#

You’ll probably know that every object in C# ultimately derives from the Object base class. The Object class has a GetType() method which returns the Type of an object.

Say you have the following class hierarchy:

public class Vehicle
{
}

public class Car : Vehicle
{
}

public class Truck : Vehicle
{
}

Then declare the following instances all as Vehicle objects:

Vehicle vehicle = new Vehicle();
Vehicle car = new Car();
Vehicle truck = new Truck();

Let’s output the type names of these objects:

Examining type of derived objects

So ‘car’ and ‘truck’ are not of type Vehicle. An object can only have a single type even if it can be cast to a base type, i.e. a base class or an interface. You can still easily get to the Type from which a given object is derived:

Type truckBase = truckType.BaseType;
Console.WriteLine("Truck base: {0}", truckBase.Name);

…which of course returns ‘Vehicle’.

View all posts on Reflection here.

Externalising dependencies with Dependency Injection in .NET part 8: symmetric cryptography

Introduction

In the previous post of this series we looked at how to hide the implementation of emailing operations. In this post we’ll look at abstracting away cryptography. Cryptography is often needed to communicate between two systems in a safe way by e.g. exchanging public keys first.

If you don’t know how to use cryptography in a .NET project check out the posts on this page.

The first couple of posts of this series went through the process of making hard dependencies to loosely coupled ones. I won’t go through that again – you can refer back to the previous parts of this series to get an idea. You’ll find a link below to view all posts of the series. Another post on the Single Responsibility Principle includes an example of breaking out different dependencies that you can look at.

We’ll extend the Infrastructure layer of our demo app we’ve been working on so far. So have it ready in Visual Studio and let’s get to it.

Cryptography in .NET

We discussed Cryptography in .NET on this blog before:

If you’re interested in the technical details then please consult those pages. I won’t go into cryptography in .NET but rather concentrate on the dependency injection side of it. We’ll abstract away all four of the above topics. As it’s a lot of code I’ve decided to break up the post into three parts:

  • This post: symmetric encryption
  • Next post: asymmetric encryption
  • Last post: hashing and digital signatures

Preparation

Add a new folder called Cryptography to the Infrastructure.Common library. We’ll follow the same methodology as in the case of emailing and communicate with proper objects as parameters and return types instead of writing a large amount of overloaded methods.

All return types will have 2 properties in common: Success and ExceptionMessage. A lot of things can go wrong in cryptography: wrong key size, unsupported block size, incomplete public/private key etc. The boolean property Success will indicate if the process was carried out successfully. ExceptionMessage will store the exception message in case Success is false. Insert the following abstract class to the Cryptography folder:

public abstract class ResponseBase
{
	public bool Success { get; set; }
	public string ExceptionMessage { get; set; }
}

Symmetric encryption

Symmetric algorithm in a nutshell means that both the message sender and receiver have access to the same cryptographic key for both encryption and decryption.

Insert a subfolder called Symmetric within the Cryptography folder.

I think any reasonable symmetric encryption implementation should be able to perform the following 3 operations:

  • Create a valid key of a given size in bits
  • Encrypt a text
  • Decrypt a cipher text

Add the following interface to the Symmetric folder to reflect these expectations:

public interface ISymmetricCryptographyService
{
	SymmetricKeyGenerationResult GenerateSymmetricKey(int bitSize);
	SymmetricEncryptionResult Encrypt(SymmetricEncryptionArguments arguments);
	CipherTextDecryptionResult Decrypt(SymmetricDecryptionArguments arguments);
}

SymmetricKeyGenerationResult is simple: it will contain the symmetric key and inherit from ResponseBase:

public class SymmetricKeyGenerationResult : ResponseBase
{
	public string SymmetricKey { get; set; }
}

SymmetricEncryptionResult will contain the encoded version of the plain text, called cipher text, and an initialisation vector (IV) for increased security. Note that IV is not always used but it’s highly recommended as it adds randomness to the resulting cipher text making brute force decryption harder. Insert the following class to the Symmetric folder:

public class SymmetricEncryptionResult : ResponseBase
{
	public string CipherText { get; set; }
	public string InitialisationVector { get; set; }		
}

There’s a number of arguments that will be necessary to both encryption and decryption such as the key size and the common key. Add the following abstract class to the subfolder:

public class CommonSymmetricCryptoArguments
{
	public int KeySize { get; set; }
	public int BlockSize { get; set; }
	public PaddingMode PaddingMode { get; set; }
	public CipherMode CipherMode { get; set; }
	public string SymmetricPublicKey { get; set; }
}

Both SymmetricEncryptionArguments and SymmetricDecryptionArguments will inherit from the above base class. Insert the following classes to the Asymmetric subfolder:

public class SymmetricEncryptionArguments : CommonSymmetricCryptoArguments
{
	public string PlainText { get; set; }		
}
public class SymmetricDecryptionArguments : CommonSymmetricCryptoArguments
{
	public string CipherTextBase64Encoded { get; set; }
	public string InitialisationVectorBase64Encoded { get; set; }
}

So we’ll send in the plain text to be encrypted in SymmetricEncryptionArguments along with all other common arguments in CommonSymmetricCryptoArguments. Decryption will need the cipher text, the IV and the common arguments in CommonSymmetricCryptoArguments.

The last missing piece is CipherTextDecryptionResult. This object will be re-used for the asymmetric encryption section and will only include one extra property, namely the decoded text. Therefore add it to the Cryptography and not the Symmetric folder:

public class CipherTextDecryptionResult : ResponseBase
{
	public string DecodedText { get; set; }
}

The code should compile at this stage so we can move on with the implementation of the ISymmetricCryptographyService interface.

The implementation: Rijndael

For the implementation we’ll take the widely used Rijndael managed implementation of symmetric encryption available in .NET. Add a new class called RijndaelManagedSymmetricEncryptionService to the Symmetric folder:

public class RijndaelManagedSymmetricEncryptionService : ISymmetricCryptographyService
{
	public SymmetricEncryptionResult Encrypt(SymmetricEncryptionArguments arguments)
	{			
		SymmetricEncryptionResult res = new SymmetricEncryptionResult();
		try
		{
			RijndaelManaged rijndael = CreateCipher(arguments);
			res.InitialisationVector = Convert.ToBase64String(rijndael.IV);
			ICryptoTransform cryptoTransform = rijndael.CreateEncryptor();
			byte[] plain = Encoding.UTF8.GetBytes(arguments.PlainText);
			byte[] cipherText = cryptoTransform.TransformFinalBlock(plain, 0, plain.Length);
			res.CipherText = Convert.ToBase64String(cipherText);				
			res.Success = true;
		}
		catch (Exception ex)
		{
			res.ExceptionMessage = ex.Message;
		}
		return res;
	}

	public CipherTextDecryptionResult Decrypt(SymmetricDecryptionArguments arguments)
	{
		CipherTextDecryptionResult res = new CipherTextDecryptionResult();
		try
		{
			RijndaelManaged cipher = CreateCipher(arguments);
			cipher.IV = Convert.FromBase64String(arguments.InitialisationVectorBase64Encoded);
			ICryptoTransform cryptTransform = cipher.CreateDecryptor();
			byte[] cipherTextBytes = Convert.FromBase64String(arguments.CipherTextBase64Encoded);
			byte[] plainText = cryptTransform.TransformFinalBlock(cipherTextBytes, 0, cipherTextBytes.Length);
			res.DecodedText = Encoding.UTF8.GetString(plainText);
			res.Success = true;
		}
		catch (Exception ex)
		{
			res.ExceptionMessage = ex.Message;
		}
		return res;
	}

	public SymmetricKeyGenerationResult GenerateSymmetricKey(int bitSize)
	{
		SymmetricKeyGenerationResult res = new SymmetricKeyGenerationResult();
		try
		{
			byte[] key = new byte[bitSize / 8];
			RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
			rng.GetBytes(key);
			res.SymmetricKey = BitConverter.ToString(key).Replace("-", string.Empty);
			res.Success = true;
		}
		catch (Exception ex)
		{
			res.ExceptionMessage = ex.Message;
		}
		return res;
	}

	private RijndaelManaged CreateCipher(CommonSymmetricCryptoArguments arguments)
	{
		RijndaelManaged cipher = new RijndaelManaged();
		cipher.KeySize = arguments.KeySize;
		cipher.BlockSize =  arguments.BlockSize;
		cipher.Padding = arguments.PaddingMode;
		cipher.Mode = arguments.CipherMode;
		byte[] key = HexToByteArray(arguments.SymmetricPublicKey);
		cipher.Key = key;
		return cipher;
	}

	private byte[] HexToByteArray(string hexString)
	{
		if (0 != (hexString.Length % 2))
		{
			throw new ApplicationException("Hex string must be multiple of 2 in length");
		}
		int byteCount = hexString.Length / 2;
		byte[] byteValues = new byte[byteCount];
		for (int i = 0; i < byteCount; i++)
		{
			byteValues[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
		}

		return byteValues;
	}		
}

This code should be quite straightforward – again, consult the posts on symmetric encryption if this is new to you.

The methods in the interface can be chained together in an example as follows:

private static void TestSymmetricEncryptionService()
{
	ISymmetricCryptographyService symmetricService = new RijndaelManagedSymmetricEncryptionService();
	SymmetricKeyGenerationResult validKey = symmetricService.GenerateSymmetricKey(128);
	if (validKey.Success)
	{
		Console.WriteLine("Key used for symmetric encryption: {0}", validKey.SymmetricKey);

		SymmetricEncryptionArguments encryptionArgs = new SymmetricEncryptionArguments()
		{
			BlockSize = 128
			,CipherMode = System.Security.Cryptography.CipherMode.CBC
			,KeySize = 256
			,PaddingMode = System.Security.Cryptography.PaddingMode.ISO10126
			,PlainText = "Text to be encoded"
			,SymmetricPublicKey = validKey.SymmetricKey
		};

		SymmetricEncryptionResult encryptionResult = symmetricService.Encrypt(encryptionArgs);

		if (encryptionResult.Success)
		{
			Console.WriteLine("Cipher text from encryption: {0}", encryptionResult.CipherText);
			Console.WriteLine("Initialisation vector from encryption: {0}", encryptionResult.InitialisationVector);
			SymmetricDecryptionArguments decryptionArgs = new SymmetricDecryptionArguments()
			{
				BlockSize = encryptionArgs.BlockSize
				,CipherMode = encryptionArgs.CipherMode
				,CipherTextBase64Encoded = encryptionResult.CipherText
				,InitialisationVectorBase64Encoded = encryptionResult.InitialisationVector
				,KeySize = encryptionArgs.KeySize
				,PaddingMode = encryptionArgs.PaddingMode
				,SymmetricPublicKey = validKey.SymmetricKey
			};
			CipherTextDecryptionResult decryptionResult = symmetricService.Decrypt(decryptionArgs);
			if (decryptionResult.Success)
			{
				Console.WriteLine("Decrypted text: {0}", decryptionResult.DecodedText);
			}
			else
			{
				Console.WriteLine("Decryption failure: {0}", decryptionResult.ExceptionMessage);
			}
		}
		else
		{
			Console.WriteLine("Encryption failure: {0}", encryptionResult.ExceptionMessage);
		}
	}
	else
	{
		Console.WriteLine("Symmetric key generation failure: {0}", validKey.ExceptionMessage);
	}
}

In short we generate a valid symmetric key of 128 bits, populate the common encryption arguments, provided a plain text, encrypt it and then decrypt the cipher text using the common arguments and the IV.

In the next post we’ll look at asymmetric encryption.

View the list of posts on Architecture and Patterns here.

Examining a Type in .NET C#

You can get hold of Types in a variety of ways. You can extract the Types available in an Assembly as follows:

Assembly executingAssembly = Assembly.GetExecutingAssembly();
Type[] typesAttachedToAssembly = executingAssembly.GetTypes();

Console.WriteLine("Types attached to executing assembly: ");
foreach (Type type in typesAttachedToAssembly)
{
	Console.WriteLine(type.FullName);
}

In my case I have the following types in the executing assembly:

Getting types in an assembly

You can also extract the types within a single Module of an assembly:

Module[] modulesInCallingAssembly = executingAssembly.GetModules();
foreach (Module module in modulesInCallingAssembly)
{
	Console.WriteLine("Module {0}: ", module.Name);
	Type[] typesAttachedToModule = module.GetTypes();
	foreach (Type type in typesAttachedToModule)
	{
		Console.WriteLine(type.FullName);
	}
}

…which outputs the following:

Getting types in a module

You can construct Types without reflection using the GetType method and the typeof keyword. Say you have a simple Customer object:

public class Customer
{
	public string Name { get; set; }
}

…then you can get its type in the following ways:

Type customerType = customer.GetType();
Console.WriteLine(customerType.FullName);

Type customerTypeRevisited = typeof(Customer);
Console.WriteLine(customerTypeRevisited.FullName);

These will yield the same result:

Customer type

Once you have a Type you can inspect it through a myriad of properties. Here comes a short extract:

Console.WriteLine("Full name: {0}", customerType.FullName);
Console.WriteLine("Namespace: {0}", customerType.Namespace);
Console.WriteLine("Is primitive? {0}", customerType.IsPrimitive);
Console.WriteLine("Is abstract? {0}", customerType.IsAbstract);
Console.WriteLine("Is class? {0}", customerType.IsClass);
Console.WriteLine("Is public? {0}", customerType.IsPublic);
Console.WriteLine("Is nested? {0}", customerType.IsNested);

Type properties

There are methods available on the Type object to read all sorts of information that can be reflected on: interfaces, constructors, properties, methods etc. We’ll look at those separately.

View all posts on Reflection here.

Elliot Balynn's Blog

A directory of wonderful thoughts

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

WEB APPLICATION DEVELOPMENT TUTORIALS WITH OPEN-SOURCE PROJECTS

Once Upon a Camayoc

ARCHIVED: Bite-size insight on Cyber Security for the not too technical.