Cómo cifrar y descifrar archivos en Android?

Quiero cifrar el archivo y almacenarlo en la tarjeta SD. Quiero descifrar ese archivo cifrado y almacenarlo en la tarjeta SD de nuevo. He intentado cifrar el archivo abriendo como corriente del archivo y cifrar es pero no está trabajando. Quiero una idea sobre cómo hacer esto.

Utilice un CipherOutputStream o CipherInputStream con un Cipher y su FileInputStream / FileOutputStream .

Yo sugeriría algo como Cipher.getInstance("AES/CBC/PKCS5Padding") para crear la clase Cipher . El modo CBC es seguro y no tiene las vulnerabilidades del modo ECB para los plaintexts no aleatorios . Debe estar presente en cualquier biblioteca criptográfica genérica, garantizando una alta compatibilidad.

No olvide utilizar un vector de inicialización (IV) generado por un generador aleatorio seguro si desea cifrar varios archivos con la misma clave. Puede prefijar el IV plano al comienzo del texto cifrado. Siempre es exactamente un bloque (16 bytes) de tamaño.

Si desea utilizar una contraseña, asegúrese de utilizar un buen mecanismo de derivación de claves (consulte cifrado basado en contraseña o derivación de clave basada en clave). PBKDF2 es el esquema de derivación basado en contraseña más utilizado y está presente en la mayoría de los tiempos de ejecución de Java , incluido Android. Tenga en cuenta que SHA-1 es una función hash poco obsoleta, pero debería estar bien en PBKDF2, y actualmente presenta la opción más compatible.

Siempre especifique la codificación de caracteres al codificar / decodificar cadenas, o usted estará en problemas cuando la codificación de la plataforma difiere de la anterior. En otras palabras, no utilice String.getBytes() pero utilice String.getBytes(Charset.forName("UTF-8")) .

Para hacerlo más seguro, agregue integridad criptográfica y autenticidad añadiendo una suma de comprobación segura (MAC o HMAC) sobre el texto cifrado y IV, preferiblemente utilizando una clave diferente. Sin una etiqueta de autenticación, el texto cifrado puede cambiarse de tal manera que el cambio no pueda detectarse.

Tenga en cuenta que CipherInputStream puede no reportar BadPaddingException , esto incluye BadPaddingException generado para cifrados autenticados!

Tuve un problema similar y para cifrar / descifrar me vino con esta solución:

 public static byte[] generateKey(String password) throws Exception { byte[] keyStart = password.getBytes("UTF-8"); KeyGenerator kgen = KeyGenerator.getInstance("AES"); SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "Crypto"); sr.setSeed(keyStart); kgen.init(128, sr); SecretKey skey = kgen.generateKey(); return skey.getEncoded(); } public static byte[] encodeFile(byte[] key, byte[] fileData) throws Exception { SecretKeySpec skeySpec = new SecretKeySpec(key, "AES"); Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, skeySpec); byte[] encrypted = cipher.doFinal(fileData); return encrypted; } public static byte[] decodeFile(byte[] key, byte[] fileData) throws Exception { SecretKeySpec skeySpec = new SecretKeySpec(key, "AES"); Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.DECRYPT_MODE, skeySpec); byte[] decrypted = cipher.doFinal(fileData); return decrypted; } 

Para guardar un archivo cifrado en sd do:

 File file = new File(Environment.getExternalStorageDirectory() + File.separator + "your_folder_on_sd", "file_name"); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file)); byte[] yourKey = generateKey("password"); byte[] filesBytes = encodeFile(yourKey, yourByteArrayContainigDataToEncrypt); bos.write(fileBytes); bos.flush(); bos.close(); 

Para decodificar un archivo utilice:

 byte[] yourKey = generateKey("password"); byte[] decodedData = decodeFile(yourKey, bytesOfYourFile); 

Para la lectura en un archivo a un byte Array hay una manera diferente por ahí. Un ejemplo: http://examples.javacodegeeks.com/core-java/io/fileinputstream/read-file-in-byte-array-with-fileinputstream/

Utilice un CipherOutputStream o CipherInputStream con un cifrado y su FileOutputStream / FileInputStream.

Tuve el mismo problema, tengo la solución de este código.

 private static final String ALGO = "AES"; private static final byte[] keyValue = new byte[] { 'o', 'n', 'e', 'n','e', 't', 'e','d', 'o', 'c', 'e', 'i', 'r', 's', 'r', 'p' }; public static String decrypt(String encryptedData){ String decryptedValue = null; try{ Key key = generateKey(); Cipher c = Cipher.getInstance(ALGO); c.init(Cipher.DECRYPT_MODE, key); byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedData); byte[] decValue = c.doFinal(decordedValue); decryptedValue = new String(decValue); }catch(Exception e){ //LOGGER.error("In TD:" + e); //Teneno_StartupService.loadForConnectionFailed(); } return decryptedValue; } private static Key generateKey(){ Key key = new SecretKeySpec(keyValue, ALGO); return key; } 

Tenemos un mismo problema, y ​​su resuelto por alguien en mi hilo de la pregunta. Usted debe echar un vistazo a: CipherInputStream y CipherOutputStream. Se utilizan para cifrar y descifrar secuencias de bytes. Para ver el código fuente detallado Kiril respuesta en este enlace: ¿Cómo cifrar el archivo de la tarjeta SD con AES en Android?

  • Kotlin es más difícil de realizar ingeniería inversa que java
  • Seguridad de la carpeta de activos de Android
  • Licencia de aplicación vs protección contra copia en Android
  • Seguridad y autenticación cliente-servidor
  • Aplicación del sistema Android 101
  • ¿Qué tan seguros son los archivos SQLite y SharedPreferences en Android?
  • Android Keystore Tipo ¿cuál debo elegir?
  • Android - después de cargar URL con webview puedo cambiar el color de fondo
  • Android M - Llavero como almacenamiento para nombre de usuario / contraseña
  • ¿Puede mi aplicación Android imitar el intento del sistema?
  • Permitir que sólo mis aplicaciones Android ejecuten api de punto final en java
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.