Cómo proteger las preferencias compartidas de Android?

La ubicación común en la que SharedPreferences se almacenan en las aplicaciones de Android es:

 /data/data/<package name>/shared_prefs/<filename.xml> 

El usuario con los privilegios de la raíz puede navegar a esta localización y puede cambiar sus valores. La necesidad de protegerla es de mucha importancia.

¿De cuántas maneras podemos cifrar shared_pref's xml archivo shared_pref's xml completo de shared_pref's xml ?

Todos sabemos que podemos cifrar y guardar datos en shared_pref's xml archivo shared_pref's xml , pero eso no sólo es 100% seguro, así que necesita cifrar todo el archivo con una clave. Necesita ayuda para conocer varias formas de cifrar todo el archivo xml . Esta es una pregunta genérica, varios métodos de cifrado discutidos como respuestas aquí pueden ser útiles para todos los desarrolladores en la seguridad de las aplicaciones.

Debe tener en cuenta que las preferencias compartidas de Android son basadas en valores clave XML. Usted no puede cambiar ese hecho (ya que rompería su analizador), en el mejor de los casos puede cifrar tanto la clave como el valor, de modo que el usuario root pueda leer, pero no tendrá la menor idea de lo que está leyendo.

Para hacer eso, podría utilizar un cifrado simple como este

 public static String encrypt(String input) { // This is base64 encoding, which is not an encryption return Base64.encodeToString(input.getBytes(), Base64.DEFAULT); } public static String decrypt(String input) { return new String(Base64.decode(input, Base64.DEFAULT)); } 

Así es como usaría esto

 // Write SharedPreferences preferences = getSharedPreferences("some_prefs_name", MODE_PRIVATE); SharedPreferences.Editor editor = preferences.edit(); editor.putString(encrypt("password"), encrypt("dummypass")); editor.apply(); // Or commit if targeting old devices // Read SharedPreferences preferences = getSharedPreferences("some_prefs_name", MODE_PRIVATE); String passEncrypted = preferences.getString(encrypt("password"), encrypt("default")); String pass = decrypt(passEncrypted); 

Usted debe saber duro, que SharedPreferences nunca fueron construidos para ser seguro, es sólo una forma sencilla de persistir los datos.

Usted debe ser consciente también de que el cifrado que he utilizado no es el más seguro, pero es simple.

Hay varias bibliotecas que proporcionan mejor cifrado, como estos

Pero todos ellos vienen al hecho de que el formato del archivo sigue siendo XML y es clave-valor basado. No puedes cambiar ese hecho. Vea abajo.

 cat /data/data/your.package.application/shared_prefs/prefs-test.xml <?xml version='1.0' encoding='utf-8' standalone='yes' ?> <map> <string name="JopRH053b7Ogw17Yxmh7Og==">0AB7Y28XEvbQcnXpEZ4j9PtqzFLtm2V3KBXjTO1V704=</string> </map> The key is "hemmelighet" and the value is "dette er en hemmelighet". 

Si la seguridad es un problema más allá del hecho de que SharedPreferences sigue estando basado en valores clave y en formato XML, debe evitarlo por completo.

 public class NodeCrypto { private String iv = "fedcba9876543210";//Dummy iv (CHANGE IT!) private IvParameterSpec ivspec; private SecretKeySpec keyspec; private Cipher cipher; private String SecretKey = "0123456789abcdef";//Dummy secretKey (CHANGE IT!) public void doKey(String key) { ivspec = new IvParameterSpec(iv.getBytes()); key = padRight(key,16); Log.d("hi",key); keyspec = new SecretKeySpec(key.getBytes(), "AES"); try { cipher = Cipher.getInstance("AES/CBC/NoPadding"); } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchPaddingException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public byte[] encrypt(String text,String key) throws Exception { if(text == null || text.length() == 0) throw new Exception("Empty string"); doKey(key); byte[] encrypted = null; try { cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec); encrypted = cipher.doFinal(padString(text).getBytes()); } catch (Exception e) { throw new Exception("[encrypt] " + e.getMessage()); } return encrypted; } public byte[] decrypt(String code,String key) throws Exception { if(code == null || code.length() == 0) throw new Exception("Empty string"); byte[] decrypted = null; doKey(key); try { cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec); decrypted = cipher.doFinal(hexToBytes(code)); } catch (Exception e) { throw new Exception("[decrypt] " + e.getMessage()); } return decrypted; } public static String bytesToHex(byte[] data) { if (data==null) { return null; } int len = data.length; String str = ""; for (int i=0; i<len; i++) { if ((data[i]&0xFF)<16) str = str + "0" + java.lang.Integer.toHexString(data[i]&0xFF); else str = str + java.lang.Integer.toHexString(data[i]&0xFF); } return str; } public static byte[] hexToBytes(String str) { if (str==null) { return null; } else if (str.length() < 2) { return null; } else { int len = str.length() / 2; byte[] buffer = new byte[len]; for (int i=0; i<len; i++) { buffer[i] = (byte) Integer.parseInt(str.substring(i*2,i*2+2),16); } return buffer; } } private static String padString(String source) { char paddingChar = ' '; int size = 16; int x = source.length() % size; int padLength = size - x; for (int i = 0; i < padLength; i++) { source += paddingChar; } return source; } public static String padRight(String s, int n) { return String.format("%1$-" + n + "s", s); } } ----------------------------------------------- from your activity or class call encrypt or decrypt method before saving or retriving from SharedPreference 
  • Prevención de la piratería de la aplicación android
  • Comprobar si el sistema de archivos Android está encriptado
  • Proguarding Android Apps - lo esencial es (especialmente en relación con los pagos en la aplicación)
  • CSRF en aplicaciones móviles
  • Android Keystore - ¿se puede recuperar una clave de usuario por root si se establece en ese usuario?
  • ¿Cómo funciona la aplicación de instalación de AppBrain?
  • Problema de seguridad del diccionario de palabras de Android
  • Esquema de autenticación para una aplicación de Android: cuando la tarjeta SIM está bloqueada o cambiada por otra, la aplicación deja de funcionar
  • Cómo ocultar la clave pública en android?
  • Herramienta de análisis de código fuente estático de código abierto (orientada a la seguridad) para Java
  • Protección de bases de datos SQLite locales (aplicación Android)
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.