web-dev-qa-db-fra.com

Comment crypter un fichier depuis une carte SD en utilisant AES dans Android?

Je veux crypter l'image de la carte SD et la stocker à nouveau sur la carte SD en utilisant AES. L'idée principale est que l'application parcourt une image, puis la crypte lorsque je pousse un bouton, puis la stocke sur une carte SD. donc mon image serait en sécurité.

J'ai déjà réussi à chiffrer des chaînes en utilisant AES à partir de ce tutoriel http://www.androidsnippets.com/encryptdecrypt-strings , mais je ne sais pas comment faire cela avec une image, pas une chaîne.

Voici comment je le fais avec une chaîne:

public static String encrypt(String seed, String cleartext) throws Exception  
{
    byte[] rawKey = getRawKey(seed.getBytes());
    byte[] result = encrypt(rawKey, cleartext.getBytes()); 
    return toHex(result);
}

private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception 
{
    SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
    byte[] encrypted = cipher.doFinal(clear);
    return encrypted;
}

Quelqu'un peut-il m'aider à donner un exemple de code pour chiffrer une image avec AES?

peut-être qu'il doit utiliser le flux de fichiers d'E/S mais je n'ai aucune idée de la façon de l'implémenter avec ce code.

34
user1421273

Si vous prenez l'entrée d'utilisateur pour le mot de passe, assurez-vous de lire cette réponse .

Vous devriez jeter un œil à: CipherInputStream et CipherOutputStream . Ils sont utilisés pour crypter et décrypter les flux d'octets.

J'ai un fichier nommé cleartext. Le fichier contient:

Hi, I'm a clear text.
How are you?
That's awesome!

Maintenant, vous avez une fonction encrypt():

static void encrypt() throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
    // Here you read the cleartext.
    FileInputStream fis = new FileInputStream("data/cleartext");
    // This stream write the encrypted text. This stream will be wrapped by another stream.
    FileOutputStream fos = new FileOutputStream("data/encrypted");

    // Length is 16 byte
    // Careful when taking user input!!! https://stackoverflow.com/a/3452620/1188357
    SecretKeySpec sks = new SecretKeySpec("MyDifficultPassw".getBytes(), "AES");
    // Create cipher
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.ENCRYPT_MODE, sks);
    // Wrap the output stream
    CipherOutputStream cos = new CipherOutputStream(fos, cipher);
    // Write bytes
    int b;
    byte[] d = new byte[8];
    while((b = fis.read(d)) != -1) {
        cos.write(d, 0, b);
    }
    // Flush and close streams.
    cos.flush();
    cos.close();
    fis.close();
}

Après avoir exécuté cette fonction, il devrait y avoir un nom de fichier encrypted. Le fichier contient les caractères cryptés.

Pour le déchiffrement, vous avez la fonction decrypt:

static void decrypt() throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
    FileInputStream fis = new FileInputStream("data/encrypted");

    FileOutputStream fos = new FileOutputStream("data/decrypted");
    SecretKeySpec sks = new SecretKeySpec("MyDifficultPassw".getBytes(), "AES");
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.DECRYPT_MODE, sks);
    CipherInputStream cis = new CipherInputStream(fis, cipher);
    int b;
    byte[] d = new byte[8];
    while((b = cis.read(d)) != -1) {
        fos.write(d, 0, b);
    }
    fos.flush();
    fos.close();
    cis.close();
}

Après l'exécution de déchiffrement, il devrait y avoir un fichier nommé decrypted. Ce fichier contient le texte libre.

Vous écrivez que vous êtes un "noob" mais selon le cas d'utilisation du chiffrement, vous pourriez faire beaucoup de mal si vous ne le faites pas correctement. Connaissez vos outils!

Utilisation de CipherOutputStream documentation Oracle :

SecretKeySpec skeySpec = new SecretKeySpec(y.getBytes(), "AES");

FileInputStream fis;
FileOutputStream fos;
CipherOutputStream cos;
// File you are reading from
fis = new FileInputStream("/tmp/a.txt");
// File output
fos = new FileOutputStream("/tmp/b.txt");

// Here the file is encrypted. The cipher1 has to be created.
// Key Length should be 128, 192 or 256 bit => i.e. 16 byte
SecretKeySpec skeySpec = new SecretKeySpec("MyDifficultPassw".getBytes(), "AES"); 
Cipher cipher1 = Cipher.getInstance("AES");  
cipher1.init(Cipher.ENCRYPT_MODE, skeySpec);
cos = new CipherOutputStream(fos, cipher1);
// Here you read from the file in fis and write to cos.
byte[] b = new byte[8];
int i = fis.read(b);
while (i != -1) {
    cos.write(b, 0, i);
    i = fis.read(b);
}
cos.flush();

Ainsi, le cryptage devrait fonctionner. Lorsque vous inversez le processus, vous devriez pouvoir lire les octets déchiffrés.

65
Kiril