Como encriptar e descriptografar o arquivo no Android?

Quero encriptar o ficheiro e guardá-lo no cartão SD. Quero descodificar o ficheiro encriptado e guardá-lo no cartão SD outra vez. Eu tentei encriptar o arquivo abrindo como fluxo de arquivo e encriptar é, mas não está funcionando. Quero uma ideia de como fazer isto.

Author: twlkyao, 2010-11-25

5 answers

Usar um CipherOutputStream ou CipherInputStream com um Cipher e o seu FileInputStream / FileOutputStream.

Eu sugeriria algo como Cipher.getInstance("AES/CBC/PKCS5Padding") para criar a classe Cipher. O modo CBC é seguro e não tem as vulnerabilidades do modo BCE para os plantexts não aleatórios. Deve estar presente em qualquer biblioteca criptográfica genérica, garantindo alta compatibilidade.

Não se esqueça de usar um Vector de inicialização (IV) gerado por um secure Androide. Note que o SHA-1 é uma função de hash um pouco desatualizada, mas deve estar bem no PBKDF2, e atualmente apresenta a opção mais compatível.

Indique sempre a codificação de caracteres quando codificar/descodificar textos, ou terá problemas quando a codificação da plataforma for diferente da anterior. Por outras palavras, não utilize String.getBytes()String.getBytes(Charset.forName("UTF-8")).

Para torná-lo mais seguro, por favor adicione integridade criptográfica e autenticidade adicionando um checksum seguro (MAC ou HMAC) sobre o cifrotexto e IV, de preferência usando uma chave diferente. Sem uma etiqueta de autenticação, o cifrotexto pode ser alterado de tal forma que a alteração não possa ser detectada.

Aviso-te que CipherInputStream maio not report BadPaddingException, isto inclui BadPaddingException gerado para Cifras autenticadas!

 55
Author: Maarten Bodewes, 2017-05-23 12:10:34

Tive um problema semelhante e para encriptar/descriptografar arranjei esta solução:

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 gravar um ficheiro encriptado para o 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 descodificar um ficheiro usar:

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

Para ler em um arquivo para uma matriz de bytes lá uma maneira diferente lá fora. Um Exemplo: http://examples.javacodegeeks.com/core-java/io/fileinputstream/read-file-in-byte-array-with-fileinputstream/

 45
Author: ZeroTek, 2013-06-17 17:28:22

Use um fluxo de cifras ou Cifras com uma cifra e o seu fluxo de Ficheiros / fluxo de Ficheiros.

 -4
Author: shadab shah, 2012-06-04 03:15:47
Temos o mesmo problema, e é resolvido por alguém no meu tópico de perguntas. Devias dar uma vista de olhos ao "CipherInputStream" e ao "CipherOutputStream". Eles são usados para criptografar e descriptografar fluxos de bytes. para o código fonte detalhado confira a resposta do Kiril neste link: Como criptografar o arquivo a partir do cartão SD usando AES no Android?
 -5
Author: user1421273, 2017-05-23 11:54:53
Tive o mesmo problema, consegui a solução deste 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;
}
 -6
Author: Ankit Chaudhary, 2015-12-18 05:58:22