Cross platform 256bit AES encryption / decryption

Recently I was writing an app for iOS and Android. Both the apps connect to webservices written in C#. One of the challenges that I faced was to securely encrypt and decrypt the sensitive data.

The encryption which I chose was – AES 256. However getting the cross platform encryption / decryption to work was a big challenge. Those of you who have worked on cross platform encryption / decryption must already be knowing about this. I also searched on internet but couldn’t find example of secure implementation of cross platform 256bit AES encryption / decryption. So I ended up writing my own library which I would like to share in this post.

Now what makes an implementation of AES 256 secure ? There are important things to consider here. First, the key used for encryption should be hashed. Some of the code snippets which I have seen on internet use plain text as key, which is a security flaw. Second, the initialization vector or IV should always be random. This is very important. Most of the implementations which I have seen on internet either do not use an IV or use hardcoded IV. To generate Random IV you’ll need a truly random number and getting a truly random number on mobile device (using sensor data) is an interesting and  separate topic of discussion in itself ! 

What happens if you don’t use random IV ? Read here and here.

Source code for the project is available here – https://github.com/Pakhee/Cross-platform-AES-encryption

This project contains the implementation of 256 bit AES encryption which works on all the platforms (C#, iOS, Android). One of the key objective is to make AES work on all the platforms with simple implementation.

Platforms Supported:

  1. iOS

  2. Android

  3. Windows (C#).

Features:

  1. Cross platform support. Encryption-Decryption works across C#, iOS and Android.

  2. Support for Random IV (initialization vector) for encryption and decryption. Randomization is crucial for encryption schemes to achieve semantic security, a property whereby repeated usage of the scheme under the same key does not allow an attacker to infer relationships between segments of the encrypted message.

  3. Support for SHA-256 for hashing the key. Never use plain text as encryption key. Always hash the plain text key and then use for encryption. AES permits the use of 256-bit keys. Breaking a symmetric 256-bit key by brute force requires 2^128 times more computational power than a 128-bit key. A device that could check a billion billion (10^18) AES keys per second would in theory require about 3×10^51 years to exhaust the 256-bit key space.

How to encrypt a string:

See code samples for more details. You’ll have to perform following steps:

  1. Generate Ramdom IV using the provided randomIV generator function.
  2. Select a secret key and hash it using the provided SHA-256 hash function.
  3. Encrypt your string using the hashed key and random IV.

How to decrypt a string:

See code samples for more details. You’ll have to perform following steps:

  1. Get the encrypted text and the randomIV used for encryption
  2. Decrypt the strying using the provided decrypt function !

Hope you’ll find this useful !

About Navneet Kumar

Navneet is a seasoned IT professional with more than 9+ years of experience. He has done double Masters in Mathematics and Software Systems from prestigious Birla Institute of Technology and Science (BITS), Pilani. Navneet is currently working as a Product Manager with Saama Technologies (http://saama.com).
This entry was posted in Uncategorized and tagged , , , , , , , . Bookmark the permalink.

8 Responses to Cross platform 256bit AES encryption / decryption

  1. Pingback: Cross platform 256bit AES encryption / decryption | craft-ur-success

  2. Excellent article, just the one I was looking for. Just one mistake in your code. Should be like this:
    byte[] input = Encoding.UTF8.GetBytes(_inputText);
    byte[] plainText = _rcipher.CreateEncryptor().TransformFinalBlock(input, 0, input.Length);

  3. Sushanth says:

    Hi Navneet,
    Thank you for the post, its very helpful. But I am facing an issue as explained below, can you please suggest a solution for this.
    ISSUE: I have encrypted a string in C# and decrypted the same in C# successfully. But when I try to decrypt the same string in Android, the first 16 characters of the decrypted string were being replaced by some junk characters. And the same happens in C# while decrypting the string Encrypted by Android.

    • Navneet Kumar says:

      Hi Sushant
      Code has been unit tested to be working fine. I’ll have to take a look at your code and check. Can you create a gist on github ?

      • Sushanth says:

        Hi Navneet,
        Please use “https://gist.github.com/anonymous/8c03bae5ac9ba90b5bfa” for the gist of C# code I am using. The Android code is exact the same that was provided by you. Also I am using a string for iv rather than creating it randomly. Is this causing the issue?

      • Navneet Kumar says:

        Any luck on this ?? Length of IV is the suspect .. see my reply on github

  4. Sushanth says:

    Yes it worked, thanks for the help. The issue was with the length of IV as you said and also was with “CryptLib.getHashSha256(“testencrypti”, 31)” it has to be 32 instead of 31 bytes.
    Also the iOS code shared by you returns NSData and I am facing error while converting the NSData to NSString. Can you please suggest how to return a encrypted string same as Android and C# in iOS as well?

  5. Sushanth says:

    Hi Navneet, can you tell me what can be the maximum size of input text that can be encrypted using this method?

Leave a comment