Cómo cifrar y descifrar archivos en Android?

Quiero encriptar 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 secuencia de archivos y cifrar, pero no está funcionando. Quiero alguna idea sobre cómo hacer esto.

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

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 textos no aleatorios . Debe estar presente en cualquier biblioteca criptográfica genérica, lo que garantiza una alta compatibilidad.

No olvide utilizar un Vector de Inicialización (IV) generado por un generador aleatorio seguro si desea encriptar múltiples archivos con la misma clave. Puede prefijar el IV plano al comienzo del texto cifrado. Siempre tiene 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 el cifrado basado en contraseña o la derivación de clave basada en contraseña). PBKDF2 es el esquema de derivación de clave basado en contraseña más comúnmente 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 un poco obsoleta, pero debería estar bien en PBKDF2, y actualmente presenta la opción más compatible.

Siempre especifique la encoding de caracteres cuando codifique / descodifique cadenas, o tendrá problemas cuando la encoding de la plataforma sea diferente a la anterior. En otras palabras, no use String.getBytes() pero use String.getBytes(Charset.forName("UTF-8")) .

Para hacerlo más seguro, agregue la integridad criptográfica y la autenticidad agregando una sum de comprobación segura (MAC o HMAC) sobre el texto cifrado y IV, preferiblemente con una clave diferente. Sin una etiqueta de autenticación, el texto cifrado se puede cambiar de tal forma que no se pueda detectar el cambio.

Tenga en cuenta que CipherInputStream puede no informar BadPaddingException , ¡esto incluye BadPaddingException generada para cifrados autenticados!

Tuve un problema similar y para cifrar / descifrar surgió 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 encriptado a 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 use:

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

Para leer en un archivo en una matriz de bytes hay una salida diferente. Un ejemplo: http://examples.javacodegeeks.com/core-java/io/fileinputstream/read-file-in-byte-array-with-fileinputstream/

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

Tenemos el mismo problema, y ​​alguien lo resuelve en mi hilo de preguntas. Debería echarle un vistazo a: CipherInputStream y CipherOutputStream. Se usan para cifrar y descifrar flujos de bytes. para obtener el código fuente detallado, consulte la respuesta de Kiril en este enlace: ¿Cómo cifrar el archivo de la tarjeta SD usando AES en Android?

Tuve el mismo problema, obtuve 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; }