Click here to Skip to main content
15,881,882 members
Articles / Security / Encryption
Tip/Trick

Encryption and Decryption Support in .NET and Android

Rate me:
Please Sign up or sign in to vote.
4.74/5 (17 votes)
29 Aug 2015CPOL2 min read 49.3K   17   20
It supports in C#.NET and Android platform for Encrypting and Decrypting data.

Introduction

In my project, I faced a situation where Encryption and Decryption is needed in both .NET and Android platforms. Suppose a file contains XML data that is produced from an application of C#.NET and that file will be sent to an Android application. The file should be encrypted for security issue and then it should be decrypted in Android side. And again the encrypted data should be sent from Android and it should be decrypted in .NET application. These code snippets solved my problems.

Using the Code

Here's the solution of this, the main challenge was managing the data in Android side as it has some limitations. OutOfMemory exception is so common when you parse or read a very long string in Android. To avoid this, I tried a lot of things, but that hampered the encryption. At last, a very easy way solved this matter, I added a property in manifest file in Android application which is: android:largeHeap="true"

While encrypting and deciphering the content, you need to be aware of some properties. The key should be matched, the parameters like Mode, Padding and Encoding Type should be matched. At first, I put the C# codes here:

C#
public class Cryptography_CSharp
    {
        public static string Encrypt(string data, string key)
        {
            RijndaelManaged rijndaelCipher = new RijndaelManaged();
            rijndaelCipher.Mode = CipherMode.CBC; //remember this parameter
            rijndaelCipher.Padding = PaddingMode.PKCS7; //remember this parameter

            rijndaelCipher.KeySize = 0x80;
            rijndaelCipher.BlockSize = 0x80;
            byte[] pwdBytes = Encoding.UTF8.GetBytes(key);
            byte[] keyBytes = new byte[0x10];
            int len = pwdBytes.Length;

            if (len > keyBytes.Length)
            {
                len = keyBytes.Length;
            }

            Array.Copy(pwdBytes, keyBytes, len);
            rijndaelCipher.Key = keyBytes;
            rijndaelCipher.IV = keyBytes;
            ICryptoTransform transform = rijndaelCipher.CreateEncryptor();
            byte[] plainText = Encoding.UTF8.GetBytes(data);

            return Convert.ToBase64String
            (transform.TransformFinalBlock(plainText, 0, plainText.Length));
        }

        public static string Decrypt(string data, string key)
        {
            RijndaelManaged rijndaelCipher = new RijndaelManaged();
            rijndaelCipher.Mode = CipherMode.CBC;
            rijndaelCipher.Padding = PaddingMode.PKCS7;

            rijndaelCipher.KeySize = 0x80;
            rijndaelCipher.BlockSize = 0x80;
            byte[] encryptedData = Convert.FromBase64String(data);
            byte[] pwdBytes = Encoding.UTF8.GetBytes(key);
            byte[] keyBytes = new byte[0x10];
            int len = pwdBytes.Length;

            if (len > keyBytes.Length)
            {
                len = keyBytes.Length;
            }

            Array.Copy(pwdBytes, keyBytes, len);
            rijndaelCipher.Key = keyBytes;
            rijndaelCipher.IV = keyBytes;
            byte[] plainText = rijndaelCipher.CreateDecryptor().TransformFinalBlock
            			(encryptedData, 0, encryptedData.Length);

            return Encoding.UTF8.GetString(plainText);
        }
    }

The above Cryptography_CSharp class is written in C# which shows the Encryption and Decryption though 
RijndaelManaged class. It uses some parameters like Mode, Padding which should be matched in Android/JAVA side also. You can send data as String through this method. I am not putting the file reading and writing codes here. Now the Android side's class would be like this:

C#
    public class Cryptography_Android {
	public static String Decrypt(String text, String key) throws Exception {
		Cipher cipher = Cipher.getInstance
		("AES/CBC/PKCS5Padding"); //this parameters should not be changed
		byte[] keyBytes = new byte[16];
		byte[] b = key.getBytes("UTF-8");
		int len = b.length;
		if (len > keyBytes.length)
			len = keyBytes.length;
		System.arraycopy(b, 0, keyBytes, 0, len);
		SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
		IvParameterSpec ivSpec = new IvParameterSpec(keyBytes);
		cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
		byte[] results = new byte[text.length()];
		BASE64Decoder decoder = new BASE64Decoder();
		try {
			results = cipher.doFinal(decoder.decodeBuffer(text));
		} catch (Exception e) {
			Log.i("Erron in Decryption", e.toString());
		}
		Log.i("Data", new String(results, "UTF-8"));
		return new String(results, "UTF-8"); // it returns the result as a String
	}

	public static String Encrypt(String text, String key) throws Exception {
		Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
		byte[] keyBytes = new byte[16];
		byte[] b = key.getBytes("UTF-8");
		int len = b.length;
		if (len > keyBytes.length)
			len = keyBytes.length;
		System.arraycopy(b, 0, keyBytes, 0, len);
		SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
		IvParameterSpec ivSpec = new IvParameterSpec(keyBytes);
		cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);

		byte[] results = cipher.doFinal(text.getBytes("UTF-8"));
		BASE64Encoder encoder = new BASE64Encoder();
		return encoder.encode(results); // it returns the result as a String
	}
}

