5

In my android app, I use Microsoft translator which requires two strings, clientId and clientSecret. At the moment, I hardcoded those two strings. Since I discovered classes.dex can be converted to jar, and then .class files can also be converted to .java files, I think that hardcoding those sensible strings is not a good thing.

So my question is simple: how to hide those strings from malicious people?

Thank you

Romain Pellerin
  • 2,470
  • 3
  • 27
  • 36
  • Similar: http://stackoverflow.com/questions/12465328/where-to-store-sensitive-global-information-such-as-api-keys-in-android-applicat – dannyroa Apr 04 '13 at 01:02
  • 1
    Check this answer http://stackoverflow.com/questions/4427238/hiding-strings-in-obfuscated-code – mrmoldovan Apr 04 '13 at 01:04

1 Answers1

1

Pre-encrypt a String and store it in a resource file. Decrypt it with a key. It's merely security through obscurity, but at least the "secrets" won't be in plain text.

public class KeyHelper {

    /**
     * Encrypt a string
     *
     * @param s
     *            The string to encrypt
     * @param key
     *            The key to seed the encryption
     * @return The encrypted string
     */
    public static String encode(String s, String key) {
        return base64Encode(xorWithKey(s.getBytes(), key.getBytes()));
    }

    /**
     * Decrypt a string
     *
     * @param s
     *            The string to decrypt
     * @param key
     *            The key used to encrypt the string
     * @return The unencrypted string
     */
    public static String decode(String s, String key) {
        return new String(xorWithKey(base64Decode(s), key.getBytes()));
    }

    private static byte[] xorWithKey(byte[] a, byte[] key) {
        byte[] out = new byte[a.length];
        for (int i = 0; i < a.length; i++) {
            out[i] = (byte) (a[i] ^ key[i % key.length]);
        }
        return out;
    }

    private static byte[] base64Decode(String s) {
        try {
            return Base64.decode(s);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private static String base64Encode(byte[] bytes) {
        return Base64.encodeBytes(bytes).replaceAll("\\s", "");
    }
}

Also note, that this example requires you to include Base64 class in your project :)

Bill Mote
  • 12,644
  • 7
  • 58
  • 82
  • Thank you!! I'll try your solution this week end and let you know if it worked. Why do you suggest me to store the string in a resource file? – Romain Pellerin Apr 04 '13 at 13:21
  • Just a further abstraction. I store them in a strings file and I usually make the key something else that's already in the strings file -- note that I make something that looks like it fits in, but isn't really being used so I don't risk changing it by mistake :) – Bill Mote Apr 04 '13 at 13:25
  • -1 this is not secure. its impossible and you don't need it. See http://cwe.mitre.org/data/definitions/602.html – rook Apr 05 '13 at 15:50
  • The code of Base64 class?, It's necessary for the example –  Apr 10 '15 at 20:44
  • No. The Base64 class is freely downloadable from the internet and I believe Android has a version built in now. – Bill Mote Apr 13 '15 at 11:30