Serialize and Encrypt an Object using C#

Background

When I was working on some demo applications to check out the IoT buzzword, I needed a way to securely submit messages back and forth between applications running on different platforms.

In the background, I use a Message Queue Service that allowed me design my applications in such a way that the sender and receiver of the message did not need to interact with the message queue at the same time as the messages placed onto the queue are stored until the recipient retrieved them.

I used 2 technologies to get my feet wet with the Message Queues:

If you want, I can describe this a bit more in detail, but for now, I want to focus on the actual message that I submitted and retreived through these queues.

I wanted to submit objects through these queues, as this would provide a lot of flexibility in sharing different types of messages and answers (like commands to do something, send answers back, update configurations and so forth).

As typically some form of strings are used as messages, I needed to do convert my objects to strings. (sometimes also called serializing)

How to convert an object to a string and back again

When I was developing an application that was consuming OData, using the Entity Framework, I noticed that one of the libraries used was  Newtonsoft.json, which is in their own wording ‘a Popular high-performance JSON framework for .NET’.

Browsing their documentation and API, I decided to give it a go.

I installed the package in Visual studio 2015 via Nuget Packet Manager and was ready to use it in my code.

As base class, I use a very simple class, containing a Token (int) and the Data (string). Sample code can be found here: InfoBlock

Now that I can create an object, I can serialize it using Newtonsoft.json with this simple line of code:

myString = JsonConvert.SerializeObject(anInfoBlock);

As I wanted to include the ‘Infoblock’ identification of the seralized object in the string, I use this in my production code:

JsonSerializerSettings theJsonSerializerSettings = new JsonSerializerSettings();

theJsonSerializerSettings.TypeNameHandling = TypeNameHandling.None;
myString = JsonConvert.SerializeObject(anInfoBlock, theJsonSerializerSettings);

To deserialize, I can typecast it to the Infoblock class.

myInfoBlock = JsonConvert.DeserializeObject<InfoBlock>(myString, theJsonSerializerSettings);

Encrypting and Decrypting a string

When I was sniffering the traffic that was sent using Microsoft Message Analyzer, I noticed that everything was easily readable and therefore I decided to make this somewhat more difficult by encrypting it.

I selected AES as encryption algorithm, (being from Belgium and this is based upon the Rijndael cipher, developed by two Belgian cryptographers, Joan Daemen and Vincent Rijmen, who submitted a proposal to NIST during the AES selection process) and based my initial code on Stackoverflow Q&A.

The AES encryption is using a symmetic key-algorithm, where the same key is used for both encrypting and decrypting the data.

  • I use a Keysize of 256 bits and Blocksize of 128 bits.
  • The Initialization Vector is a 128-bit random starting value

In order to be able to successfully decrypt the string, we need to know the key and the Initialization Vector.

  • The Key is embedded in our coode, so this is fine
  • The Initialization Vector is random, so to share it, we embed this in the encrypted string. I preferred to also store this somewhere randomly in the encrypted string, to feel a bit more secure.

To make the decription a bit harder, we have to make sure that each time when we encrypt the same string, the encrypted vesion is different. We will test this in our Test Units using the appropriate asserts.

Implementation

in .NET, we have an encryption freamework we can use. Unfortunately the newer WinRT uses different classes to get this done, but by using conditional compilation we can achieve this.

#if WINDOWS_UWP

using Windows.Security.Cryptography;
using Windows.Security.Cryptography.Core;
using Windows.Storage.Streams;

#else

using System.Security.Cryptography;

#endif

In WinRT (UAP) I use:

myCryptoAlgorithm = SymmetricKeyAlgorithmProvider.OpenAlgorithm(“AES_CBC_PKCS7”);

In legacy windows applications, this is:

myCryptoAlgorithm = new AesCryptoServiceProvider();
myCryptoAlgorithm.Mode = CipherMode.CBC;
myCryptoAlgorithm.Padding = PaddingMode.PKCS7;
myCryptoAlgorithm.KeySize = 256;
myCryptoAlgorithm.BlockSize = 128;

CBC means Cipher Block Chaining:

The Cipher Block Chaining (CBC) mode introduces feedback. Before each plain text block is encrypted, it is combined with the cipher text of the previous block by a bitwise exclusive OR operation. This ensures that even if the plain text contains many identical blocks, they will each encrypt to a different cipher text block. The initialization vector is combined with the first plain text block by a bitwise exclusive OR operation before the block is encrypted. If a single bit of the cipher text block is mangled, the corresponding plain text block will also be mangled. In addition, a bit in the subsequent block, in the same position as the original mangled bit, will be mangled.

PKCS7 is a method of adding bytes to the text, so that the complete buffer is filled.

The PKCS #7 padding string consists of a sequence of bytes, each of which is equal to the total number of padding bytes added.

Most plain text messages do not consist of a number of bytes that completely fill blocks. Often, there are not enough bytes to fill the last block. When this happens, a padding string is added to the text. For example, if the block length is 64 bits and the last block contains only 40 bits, 24 bits of padding are added.

