Encryption compatible between Android and C#

I've found plenty of examples how to do encryption in C#, and a couple for Android, but I'm particularly looking for a way to handle encrypting (using something like AES, TripleDES, etc.) from Android, and eventually wind up being decrypted in C#. I found an example for encoding AES in Android and encoding/decoding AES in C# but am not sure if these are compatible (C# requires an IV, nothing is specified for this in the Android example). Also, a recommendation on a good way of encoding the encrypted string for transmission over HTTP (Base64?) would be helpful. Thanks.

Asked by: David250 | Posted: 24-01-2022

Answer 1

Got some help from http://oogifu.blogspot.com/2009/01/aes-in-java-and-c.html.

Here is my Java class:

package com.neocodenetworks.smsfwd;

import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import android.util.Log;

public class Crypto {
    public static final String TAG = "smsfwd";

    private static Cipher aesCipher;
    private static SecretKey secretKey;
    private static IvParameterSpec ivParameterSpec;

    private static String CIPHER_TRANSFORMATION = "AES/CBC/PKCS5Padding";
    private static String CIPHER_ALGORITHM = "AES";
    // Replace me with a 16-byte key, share between Java and C#
    private static byte[] rawSecretKey = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

    private static String MESSAGEDIGEST_ALGORITHM = "MD5";

