Folder Permission Only for the Android Application

3

Can you make files in a folder on sdcard only accessible by the application? (something like chown and chmod) Not necessarily reading but preventing removal and editing through other applications (eg explorer). Dismiss devices with root

    
asked by anonymous 19.09.2014 / 09:24

1 answer

3

There is a viable solution if you want to save (possibly large) files to 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 comments ), and use it to encrypt / decrypt the files you want to protect. So you take advantage of the abundance of space that sdcard offers without having to spend too much space on your application (a symmetric encryption key like AES takes up only 32 bytes).

This question in SOen shows you ways to do this. If you decide to follow it, pay close attention to the comments of the owlstead user - it may be that the responses quoted (including the accepted ones) are not secure / trusted implementations. I do not know enough to say so, but the warning is there ... (he seems to know what he's talking about, unlike me, I'm a layman on the subject)

This other answer , on the other hand, seems to take good care of all the details (correct key derivation, correct operation, correct encoding ), so that it can be a viable medium. It's not specific to Android, though, 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 provide the user with a means of backing up the encryption key, or the password used to derive it (if any). Otherwise, if there is a problem with the device and the application and / or its data is lost, the user loses access to all their files.

One way to do this is by using a strong / strong password / key that the user only has to enter once when installing the application and / or back up, and from there it is saved in the restricted area of the application. A simpler password or PIN is used on a day-to-day basis for user authentication.

Motivation

Think of a sdcard as 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 can not depend on any protection offered by the operating system. He needs to protect himself.

(This is a case analogous to getting a system with Unix / Linux, taking the HD and putting it on another computer with a different OS - there is no guarantee that this OS will honor the access permissions. let any user access anything ...)

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

  

Disclaimer: I have no hands-on experience with Android development, but by my understanding of this security reference all leads me to believe that this is a viable path. For devices without root , of course, as requested in the question.

    
19.09.2014 / 20:45