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

Create and use OneTime Passwords

Background

Probably you noticed that a lot of websites and applications start to use some form of Two-Factor Authentication.

In enterprises, this has been used for years to allow the users to securely authenticate for using VPN or web-based published corporate applications.

This relied on ‘Something you know’ and ‘Something you have’.

The Something you Know was typically a password and maybe on top of that a PIN code.

The Something you Have was typically a hardware token that displays a different numeric code every minute, maybe augmented with a computer certificate.

Use in our Applications / WebServices

While having to use a password is a basic requirement to authenticate the user, I think it has a lot of advantages to force the use of a Onetime Password as well.

This not only to authenticate the user , but also to make sure that when your WebService needs to do something, it has an additional check to make sure that this request was asked by the user or application on behalf of the user and is within an appropriate timeframe. (This should protect a bit against somebody capturing your web-request and replaying it)

This can also be used to make sure that when you receive a request back from the WebService, that you have a bit more guarantee that it actually comes from that Webservice.

Create Shared Project for OTP Handling

Create Secure Login with SQL, VS2015, Web Services in C#

A question that most developers sooner or later ask themselves is:

How to securely authenticate a user who is going to use my application or services?

This is what I want to tackle in this blog. As I stumble over the different parts involved, it will probably grow over time.

A lot of very good Frameworks and API’s exist to do this, but sometimes it is more fun (cheaper, prevents spam, …) to code 😉


The info I provided here, is just for the fun of developing it myself and meanwhile playing around with the current tools and overall learning (the hard way) about all the components involved, which will probably make me appreciate the public (payable?) services on the internet.


So, let’s begin

1. Datastore for Login Info

First of all, we need a place to store the login information.

In the past I developed some LOB applications, which evolved using the different SQL server generations (6.5, 7.0, 2000, 2005) at that time, so looking at SQL Server 2014 for this personal project, seems to be the logical choice.

UserTable

Here I describe the table structure: Table Structure for secure Login

I’m a big fan of creating small tables with not too many fields and have each additional need for related data (like address info, birth dates, whatever) to be stored in separate tables, and let the relational database do the joining.

As the table structure might change over time, and the so-called ‘business logic’ on what needs to happen in the background when accessing data (adding data, modifying and deleting it), I like to use Stored Procedures.

This way, when the underlying things change, I do not need to adapt any code in my applications and services that use it.

Here I show the Stored Procedure: Stored Procedure to Add Login

Security advise:

  • Create specific internal SQL-server accounts and passwords to protect the tables, stored procedures,, …
  • Change the access rights on the SQL server table which stores the login info, so that only the specific SQL-server account (and the administrator off course) can access it.
  • Change the access rights of the Stored procedure likewise

2. Web Service to handle the Login actions

As I want to be able to use the authentication of the user from different platforms (currently Windows WPF and Windows 10 UAP, maybe later I will give a try for Android and IOS) and I’m not sure from what network, the applications will try to access it, using a WebService on the standard http/https ports would fit most scenario’s, as this can be used on internet connections routed through a proxy and most networks allow these ports (80/443) to pass unhindered.

Here I describe on how to Create the project in Visual Studio 2015: Create the Project

The minimal methods I implement here are:

  • HelloWorld
    This is returning a fixed string, so I can see if the Service is running correctly
  • AddUser
    This returns a unique Identifier, when a new Login is created in the database
  • GetUserIdentifier
    This returns the unique Identifier of the user

The code for these is described here: Minimal Methods

Deploying the WebService

In order to be able to use this WebService from the internet, we need to deploy it to a web server.

This is how to use the Publish Wizard: Publish Website

For now, I’m not going into detail on how to configure your web server (IIS, or hosted on Azure,  …). Send me a post if you would like me to describe this as well.

3. Create Client applications to test the service

We will create a WPF Client application to test the service we created earlier.

The finished project will look like this:

IdentityClient

These are the steps to create the Project and add the testing code: Create the WPF Client to test the Web Service

 to do – show the UAP Creation and calling of the WebService

4. Add a OneTime Password (OTP) for Login and WebService Calls

While having to use a password is a basic requirement to authenticate the user, I think it has a lot of advantages to force the use of a Onetime Password as well.

This not only to authenticate the user , but also to make sure that when your WebService needs to do something, it has an additional check to make sure that this request was asked by the user or application on behalf of the user and is within an appropriate timeframe. (This should protect a bit against somebody capturing your web-request and replaying it)

This can also be used to make sure that when you receive a request back from the WebService, that you have a bit more guarantee that it actually comes from that WebService.

Some background: Create and use OneTime Passwords

As I want to use this OneTime Password (OTP) both in our clients and our WebService, I think it is best to use a Shared project.

The steps to follow to create the Shared Project and the OTP code, can be found here: Create Shared Project for OTP handling

Unfortunately in Visual Studio 2015, you can not (due to  bug ?) use the GUI to add a reference to the Shared project. To do this yourself, close Visual Studio, and open the AuthenticatorService.csproj file in notepad, and above the tag <ProjectExtensions>, add the line:
<Import Project=”..\OTPSharedProject\OTPSharedProject.projitems” Label=”Shared” />

To handle the Logon of a user, we will adapt our SQL server database, by adding a table to log all the Login attempts and create an additional Stored Procedure.

UserLogonHistory

Here I describe the table structure: Table structure to Track Logins

Here I show the Stored Procedure: Stored Procedure to Track User Login


In Visual Studio, select your WebService project and add the Method LogonUserWithOTP Code for LogonUserWithOTP

To be able to use the code we created in Create Shared Project for OTP handling, we need to reference this in our client applications.

In the Solution Explorer Window, Right-click the IdentityClient and select Add | Reference and choose your Shared Project

Add_Reference_Shared Project

Adapt the IdentityClient as described here: Code to adapt WPF client to use OTP WebService

This will produce this test-output:

IdentityClient_Run02

Showing a successful login.

5. Secure the WebService Calls

So far, the communication between the clients and WebService all happened in plain text, using the http protocol.

To augment the security, it is best to swap to using https:

For this, you need to purchase a public SSL certificate, and install this on your webserver. I’m using some from SSLS.com

to do – show how to modify the WebService and Client projects to use https.

(function(i,s,o,g,r,a,m){i[‘GoogleAnalyticsObject’]=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,’script’,’//www.google-analytics.com/analytics.js’,’ga’);

ga(‘create’, ‘UA-72228030-1’, ‘auto’);
ga(‘send’, ‘pageview’);