Some encryption standards specify a particular padding scheme. The following example shows how these modes work. Given a blocklength of 8, a data length of 9, the number of padding octets equal to 7, and the data equal to FF FF FF FF FF FF FF FF FF:

with PKCS7 padding, this then becomes: FF FF FF FF FF FF FF FF FF 07 07 07 07 07 07 07

The Sample Code for my String Encryptor class can be found here: StringEncryptor

Putting it all together

Now that I have a class to Encrypt and Decrypt strings, I create a helper class to Serialize and Encrypt an InfoBlock and do the reverse (Decrypt a string and Deserialize it back to an Infoblock)

The class is: InfoBlockConvertor

This is how I use it in my TestUnit:

[TestMethod]
public void EncryptDecryptInfoBlock()
{

// Arrange
InfoBlock InfoBlock01 = new InfoBlock();

// Act
InfoBlock01.Token = InfoBlock.SOMETHINGELSE;
InfoBlock01.Data = “Testing 123: Add some special characters &é@#’öçà!£$<ù}”;
var encryptedString1 = InfoBlockConvertor.EncodeToString(InfoBlock01);
var encryptedString2 = InfoBlockConvertor.EncodeToString(InfoBlock01);
var InfoBlock02 = InfoBlockConvertor.DecodeFromString(encryptedString2);

// Assert
Assert.AreNotEqual(encryptedString1, encryptedString2, “Infoblock should never be encrypted the same twice”);
Assert.AreEqual(InfoBlock01.Token, InfoBlock02.Token, “Tokens should match original value”);
Assert.AreEqual(InfoBlock01.Data, InfoBlock02.Data, “Data should match original value”);

}

When I execute these tests, I get these results:

Tests_Infoblock

So everything works fine 😉

 


Complete solution Code and Testing Units can be found at Github Sources

 

Advertisements

Get Time from NTP server using C#

Background

When I was developing code for checking the OneTime Passwords  Code for LogonUserWithOTP, I noticed that on one of my development machines (Win7 Enterprise, domain joined) and also on my Windows 10 Mobile Insider Preview Device, the local clock had a rather big offset compared to the time on the server.

So, I decided to write some code that I could share between regular .NET applications and the newer Windows UAP platform.

Doing a search on the internet, I noticed that this had been discussed earlier (like on Q&A on Stackoverflow) but not yet made into a class to be shared between the different windows platforms.

The NTP servers I will use in my code is the Global NTP pool.

Implementation

As the NTP uses UDP communication on port 123, we need to implement this using Sockets in regular .NET applications and DatagramSockets in the newer WinRT/UAP based applications.

As I want to share my code between the different types of projects, I opted for a Shared Project setup, using Conditional Compilation Directives.

When you create a Windows UAP, in your project properties, you can see that by default, 3 Conditional Compilarion Symbols are added to your application: NETFX_CORE, WINDOWS_UWP and CODE_ANALYSIS:

Windows_UWP_Directive

I use the subsequent Conditional Compilation Directives in my code, when I need to make a distinction of the code, depending on the target platform:

#if WINDOWS_UWP

//Code for UAP goes here

#else

//Code for regular .NET goes here

#endif

I decided to create a Helper Classs that would embed all the logic of getting the Universal Time from a NTP server. My first idea was to make it a Static Class, so I could just call the it’s methods, whithout having to instantiate it,  but in UAP this would not work, as I had implemented a call-back method.

It only makes sense to have one instance in my application, so being a big fan of Design Patterns and (being blown away in 1994 when the now famous book Design Patterns: Elements of Reusable Object-Oriented Software appeared) I choose to implement the Singleton Pattern for my Helper Class

public class DateTimeGenerator
{

#if WINDOWS_UWP

private TaskCompletionSource<DateTime> myResultCompletionSource;

#endif

private static DateTimeGenerator myInstance;

//————————————————————————————————-
//— Singleton, make sure that only 1 Instance of the class exists
//————————————————————————————————-

public static DateTimeGenerator Instance
{

get
{

if (myInstance == null)
{

myInstance = new DateTimeGenerator();

}

return myInstance;

}

}

//————————————————————————————————-
//— Private constructor to initialise the internal variables
//————————————————————————————————-

private DateTimeGenerator()
{

#if WINDOWS_UWP

myResultCompletionSource = null;

#endif

}

 

You can see that the scope of the constructor is Private, so it can not be invoked directly from your code, and you must use the Instance property of the class.


The method GetNTPTime() is implemented as an Async Task, as it relies on your internet connection, DNS resolution, firewall settings, latency and other network infrastructure stuff and can take a while to contact the NTP server and get the current NTP time back. So to keep the UI responsive, it is best to use a Async Task as this way it runs on it’s own thread.

public async Task<DateTime> GetNTPTime()

The complete code can be found at GitHub Source


I think that the best way to use the NTP functionality in your own code is to

  • have a settings page in your local application, that allows the user to specify whether to use NTP adjustment or not
  • do a periodic check in your appliction (once a day for example, or when loading the app) and inform the user in case of a larger than allowed, clock deviation.