Bonjour à tous,

j'ai un soucis avec le chiffrement sous Android, j'aimerai chiffrer les mots de passes en TripleDES avec un vecteur de génération basé sur PBKDF2.

Ma solution fonctionne uniquement sur Android 4.3 et les versions supérieurs, tandis que sur Android 4.2 et moins le mot de passe chiffré est incorrect et aléatoire.

Voici mon code :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
private static final String KEY = "a2[..]";
private static final String SALT = "t[..]";
private static final String IV = "u[..]";
private static final String DES_EDE_PKCS5 = "DESede/CBC/PKCS5Padding"
 
public static String encrypt(String password) {
    byte[] byteSalt = Base64.decode(SALT, Base64.DEFAULT);
    byte[] bytesIv = Base64.decode(IV, Base64.DEFAULT);
    String mdp = "";        
    try {           
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");          
        KeySpec spec = new PBEKeySpec(KEY.toCharArray(), byteSalt, NB_ITER_RFC, SIZE_KEY);          
        SecretKey secretKey = factory.generateSecret(spec);             
        Cipher c = Cipher.getInstance(DES_EDE_PKCS5);           
        IvParameterSpec ivParam = new IvParameterSpec(bytesIv);         
        c.init(Cipher.ENCRYPT_MODE, secretKey, ivParam);                
        byte[] encrypted = c.doFinal(password.getBytes("UTF-8"));
        mdp = Base64.encodeToString(encrypted, Base64.DEFAULT);                 
    }
    catch [..]
    return mdp;
}
ça c'est une autre solution avec la librairie Bouncy Castle (le résultat est identique) :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
PBEKeySpec pbeKeySpec = new PBEKeySpec(PASSWORD.toCharArray(), byteSalt, NB_ITER_RFC, SIZE_KEY);
byte[] key2 = PBEParametersGenerator.PKCS12PasswordToBytes(pbeKeySpec.getPassword());
SecretKey temp2 = factory.generateSecret(pbeKeySpec);
Cipher c2 = Cipher.getInstance(DES_EDE_PKCS5);
c2.init(Cipher.ENCRYPT_MODE, temp2, ivParam);
byte[] encrypted2 = c2.doFinal(texteAChiffrer.getBytes("UTF-8"));       
mdp = Base64.encodeToString(encrypted2, Base64.DEFAULT);

Sur Android 4.2 et moins pour un même mot de passe, la fonction de chiffrement va tout le temps sortir un mot de passe chiffré aléatoirement comme ceci :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
D/andro-Chiffrement-encrypt(10739): password chiffré = P7vWc+7hFuUaWQghVeO+zA==
D/andro-Chiffrement-encrypt(10739): password chiffré = jGr6nlvnYLd/AK/d7nkUrA==
D/andro-Chiffrement-encrypt(10739): password chiffré = I2weyEddIav7EulAiuQDbg==
D/andro-Chiffrement-encrypt(10739): password chiffré = HF7OFpUXYuwOm81WekReDg==

Je suis tombé sur ce post du blog d'Android Developers: http://android-developers.blogspot.f...-thoughts.html

Où apparemment à partir d'Android 4.3 la génération de nombre pseudo aléatoire serait buggé, il conseille d'intégrer la classe "PRNGFixes" qui permet de résoudre cela, c'est ce que j'ai fait, j'ai pris soin d'appeler le "PRNGFixes.apply();" dans le onCreate() de ma classe qui "extends Application" je l'ai bien notifié dans mon "Manifest.xml" (<application android:name="UILApplication" [..])

Mais même avec "PRNGFixes" cela ne change strictement rien...

j'ai testé de changer le répertoire "dev/urandom" par "dev/random" pour voir si ça changeait quelque-chose. Le résultat c'est que ça freeze, écran noir que c'est une opération bloquante (http://fr.wikipedia.org/?title=/dev/random)

En tout cas, une chose est sûr, c'est que le problème vient de l'OS sur la génération des nombres pseudo aléatoire, Je voulais donc savoir si quelqu'un aurait une idée pour contourner ce problème ?


Merci d'avance :-)