    public Crypto(String passphrase) {
        byte[] passwordKey = encodeDigest(passphrase);

        try {
            aesCipher = Cipher.getInstance(CIPHER_TRANSFORMATION);
        } catch (NoSuchAlgorithmException e) {
            Log.e(TAG, "No such algorithm " + CIPHER_ALGORITHM, e);
        } catch (NoSuchPaddingException e) {
            Log.e(TAG, "No such padding PKCS5", e);

        secretKey = new SecretKeySpec(passwordKey, CIPHER_ALGORITHM);
        ivParameterSpec = new IvParameterSpec(rawSecretKey);

    public String encryptAsBase64(byte[] clearData) {
        byte[] encryptedData = encrypt(clearData);
        return net.iharder.base64.Base64.encodeBytes(encryptedData);

    public byte[] encrypt(byte[] clearData) {
        try {
            aesCipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec);
        } catch (InvalidKeyException e) {
            Log.e(TAG, "Invalid key", e);
            return null;
        } catch (InvalidAlgorithmParameterException e) {
            Log.e(TAG, "Invalid algorithm " + CIPHER_ALGORITHM, e);
            return null;

        byte[] encryptedData;
        try {
            encryptedData = aesCipher.doFinal(clearData);
        } catch (IllegalBlockSizeException e) {
            Log.e(TAG, "Illegal block size", e);
            return null;
        } catch (BadPaddingException e) {
            Log.e(TAG, "Bad padding", e);
            return null;
        return encryptedData;

    private byte[] encodeDigest(String text) {
        MessageDigest digest;
        try {
            digest = MessageDigest.getInstance(MESSAGEDIGEST_ALGORITHM);
            return digest.digest(text.getBytes());
        } catch (NoSuchAlgorithmException e) {
            Log.e(TAG, "No such algorithm " + MESSAGEDIGEST_ALGORITHM, e);

        return null;

I used http://iharder.sourceforge.net/current/java/base64/ for the base64 encoding.

Here's my C# class:

using System;
using System.Text;
using System.Security.Cryptography;

namespace smsfwdClient
    public class Crypto
        private ICryptoTransform rijndaelDecryptor;
        // Replace me with a 16-byte key, share between Java and C#
        private static byte[] rawSecretKey = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

        public Crypto(string passphrase)
            byte[] passwordKey = encodeDigest(passphrase);
            RijndaelManaged rijndael = new RijndaelManaged();
            rijndaelDecryptor = rijndael.CreateDecryptor(passwordKey, rawSecretKey);

        public string Decrypt(byte[] encryptedData)
            byte[] newClearData = rijndaelDecryptor.TransformFinalBlock(encryptedData, 0, encryptedData.Length);
            return Encoding.ASCII.GetString(newClearData);

        public string DecryptFromBase64(string encryptedBase64)
            return Decrypt(Convert.FromBase64String(encryptedBase64));

        private byte[] encodeDigest(string text)
            MD5CryptoServiceProvider x = new System.Security.Cryptography.MD5CryptoServiceProvider();
            byte[] data = Encoding.ASCII.GetBytes(text);
            return x.ComputeHash(data);

I really hope this helps someone else!

Answered by: David217 | Posted: 25-02-2022

Answer 2

In the provided c# source code sample, watch out this line:


UTF-8 is the default encoding for Android, so encrypted string (especially non-ASCII chars such as Chinese) will be passed to C# assuming UTF-8. The text becomes scrambled if decoded back to string using ASCII encoding. Here is a better one,



Answered by: Roland610 | Posted: 25-02-2022

Answer 3

Yes it should be fine, as long we the keysize is the same - 128 bit AES and the correct block cipher mode (CBC). You might run into issues with padding, but that should be fairly easy to sort out. I ran into these issues with Java and Python recently, but got everything working in the end. Base64 for encoding should be fine over HTTP. Good luck!

Answered by: William178 | Posted: 25-02-2022

Answer 4

If you correctly implement the same cipher (like AES) and mode (like CTR, CFB, CCM, etc) on both ends, the ciphertext from one end can be decrypted by the other end regardless of platform.

The Android example you linked to appears to use the ECB mode, and thus is not secure for your purposes. It's critically important that you understand the implications of the block mode you select. It's very easy to get crypto wrong at this level, resulting in a system that's not as secure as you think it is.

EDIT: I take that back, it's not using ECB, but the way it generates the IV is not practical. In any case, my point about understanding the implications of the block modes stands.

You can start with this wikipedia article. Bruce Schneier's book 'Practical Cryptography' is also hugely valuable to anyone implementing cryptographic security.

As to encoding the string, if you must convert the string into ASCII text Base64 is as good a way as any, but I would suggest you investigate use of HTTP PUT or POST to spare you this additional step.

Answered by: Roland118 | Posted: 25-02-2022

Answer 5

Most of the examples on internet are weak implementation of AES. For an implementation to be strong, random IV should be used all the time and key should be hashed.

For more secure(random IV + hashed key) cross platform (android, ios, c#) implementation of AES see my answer here - https://stackoverflow.com/a/24561148/2480840

Answered by: Patrick282 | Posted: 25-02-2022

Similar questions

java - How can I find an Android encryption library or class compatible with my C# code?

Closed. This question does not meet Stack Overflow guid...

c++ - Best encryption library for mobile devices?

Hello I have been using LibTomCrypt to use SHA1 encryption ( for data integrity checking ) on mobile devices (iPhone OS and Android for the moment ). I was wondering if anyone is using anything else, things to consider are Portability ( C preferred but C++ is also an option ), and libraries size ( small == better for my particular needs ).

android - Java Encryption issue

I am using PBE encryption to encrypt and decrypt some text on an Android application but I get the BadPaddingException: with the "pad block corrupted" message when I use the wrong private key to decrypt the text. My question, since I am not well versed with encryption in Java, is if this is the normal behavior of the encryption API, because I need to do some logic in the case when the wrong key is entered, but I do not k...

encryption - How to add Bouncy Castle algorithm to Android?

I am trying to write a small application using bouncycastle algorithm, from the BouncyCastleProvider.java it says we have to import and add the provider during runtime by the following...

encryption - how to play an encrypted file in Android

I need to be able to play an encrypted file in Android. The file is AAC. The only way I can see to do this is either: decrypt the file to internal private storage and point the player at that file to play, or decrypt & decode the file to pcm and feed it to an AudioTrack. 1 isn't great because it takes a long time to do that. 2 isn't great either because I don't ...

encryption - Should I use the bouncy castle libraries or the ones included in Android for AES

I'm writing an android app where I need to use AES. Is it better to use the bouncy castle libraries or should I just stick with what is included in default android libraries?

What is the most secure encryption mode for Android?

Currently I am using: Algorithm_mode_padding="RSA/ECB/PKCS1Padding" Provider="BC" I have heard that ECB can cause patterns in the output. What is the most secure Algorithm, mode and padding for Android at the moment? I will be using this for license files. Also, what is the best keysize to use when creating a new public and private key?

encryption - Asymmetric Crypto on Android

I would like to ask if i can use Asymmetric Crypto (like RSA or ECC) on android mobile phones, how, and what are the best libraries i should use.

android - Identify GSM encryption algorithm

I would like to find out whether my android phone (ADP) is using A5/0, A5/1 or A5/2 at a specific time. How can I achieve this?

encryption - How can I store music on an android phone without allowing the user to be able to download it and use it?

I am working on an app that connects to a media providing site and downloads mp3 files to the user phone. I would like for the user to be unable to copy these files off the phone but only listen to them through my app. I am currently trying to encrypt the files using DES and encryption and decrypt and play the file in bits in the app. This is however not working. Is there a better way of achieving my end goal or ha...

security - Android Data Encryption dilemma

I'm creating an application that encrypts data with a key that is created each time the user logs into the app. However, there are times when data will be received via a BroadcastReceiver that needs encrypting, but the user is not logged in and so the encryption key is not available. Security is pretty important and so using a key stored in code to encrypt the data until the user next logs in is out of the question as is s...

Still can't find your answer? Check out these communities...

Android Google Support | Android Community | Android Community (Facebook) | Dev.io Android