Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Encryption compatible between Android and C#

Tags:

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.

like image 813
Jess Avatar asked Jan 19 '10 03:01

Jess


People also ask

Which encryption does Android use?

Android full-disk encryption is based on dm-crypt , which is a kernel feature that works at the block device layer. Because of this, encryption works with Embedded MultiMediaCard (eMMC) and similar flash devices that present themselves to the kernel as block devices.

Does Android use AES?

Symmetric Encryption using AES Algorithm — Android Encryption. Symmetric Key is a key generated by Password-Based Key Derivation Function (PBKDF2) by taking a password and hashing it with salt over many times, to ensure to produce a unique key , even if different user uses a same password.

Is Android filesystem encrypted?

Full-disk encryption was introduced to Android in 4.4, but Android 5.0 introduced these new features: Created fast encryption, which only encrypts used blocks on the data partition to avoid first boot taking a long time. Only ext4 and f2fs filesystems currently support fast encryption.

Which two levels are supported by Android for device encryption?

On FDE-based Android devices, all user data is encrypted using AES-256-XTS or AES-256-CBC (depending on the device) with a randomly generated encryption key, also known as the Primary Key.


1 Answers

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!

like image 78
Jess Avatar answered Oct 13 '22 13:10

Jess