In the above class, it is shown that the Cryptography is done through Cipher Class with AES Algorithm. Mode and Padding parameters should be same. BASE64Encoder is used for encoding and decoding the bytes.

So this is it, this code snippets work perfectly in my application. My next target is to build an API which can support Encryption in any platforms in faster and more efficient ways. The code snippet of Android side is completely JAVA, and you will face OutOfMemoryException. For solving this, you need to add android:largeHeap="true" in android.manifest file. And you can use this code snippet in a JAVA application also.

Points of Interest

This was a challenge for me. It is great fun to work with Encryption and Deciphering data.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL).

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) ASA
Bangladesh Bangladesh
I am well determined and self motivated to work in multiple platforms. I don't want to isolate me in a single platform, want to be an expert in multiple technologies. And i have managerial ability and organizer experience, so in future i can be a good project manager also. I open a lot of ways to lead my life, if i fail in a certain path then other options make me confident enough to go ahead. Another thing everyone says about me and i really feel it, i am always positive minded having a very positive attitude to accomplish a job whether it is possible or not. I learn all possible ways of solving a problem then find out the optimal solution. This strategy is a little bit time consuming, but finding the best solution requires time.
This is a Organisation (No members)


Comments and Discussions

 
QuestionI want to implement the in iOS , Encryption or decryption Pin
Member 140141099-Oct-18 20:36
Member 140141099-Oct-18 20:36 
QuestionModifications Pin
Member 1143906215-Feb-18 7:20
Member 1143906215-Feb-18 7:20 
Questionandroid.util.Base64 can be swapped in with NO_WRAP Pin
Member 96265421-Nov-17 18:55
Member 96265421-Nov-17 18:55 
QuestionBase64Encoder. Android Studio .. Pin
wtf3226-Dec-16 9:39
wtf3226-Dec-16 9:39 
SuggestionYou should replace BASE64Decoder() Pin
Sergio Andrés Gutiérrez Rojas25-Oct-15 17:06
Sergio Andrés Gutiérrez Rojas25-Oct-15 17:06 
GeneralRe: You should replace BASE64Decoder() Pin
wtf3226-Dec-16 9:40
wtf3226-Dec-16 9:40 
QuestionThe .NET version uses PKCS7 padding and Android uses PKCS5 Pin
Andre Sanches (alvs)3-Sep-15 7:37
Andre Sanches (alvs)3-Sep-15 7:37 
AnswerRe: The .NET version uses PKCS7 padding and Android uses PKCS5 Pin
Miral Sarwar3-Sep-15 19:31
professionalMiral Sarwar3-Sep-15 19:31 
GeneralMy vote of 5 Pin
PVX0071-Sep-15 6:46
PVX0071-Sep-15 6:46 
GeneralRe: My vote of 5 Pin
Miral Sarwar1-Sep-15 17:57
professionalMiral Sarwar1-Sep-15 17:57 
QuestionShould not use Key as IV Pin
Member 1019551331-Aug-15 1:35
Member 1019551331-Aug-15 1:35 
GeneralMy vote of 5 Pin
Humayun Kabir Mamun30-Aug-15 23:59
Humayun Kabir Mamun30-Aug-15 23:59 
GeneralRe: My vote of 5 Pin
Miral Sarwar31-Aug-15 4:12
professionalMiral Sarwar31-Aug-15 4:12 
GeneralMy vote of 5 Pin
Аslam Iqbal29-Aug-15 20:11
professionalАslam Iqbal29-Aug-15 20:11 
GeneralRe: My vote of 5 Pin
Miral Sarwar29-Aug-15 20:47
professionalMiral Sarwar29-Aug-15 20:47 
GeneralRe: My vote of 5 Pin
Аslam Iqbal29-Aug-15 20:53
professionalАslam Iqbal29-Aug-15 20:53 
QuestionAndroid Support? Pin
Paul Conrad29-Aug-15 8:51
professionalPaul Conrad29-Aug-15 8:51 
AnswerRe: Android Support? Pin
Miral Sarwar29-Aug-15 17:09
professionalMiral Sarwar29-Aug-15 17:09 
GeneralMy vote of 5 Pin
newton.saber29-Aug-15 2:53
newton.saber29-Aug-15 2:53 
GeneralRe: My vote of 5 Pin
Miral Sarwar29-Aug-15 7:47
professionalMiral Sarwar29-Aug-15 7:47 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.