I have recently released a small open source library that I thought might be useful to people. The library is called Block Encrypter it is designed to make asymmetric encryption of  data in .NET / C# easier. The code in this library has been developed over the past year and used in my open source tools SafePad and Text Shredder. The way in which this library goes about encryption has been peer reviewed by many people in the open source community so should give you a level of comfort that it is secure in how it goes about encrypting data. Block Encrypter encrypts data using standard cryptographic primitives like AES, HMAC, PBKDF, and cryptographically secure random number generation.

Download the Block Encrypter .NET encryption library.
Download the Block Encrypter .NET encryption library.

I have previously discussed AES encryption in .NET in my cryptography series of articles. I also posted an article linking to some really useful videos by Patrick Townsend about how the AES algorithm works. If you are interested in symmetric cryptography I highly recommend watching them.


First lets look at some usage examples. The main object in the library to call is the Block Encrypter object and this contains methods that allow you to encrypt/decrypt strings or byte arrays of data.

Overview of the Library

The library itself is quite straight forward to use and there are not that many objects to get to grips with. The main entry point for the library is the BlockEncrypter object. This object will then call out to the GzipCompression object, Aes object, and the ByteHelpers object.

Block Encryter Class Diagram
Block Encryter Class Diagram

The library is also well covered in unit tests that exercise the majority of the functionality.

Encrypting and Decrypting Strings

const string originalMessage = "This is my message to encrypt.";

string encrypted = BlockEncrypter.EncryptStringBlock(originalMessage, Encoding.ASCII.GetBytes("Pa55w0rd"));
string decrypted = BlockEncrypter.DecryptStringBlock(encrypted, Encoding.ASCII.GetBytes("Pa55w0rd"));

Assert.AreEqual(originalMessage, decrypted);

In the example above the string “This is my message to encrypt” is encrypted and then decrypted using the password “Pa55w9rd”. Naturally this is a really bad password, but it is just an example.

Encrypting and Decrypting Byte Arrays

const string originalMessage = "This is my message to encrypt.";
byte[] testBytes = ByteHelpers.GetBytes(originalMessage);

byte[] encrypted = BlockEncrypter.EncryptByteBlock(testBytes, Encoding.ASCII.GetBytes("Pa55w0rd"));
byte[] decrypted = BlockEncrypter.DecryptByteBlock(encrypted, Encoding.ASCII.GetBytes("Pa55w0rd"));

Assert.IsTrue(ByteHelpers.ByteArrayCompare(testBytes, decrypted));

Summary Encryption and Decryption Process


This process is the same regardless of whether you are encrypting text or data. When encrypting text, the first thing the code does is convert it into a byte array.

  1. Generate a 32byte salt with a cryptographic random number generator. This salt is used to give us extra entropy when encrypting your data.
  2. Compress the data to be encrypted.
  3. Using the password and the salt from step 1, derive an encryption key using a password based key derivation function (RFC2898) and the salt. By using a new salt every time we encrypt we guarantee that even for the same message, the cipher text will be different each time.
  4. Create the AesCryptoServiceProvider object. This is a FIPS Certified version of the AES Algorithm in .NET. Explicitly set the mode to Cipher Block Chaining and the padding to PKCS7. These are the defaults, but for the sake of clarity I made them explicit.
  5. Using the derived key form step 3, then derive a 16 byte initialization vector.
  6. Create a new MemoryStream, CryptoStream and encrypt the data.
  7. Generate a SHA256 based Message Authentication Code (HMAC) of the salt + cipher text using the AES Encryption Key.
  8. Combine the HMAC and the encrypted cipher text into 1 byte array.
  9. Append the original salt from step 1 to the front of the message. The salt is not a secret value. It is there purely to give extra entropy.


The decryption process of a block of data is as follows.

  1. Extract the salt form the first 32 bytes of the data block.
  2. Extra the remaining HMAC and encrypted cipher text from the data block.
  3. Using the password and the salt from step 1, derive an encryption key using a password based key derivation function and the salt.
  4. Create the AesCryptoServiceProvider object. This is a FIPS Certified version of the AES Algorithm in .NET. Explicitly set the mode to Cipher Block Chaining and the padding to PKCS7. These are the defaults, but for the sake of clarity I made them explicit.
  5. Derive the initialisation vector from the encryption key.
  6. Calculate a new HMAC of the salt + cipher text using the encryption key. Check that this HMAC matched the original HMAC. If it doesn’t throw an exception and don’t proceed with decryption.
  7. Create a MemoryStream, CyptoStream and decrypt the data.
  8. Decompress the decrypted byte stream. This leaves you with the original message before encryption.


As you can see there is more just using the AesCryptoServiceProvider class to encrypt and decrypt data securely.

Please don’t use the AesManaged class in .NET as this is not FIPS Certified, so if you need to pass your encrypted data to another system / platform, you will not be able guarantee that the other system can decrypt it.

The generation of the original salt is designed to give you entropy and this means that the original message, if encrypted multiple times, will always produce a different cipher text. This helps guard you against known cipher text attacks.

When it comes to using a password to generate the key, the password based key derivation function (RFC2898) is used to generate the actual encryption key. This derivation function allows you to pass in how many rounds to use when generating the key. In this library I have it defaulted to 70,000, but you can set any number you like. The more rounds you use, the slower it is, but it is safer against brute force attacks. The idea is to slow down the key generator function so brute force cracking of the key becomes prohibitively slow.

If you didn’t want to use a human readable password, you could generate a long cryptographically secure random number instead and pass that into the block encrypter.

We also take message integrity into account by generating a SHA256 based HMAC of the encrypted message and its salt. This differs from just using SHA256 in that the HMAC is also based on the encryption key, so you need to know the key to calculate and check the same HMAC. This allows us to detect if the message has been tampered with in transit or corrupted.

I hope you find this little library useful. Many people have reviewed this code in various different states of development and have offered me much advice on how to improve it and make sure it is secure, so if you need to encrypt data in your systems, this library would be a good base for you to use.


  1. It seems we share a similar belief that encryption should be developed by few, peer reviewed by all, and then reused/consumed wherever possible… and while I don’t use the crypto libs in C# very often, I’ve used them a few times and I’m aware of them… the question is simple this: how do your APIs improve or differ from the Microsoft APIs?

    1. That’s a good question. For a start I am not replacing any of the .NET API’s, that would be madness. What this library does is use the various .NET API’s together to allow you to encrypt data with AES where the key is generated using a PBKDF using sufficient entropy and then HMAC’d.

      Even though Microsoft provide the individual API’s, I quickly learnt that even though they are there, its how you use them that is important too and this is where the peer review came in, specifically around using HMACs instead of just SHA256 for integrity, generating salts each time for the PBKDF and then deriving the IV from that key.

      If anything, you can treat the library as is, or use it as sample code to learn how to use the Microsoft API’s. I had a number of people ask me about it, so I decided to refactor the code out into a library and give it out.

  2. Dear Stephen,
    I bless the best wishes and health for that cute baby and then yourself too. Your shared knowledge help me so much to my starting encryption in ASP.NET

    I’m waiting to learn more things from your space

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: