Asegurar archivos multimedia en el móvil

Estoy pensando en desarrollar un catálogo de aves para Android. Contendrá muchas imágenes y archivos de audio. Todos esos archivos vienen de una compañía de terceros con derechos de autor.

Mi aplicación debe asegurar (tanto como sea posible) que esos archivos multimedia no sean accesibles, copiados o manipulados.

¿Qué estrategias podría seguir? Crypt archivos en el sistema de archivos y descifrar en la memoria antes de mostrar o jugar? Mantenerlos en SQL Lite como CLOBs? ¿Es SQL Lite accesible desde otras aplicaciones o está oculto para el resto de aplicaciones? ¿Alguna otra idea? No he encontrado demasiada información sobre este "problema" en la web.

Gracias por adelantado,

Chemi.

Sugiero guardar estos archivos en la tarjeta SD, no en el archivo privado de tu actividad, ya que las imágenes / archivos de audio suelen ser bastante grandes (he visto en esta discusión que estás planeando manejar 400 MB, ¿es la misma aplicación? ). Así que la criptación debería estar bien, y más sencilla que SQLite.

La clase a continuación permite cifrar los bytes de los archivos binarios:

import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.security.SecureRandom; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; public class AESEncrypter { public static void encryptToBinaryFile(String password, byte[] bytes, File file) throws EncrypterException { try { final byte[] rawKey = getRawKey(password.getBytes()); final FileOutputStream ostream = new FileOutputStream(file, false); ostream.write(encrypt(rawKey, bytes)); ostream.flush(); ostream.close(); } catch (IOException e) { throw new EncrypterException(e); } } public static byte[] decryptFromBinaryFile(String password, File file) throws EncrypterException { try { final byte[] rawKey = getRawKey(password.getBytes()); final FileInputStream istream = new FileInputStream(file); final byte[] buffer = new byte[(int)file.length()]; istream.read(buffer); return decrypt(rawKey, buffer); } catch (IOException e) { throw new EncrypterException(e); } } private static byte[] getRawKey(byte[] seed) throws EncrypterException { try { final KeyGenerator kgen = KeyGenerator.getInstance("AES"); final SecureRandom sr = SecureRandom.getInstance("SHA1PRNG"); sr.setSeed(seed); kgen.init(128, sr); // 192 and 256 bits may not be available final SecretKey skey = kgen.generateKey(); return skey.getEncoded(); } catch (Exception e) { throw new EncrypterException(e); } } private static byte[] encrypt(byte[] raw, byte[] clear) throws EncrypterException { try { final SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); final Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, skeySpec); return cipher.doFinal(clear); } catch (Exception e) { throw new EncrypterException(e); } } private static byte[] decrypt(byte[] raw, byte[] encrypted) throws EncrypterException { SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); try { final Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.DECRYPT_MODE, skeySpec); return cipher.doFinal(encrypted); } catch (Exception e) { throw new EncrypterException(e); } } 

}

También necesitará esta clase de excepción:

 public class EncrypterException extends Exception { public EncrypterException ( ) { super( ); } public EncrypterException (String str ) { super(str); } public EncrypterException (Throwable e) { super(e); } } 

A continuación, sólo tiene que utilizar lo siguiente para generar archivos cifrados:

 encryptToBinaryFile("password", bytesToSaveEncrypted, encryptedFileToSaveTo); 

Y en tu aplicación, puedes leerlos de la siguiente manera:

 byte [] clearData = decryptFromBinaryFiles("password", encryptedFileToReadFrom); 

Para usar una contraseña hardcoded puede ser hackeado cavando en el código ofuscado y buscando cadenas. No sé si esto sería un nivel de seguridad suficiente en su caso?

De lo contrario, puede almacenar la contraseña en las preferencias privadas de su Actividad o mediante trucos como this.class.getDeclaredMethods () [n] .getName () como contraseña. Esto es más difícil de encontrar.

Acerca de las actuaciones, usted tiene que saber que la criptación / descifrado puede tomar bastante tiempo. Esto requiere algunas pruebas.

[EDIT: 04-25-2014] Hubo un gran error en mi respuesta. Esta implementación está sembrando SecureRandom , que es malo ('mal', dirían algunos).

Hay una manera fácil de evadir este problema. Se explica en detalle aquí en el blog de desarrolladores de Android. Lo siento por eso.

Problema similar he resuelto utilizando BLOBs SQLite. Puedes probar la aplicación en AndroidMarket

De hecho, estoy guardando archivos multimedia en una serie de BLOBs. SQLite soporta BLOB hasta 2 gigs , pero debido a las limitaciones de Android me vi obligado a fragmentar archivos a 4 meg BLOBs.

El resto es fácil.

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.