Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / security / cryptography

Android and .NET Encryption.

4.93/5 (15 votes)
6 Oct 2014CPOL6 min read 50.5K   1.6K  
This article will explain briefly how to use a basic encryption/decryption on Android and on .NET platforms, with focus on passing encrypted data from Android to .NET.
Source:
Github: https://github.com/Pavel-Durov/CodeProject-Android-and-NET-Encryption
Direct:

Table of Contents

Preface

Sensitive data that can be observed by foreign eyes should be encrypted.

What is sensitive is your decision to make. It can be any personal data, images that you are sending over the network, your GPS location etc…

Sensitive data is vulnerable when its exposes outside of your program, when it is sent on the internet, or saved to local file system.

This article is not about security, it’s about simple encryption/decryption implementation. 

What is Encryption?

Encryption is a transformation of the plaintext into a cipher text.

Decryption is the opposite; it is a transformation of the cipher text to plain text, to a readable format.

Encryption algorithms can be divided into 2 groups, symmetric and asymmetric. Both have their advantages and drawbacks.

Symmetric Encryption

Encryption and decryption are performed by one identical shared key. This key is shared between the sender and the recipient.

In order to encrypt the message, the sender uses the shared key; the recipient must use the same key to decrypt the message.

Symmetric algorithm is very fast but it requires both sides to have a unique identical key, which can be a problem in a big system because of the enormous number of keys management.

Asymmetric Encryption (public-key cryptography)

The sender and the recipient use different keys to encrypt and decrypt the message, each one has a pair of keys – public and private.

When the sender wants to encrypt a message, he uses the recipient public key. The recipient can then decrypt the message using his private key. This approach is slower but key management is much easier on large systems.

Symmetric Encryption in Android

In this example we will use an Android’s SDK class Cipher for our encryption/decryption purposes.

Cipher class provides access to implementations of cryptographic ciphers for encryption and decryption. More about this on:

http://developer.android.com/reference/javax/crypto/Cipher.html

 

CryptoHandler class

Our Cipher depends on two keys, the first one is the secret key passed as string to constructor, and the second is a raw secret key which is 16-byte long.

 

Let’s examine our CryptoHandler class.

Java
<a name="CryptoHandlerClass">
//CryptoHandler constructor

 public CryptoHandler(String passphrase)

 {
     //decodes passd phrase to encrypted byte[]
     byte[] passwordKey = encodeDigest(passphrase);
     try
     {
       //_aesCipher instantiation passing transformation parameter
         _aesCipher = Cipher.getInstance(CIPHER_TRANSFORMATION);
     }
     catch (NoSuchAlgorithmException e)
     { //Invalid algorithm in passed transformation parameter
         Log.e(TAG, "No such algorithm " + CIPHER_ALGORITHM, e);
     }

     catch (NoSuchPaddingException e)
     { //Invalid padding in passed transformation parameter
         Log.e(TAG, "No such padding PKCS5", e);
     }


     //Encodes the passed password phrase to a byte[]
     //that will be stored in class private member of SecretKey type
     _secretKey = new SecretKeySpec(passwordKey, CIPHER_ALGORITHM);

     //Creates a new IvParameterSpec instance with the bytes
     //from the specified buffer iv used as initialization vector.
     _ivParameterSpec = new IvParameterSpec(rawSecretKey);

 }</a>

In our CryptoHandler class we will use an AES (Advanced Encryption Standard) encryption on which you can read more here:

http://en.wikipedia.org/wiki/Advanced_Encryption_Standard

The AES instantiation happens in the following line:

Java
private static String CIPHER_TRANSFORMATION = "AES/CBC/PKCS5Padding";

_aesCipher = Cipher.getInstance(CIPHER_TRANSFORMATION);

We invoke a Cipher static method which returns an instantiated object of type Cipher (if no exceptions were thrown).

“AES/CBC/PKCS5Padding “(passed String transformation argument)

 

AES – The encryption algorithm (Advanced Encryption Standard).

CBC – The name of a feedback mode (in our case Cipher Block Chaining).

PKCS5Padding – The name of the padding scheme.

 

CryptoHandler class methods

In addition to the constructor we also have 3 other methods in our CryptoHandler class:

Java
<a name="CryptoHandlerClassMethods">
public byte[] Encrypt(byte[] clearData)</a>

Encrypt method sets the _aesCipher to Encrypt Mode by passing the Cipher.ENCRYPT_MODE constant to init() method.

Java
<a name="CryptoHandlerClassMethods">
public byte[] Decrypt(byte[] data)</a>

Decrypt method does the same but instead of passing Cipher.ENCRYPT_MODE it passes Cipher.DECRYPT_MODE.

Both Decrypt and Encrypt methods are calling the DoWork() method, the only difference between them is the Cipher mode constant that each sets.

Java
<a name="CryptoHandlerClassMethods">
public byte[] DoWork(byte[] data)</a>

Calls the _aesCipher.doFinal(data) method and catches exceptions.

Java
<a name="CryptoHandlerClassMethods">
private byte[] encodeDigest(String text)</a>

