Folder permission only for Android application

How do I get files from a folder on sdcard to be accessed only by the application? (something like chown and chmod) Not necessarily reading, but prevent removal and editing through other applications (ex: explorer). Disregard devices with Root

Author: ramaral, 2014-09-19

1 answers

There is a workable solution if you want to save (possibly large) files on your sdcard and still make them accessible exclusively to your application: generate an encryption key in your application, save it inside the application itself ( as suggested by Jorge B. in the comments ), and use it to encrypt/decrypt the files you want to protect. Thus, you at the same time take advantage of the abundance of space that sdcard offers, without having to overspend the space limited that your application has (a symmetric encryption key, like AES, takes up only 32 bytes).

This question in Soen shows ways to do this. If you decide to follow it, pay close attention to owlstead's user comments - it may be that the answers cited (including the one you accept) are not safe/reliable implementations. I don't have enough knowledge to give my opinion, but there's the warning... (he seems to know well what he's talking about, unlike me, who I am semi-lay in the subject)

This other answer , on the other hand, seems to take good care of all the details (correct key derivation, correct mode of operation, treatment of encoding correct), so that can be a viable means. It is not specific Pro Android, however, but for Java in general - which at first should not be a problem. I will transcribe it here, adapting and commenting:

/** Cria a chave para ser usada na cifragem/decifragem
 *  @param senha A senha mestra. Secreta. Ficará salva junto ao aplicativo, não precisando
 *               ser digitada pelo usuário (deve ser longa). Precisa de um meio de backup.
 *  @param sal 8 bytes aleatórios. Não necessariamente secreto. Ficará salvo junto ao
 *             aplicativo. Precisa constar no backup, junto com a senha.
 *  @returns A chave secreta. Pode-se salvar ela, ou o par senha/sal, seu critério.
 */
SecretKey obterChave(String senha, byte[] sal) {
    SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
    KeySpec spec = new PBEKeySpec(senha, sal, 65536, 256);
    SecretKey tmp = factory.generateSecret(spec);
    return new SecretKeySpec(tmp.getEncoded(), "AES");
}

/* Para cifrar um texto, usando a chave gerada anteriormente. */
byte[][] cifrarTexto(SecretKey chave, String texto) {
    return cifrarDados(chave, texto.getBytes("UTF-8")); // Sempre o mesmo encoding
}

/* Para cifrar um arquivo binário, usando a chave gerada anteriormente. */
byte[][] cifrarDados(SecretKey chave, byte[] dados) {
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, chave);
    AlgorithmParameters params = cipher.getParameters();

    // O IV (Vetor de Inicialização) não é secreto, mas tem de ser diferente pra cada
    // arquivo que for cifrado. Ele é gerado automaticamente pela biblioteca.
    byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV();
    byte[] cifra = cipher.doFinal(dados);

    return new byte[][] { cifra, iv }; // Ambos são necessários para decifrar! Salve-os.
}

/* Para decifrar um texto, usando a chave gerada anteriormente. */
String decifrarTexto(SecretKey chave, byte[][] cifraIV) {
    return new String(decifrarDados(chave, cifraIV), "UTF-8"); // Sempre o mesmo encoding
}

/* Para decifrar um arquivo binário, usando a chave gerada anteriormente. */
byte[] decifrarDados(SecretKey chave, byte[][] cifraIV) {
    byte[] iv = cifraIV[1];
    byte[] cifra = cifraIV[0];

    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.DECRYPT_MODE, chave, new IvParameterSpec(iv));
    return cipher.doFinal(cifra);
}

Care

It is important to offer the user a means of making backup of the encryption key, or the password used to derive it (if any). Otherwise, if there is any problem with the device and the application and / or its data is lost, the user loses access to all its files.

One way to do this is by using a password/Master Key - strong - that the user only has to type once when installing the application and/or backing up, and from there it is saved in the restricted area of the application. One more password simple or PIN is used in day-to-day, for user authentication.

Motivation

Think of an sdcard as what it is: an external storage device . Being External, it is common and predicted that it will be decoupled from one machine and coupled to the other - so that it cannot depend on any protection offered by the operating system. He needs to protect himself.

(this is an analogous case to you take a Unix / Linux system, take the HD and put it on another computer with a different OS - there is no guarantee that this OS will honor access permissions. It can let any user access anything...)

The solution default for this case is encryption. And it comes with all the " pitfalls " and " gotchas" you might expect - the main one being the importance of making backup of the key. What is the best way to do this backup , there is no way to to put it generically: it is a balance between confidentiality and availability. But whatever you do, the important thing is that you do!

Disclaimer: I have no practical experience with Android development, but from my understanding of this security Reference Everything leads me to believe that this is a viable path. For appliances without root , of course, as requested in the question.

 3
Author: mgibsonbr, 2017-05-23 12:37:27