Comment chiffrer et déchiffrer le fichier sous Android?

je veux crypter le fichier et le stocker dans la carte SD. Je veux décrypter ce fichier crypté et le stocker dans la carte SD à nouveau. J'ai essayé de chiffrer le fichier en ouvrant comme file stream et Crypt est, mais il ne fonctionne pas. Je veux une idée sur comment le faire.

55
demandé sur twlkyao 2010-11-25 12:09:07

5 réponses

utilisez un CipherOutputStream ou CipherInputStream avec un Cipher et votre FileInputStream / FileOutputStream .

je suggère quelque chose comme Cipher.getInstance("AES/CBC/PKCS5Padding") pour créer la classe Cipher . Le mode CBC est sécurisé et ne présente pas les vulnérabilités du mode ECB pour les textes non aléatoires . Il doit être présent dans tout produit générique bibliothèque cryptographique, assurant une grande compatibilité.

N'oubliez pas d'utiliser un vecteur D'initialisation (IV) généré par un générateur aléatoire sécurisé si vous voulez chiffrer plusieurs fichiers avec la même clé. Vous pouvez préfixer la simple IV Au début du cryptogramme. Il est toujours exactement un bloc (16 octets) dans la taille.

Si vous voulez utiliser un mot de passe, assurez-vous que vous utilisez une bonne clé mécanisme de dérivation (recherche de cryptage basé sur le mot de passe ou de dérivation de clé basée sur le mot de passe). PBKDF2 est le schéma de dérivation des clés basé sur Mot de passe le plus couramment utilisé et il est présent dans la plupart des temps D'exécution Java , y compris Android. Notez que SHA-1 est une fonction de hachage un peu dépassée, mais il devrait être parfait dans PBKDF2, et ne présente actuellement l'option la plus compatible.

spécifiez toujours l'encodage des caractères lors de l'encodage / décodage des chaînes, ou vous serez en difficulté lorsque l'encodage de la plate-forme diffère de la précédente. En d'autres termes, n'utilisez pas String.getBytes() mais utilisez String.getBytes(Charset.forName("UTF-8")) .

pour le rendre plus sûr, veuillez ajouter l'intégrité et l'authenticité cryptographiques en ajoutant un checksum sécurisé (MAC ou HMAC) sur le cryptogramme et IV, de préférence en utilisant une clé différente. Sans étiquette d'authentification, le cryptogramme peut être modifié de manière à ce que le changement ne puisse pas être détecté.

soyez averti que CipherInputStream peut pas rapport BadPaddingException , ce qui inclut BadPaddingException a généré pour les algorithmes de chiffrement authentifié!

55
répondu Maarten Bodewes 2017-05-23 12:10:34

j'ai eu un problème similaire et pour crypter/décrypter j'ai trouvé cette solution:

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;
    }

Pour enregistrer un fichier crypté à sd:

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();

décoder un fichier d'utilisation:

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

pour la lecture dans un fichier à un tableau d'octets là un chemin différent là-bas. Un exemple: http://examples.javacodegeeks.com/core-java/io/fileinputstream/read-file-in-byte-array-with-fileinputstream /

45
répondu ZeroTek 2013-06-17 17:28:22

utilisez un CipherOutputStream ou CipherInputStream avec un Cipher et votre FileOutputStream / FileInputStream.

-4
répondu shadab shah 2012-06-04 03:15:47

nous avons un même problème, et il est résolu par quelqu'un dans mon fil d'interrogation. Vous devriez juste jeter un oeil à: CipherInputStream et CipherOutputStream. Ils sont utilisés pour chiffrer et déchiffrer les flux d'octets. pour le code source détaillé, consultez la réponse de Kiril dans ce lien : comment chiffrer le fichier à partir de la carte SD en utilisant AES dans Android?

-5
répondu user1421273 2017-05-23 11:54:53

j'ai eu le même problème, j'ai eu la solution à partir de ce code.

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
répondu Ankit Chaudhary 2015-12-18 05:58:22