Used once in the constructor for password phrase encoding.

The private raw key is stored as a byte array in the class:

Java
<a name="CryptoHandlerClassMethods">
 private static byte[] _rawSecretKey =

 {
       0x12, 0x00, 0x22, 0x55, 0x33, 0x78, 0x25, 0x11,
       0x33, 0x45, 0x00, 0x00, 0x34, 0x00, 0x23, 0x28
 };</a>

This key must be shared between the sender and the recipient, in our case we are participating as both of them, so we are using the same key instance for encryption and decryption.

Android implementation

On MainActivity layout you can see two colored areas, the blue one is the one that you enter your text for encryption, the green one is just displaying it.

 

When you pressing the Encrypt button, the encrypted data will be saved to the internal file system (You can see it under the files folder) and showed as gibberish on the green view (this is the cipher text of the original plaintext).

 

*The saved data will override the previous and will not be appended to existing data in the file.

 

Java
<a name="AndroidImplementation">
/**
 * Encrypts the String value that entered in the _tvMessage EditText View
* and saves is to file on local file system
* */
private void EncryptMessage()
{
     String message  = _tvMessage.getText().toString();
     if(message != null && message.length() > 0)
     {
          //performs text encryption
          byte[] bytes = _crypto.Encrypt(message.getBytes());
          //sets view value
          SetTextViewEncryptresult(bytes);

          //saves encrypted text to internal file
          _streamHandler.SaveTextFile
              (
                     FileStreamHandler.ENCRYPTED_TXT_FILENAME,
                     bytes
              );

     }     
}</a>

Image 1

* If you don’t know how to view your internal data of Android device, check my article:

http://www.codeproject.com/Articles/825304/Accessing-internal-data-on-Android-device

 

All file operations is performed through the FileStreamHandler in handlers package.

There are several methods that are responsible for reading and writing into an internal file.

As you click the Decrypt button on MainActivity layout, the message will be read from the saved file and shown to you as Toast message.

 

Java
/**
 * Decrypt the message from saved local file content.
 * calls ShowToast() method
 * */

private void DecryptMessage()

{
       byte[] fileContent = _streamHandler

              .ReadFromLocalFile(FileStreamHandler.ENCRYPTED_TXT_FILENAME);            

       if(fileContent != null && fileContent.length > 0)
       {
              //preforms decryption of the fuile content
              byte[] decrypted = _crypto.Decrypt(fileContent);
             
              //Creates new String instance of passed byte[] as UTF-8
              String readableData = StringHandler.GetString(decrypted);
              String encrypted = StringHandler.GetString(fileContent);

              if(readableData != null && encrypted != null)
              {
                     //showing toast
                     ShowToast
                     (     
                           getString(R.string.msg_decrypted) + readableData,
                           getString(R.string.msg_encrypted) + encrypted

                     );
              }
       }
       else
       {      //if file not exist or file content is empty
              ShowToast(":(", "!");
       }
}

If you clicked on Decrypt button and you got something like this:

Image 2

That means that you finished the whole cryptographic cycle.

You entered a plain text, which was encoded to a cipher text and saved to local file, which afterwards were read and deciphered to a normal readable text.

In this example we saved the key and the password phrase as hardcoded value in our java class, however this is not an optimal solution, since it can be inspected very easily using reverse engineering, so keep it in mind and store the key in safe place.

Decrypting Android message on .NET

Now we’ll see how to decipher the cipher text that we encrypted on Android device, on .NET using C# language. This can be done on other platforms as well because we used standard encryption.

We will pull the file that we saved previously on the Android device to the machine and will import it to basic Console Application on Visual Studio.

Ok, let’s create the file and pull it using adb:

Steps:

  1. Enter message in the blue area and press the Encrypt button.

Image 3

 

Now our message is encrypted and saved to the hard drive.

     2. Next we'll run several commands to grand file permissions and pull command to get the  file from the  device.

 

*Again, if you don’t understand, please look at my article about adb tool and Android internal files permissions:

http://www.codeproject.com/Articles/825304/Accessing-internal-data-on-Android-device

Image 4

Since all my adb commands were executed successfully I can now browse my file in my Downloads directory:

Image 5

Now we are going to import it to our .NET Console Application.

*Do not copy the text, we are dealing here with binary data and coping it as string can change its value! Simply copy the file as is.

In our C# Console Application we got the CryptoHandler class that is basically the same as on Android. Notice that on .NET we used two instances of ICryptoTransform as the decryption and encryption mechanism. That’s pretty much the same, since on Android we used constants and here we are using factory method of RijndaelManaged .NET class.

 

If every thing goes as it should be, run the C# program and you will see the same message as entered on the Android device:

Image 6

Summary

We encrypted and decrypted our simple message on Android and .NET Application. This can be done as part of Client-Server communication (Android as Client, .NET as Server) with text or any other binary file that you wish to encrypt, except that you will need to deal with data transition over network, which we didn’t covered here.

Do not run and encrypt every thing that you have on your hands, especially when you dealing with large binary files. That can decrease your application efficiency, especially if you are defending data that no one is interested in.

License

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