Il y a quelques jours, je regardai le projet lancé par hackaday de faire un password keeper qui soit offline : Mooltipass
Je me suis dis que c’était quand même bien pratique et que j’en aurai bien besoin sur mon téléphone mobile. Comme ça faisait pas mal de temps que je n’avais pas développé sur Android, c’était l’occasion de réfléchir au plus gros problème que l’on retrouve sur les mobiles, ils ne disposent pas d’un espace sécurisé.
Vous pouvez récupérer l’application sur google play directement à cette adresse : Téléchargement
Le mécanisme de protection
Afin de réaliser ce projet, j’ai supposé que le mobile n’était pas vérolé à priori et qu’aucun touchlogger n’était présent sur celui ci.
En plus de cela, j’ai supposé que l’utilisateur été suffisamment doué pour choisir un mot de passe solide dont on peut sauvegarder le hash sans qu’il soit casser rapidement.
L’idée est donc de chiffrer l’ensemble des mots de passe de l’utilisateur en utilisant un secret que seul l’utilisateur connait.
Pour cela nous allons utiliser les API java cryptographiques et utiliser l’algorithme AES.
Afin de générer le secret pré partagé, nous allons utiliser une phrase secrete. Ce secret consiste en une phrase que seul l’utilisateur connait. Nous utiliserons alors une fonction de hashage pour générer la clé de chiffrement à partir de la phrase secrète de l’utilisateur. A cela nous ajoutons un salt, ceci permet de diversifier le secret pré partagé en fonction de son usage.
La fonction de diversification a été codé comme suis :
private byte[] diversify(String password, String salt) { password = password + salt; byte[] key = new byte[16]; MessageDigest sha1 = null; try { sha1 = MessageDigest.getInstance("SHA"); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } sha1.update(password.getBytes()); byte[] hash = sha1.digest(); System.arraycopy(hash, 0, key, 0, 16); return key; } |
Le stockage des données
Afin de stocker les données, nous allons transporter la clé dérivée pour la session courante et utiliser une base de données Android pour stocker les mots de passe. L’ensemble du contenu de la base de données est bien entendu chiffré avant insertion.
Chaque entrée est identifiée par les champs suivants :
public class PasswordReference { private int id; private String description; private String login; private String password; |
L’id est stocké en clair, pour les autres champs, nous utilisons un salt différents pour chacun.
Attaques possibles
La première attaque possible est de regarder par dessus l’épaule. Ainsi l’utilisateur récupère le secret pré partagé.
Une seconde attaque serait d’utiliser un key logguer. Afin de palier à ce genre d’attaque, il faudrait ajouter un deuxième paramètre dans la génération du secret pré partagé. Ce deuxième paramètre serait un code pin avec clavier dynamique. Ainsi un touchlogger deviendrait inefficace pour récupérer le code pin.
Cependant cette technique n’empêcherait pas de bruteforcer les solutions restantes et avec un code pin à 4 chiffres, ça ne fait que 10 000 essais.
L’attaque par bruteforce reste la dernière possible et celle ci peut être évitée à condition de choisir un mot de passe sure et de le changer régulièrement.
Sources
L’ensemble des sources de ce petit programme peut être télécharger sur github à l’adresse suivante : https://github.com/julien14/secretKeeper
Bien sur le programme est libre et sous licence GPL. Enjoy !