Reputation: 93
we use some Networkcredentials in out App. I just decompiled the app and was able to see the Credentials like Name and Password. I do not really get how to prevent this. I think the word "obfuscator" is the direction which I have to go. We test proguard but it does not have string encryption or am I wrong?
Is there an easy and free way to do this?
Thank you.
Upvotes: 6
Views: 6362
Reputation: 920
You should consider to encipher the username and the password: How to encrypt String in Java.
// bytes to encrypt
byte[] input;
// the key and the initialization vector
byte[] keyBytes;
byte[] ivBytes;
// initialize the Cipher
SecretKeySpec key = new SecretKeySpec(keyBytes, "DES");
IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
// encryption
cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);
byte[] encrypted= new byte[cipher.getOutputSize(input.length)];
int enc_len = cipher.update(input, 0, input.length, encrypted, 0);
enc_len += cipher.doFinal(encrypted, enc_len);
// decryption
cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);
byte[] decrypted = new byte[cipher.getOutputSize(enc_len)];
int dec_len = cipher.update(encrypted, 0, enc_len, decrypted, 0);
dec_len += cipher.doFinal(decrypted, dec_len);
Usually, the key
(bytes array) should be stored in a file that is only accessible on the specific instance where the server is running and not coded into the app source file.
Otherwise you can use hash (e.g: md5 or sha1) and store the fingerprint instead of the plain string:
// SHA1("hello world") -> "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed
This is a simple method which allows you to calculate the SHA1 hash
of a string:
public static String SHA1(String text) throws NoSuchAlgorithmException, UnsupportedEncodingException {
MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(text.getBytes("iso-8859-1"));
byte[] hash = md.digest();
Formatter formatter = new Formatter();
for (byte b : hash)
formatter.format("%02x", b);
return formatter.toString();
}
Import java.io.UnsupportedEncodingException
, java.security.MessageDigest
and java.security.NoSuchAlgorithmException
are required.
Upvotes: 3
Reputation: 38424
Sorry, but this simply does't work no matter what you'll try. If you obfuscate / encrypt the credentials, the program still must be able to decrypt them at run-time. Therefore, the encryption keys must also be in the generated bytecode somewhere and therefore it's possible to take them, and decrypt the credentials manually outside the program (or just step through the program and read the credentials once they're decrypted).
What you're trying to do is Security by Obscurity and it doesn't work.
Whatever you do, if the program can obtain the credentials at run-time without any external help, a skilled attacker can do the same given enough time.
What you should do:
Upvotes: 8
Reputation: 2125
Your issue is related to encryption and not obfuscation. You may use this library to store the credentials in an encrypted way: http://www.jasypt.org/encrypting-configuration.html There are different ways to pass the encryption key to it.
Otherwise, depending on your context, consider using different authentication mechanisms (SSO like) instead of login/password.
Upvotes: 0