Question

So i have an android app, and a google app engine server written in python. The android app needs to send some sensible information to the server, and the way I do that is by doing an http post.

Now i have been thinking about encrypting the data in android before sending it, and decrypting it once it is on the gae server.

This is how i encrypt and decrypt in java :

private static final String ALGO = "AES";



public static String encrypt(String Data) throws Exception {
        Key key = generateKey();
        Cipher c = Cipher.getInstance(ALGO);
        c.init(Cipher.ENCRYPT_MODE, key);
        byte[] encVal = c.doFinal(Data.getBytes());
     //   String encryptedValue = new BASE64Encoder().encode(encVal);

        byte[] decoded = Base64.encodeBase64(encVal);

        return (new String(decoded, "UTF-8") + "\n");
    }

public static String decrypt(String encryptedData) throws Exception {
        Key key = generateKey();
        Cipher c = Cipher.getInstance(ALGO);
        c.init(Cipher.DECRYPT_MODE, key);
        byte[] decordedValue =Base64.decodeBase64(encryptedData);
        byte[] decValue = c.doFinal(decordedValue);
        String decryptedValue = new String(decValue);

        return decryptedValue;

    }

    private static Key generateKey() throws Exception {
        Key key = new SecretKeySpec(Constant.keyValue, ALGO);
        return key;
    }

And this is how i try to decrypt on the server (i don't know yet how to do the encryption..maybe you guys can help with that too)

def decrypt(value):
    key = b'1234567891234567'

    cipher = AES.new(key, AES.MODE_ECB)
    msg = cipher.decrypt(value)

    return msg

As i looked in the logs, the string test that i get is : xVF79DzOplxBTMCwAx+hoeDJhyhifPZEoACQJcFhrXA= and because it is not a multiple of 16 (idk why, i guess this is because of the java encryption) i get the error

ValueError: Input strings must be a multiple of 16 in lenght

What am i doing wrong?

Was it helpful?

Solution 2

This string "xVF79DzOplxBTMCwAx+hoeDJhyhifPZEoACQJcFhrXA=" is a base64-encoded value.

https://en.wikipedia.org/wiki/Base64

Base64 encoding is widely used lots of applications, it's a good way to encode binary data into text. If you're looking at a long encoded value, the "=" at the end can be a good indicator of base64 encoding.

In your python code you probably need to base64 decode the data before handing it to the decryption function.

I have two recommendations:

  1. If crypto isn't a comfort zone for you, consult with someone who is good in this area for your project.

  2. Be aware that embedding a symmetric encryption key in an Android app that you distribute is a bad idea. Anyone that can get a copy of your app can extract that key and use it to decrypt or spoof your messages.

OTHER TIPS

Why are you not using ssl (aka https)? That should provide all the encryption needed to transport data securely and privately between the phone and App Engine.

The basics of it: Instead of sending data to http://yourapp.appspot.com/, send it to https://yourapp.appspot.com/.

For a complete secure and authenticated channel between App Engine and Android, you can use Google Cloud Endpoints. It will even generate the Android side code to call it.

Java:

Python:

For a longer show and tell, check the IO 13 talk: https://www.youtube.com/watch?v=v5u_Owtbfew

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top