Utiliser char[]Tableau sur une chaîne pour manipuler les mots de passe en Java?

Utilisez char [] Tableau sur une chaîne pour manipuler les mots de passe en Java?

1. Vue d'ensemble

Dans cet article, nous expliquerons pourquoi nous devrions utiliser le tableauchar[] pour représenter les mots de passe au lieu deString en Java.

Veuillez noter que ce tutoriel se concentre sur les façons de manipuler les mots de passe dans la mémoire, et non sur les façons réelles de les stocker, qui sont généralement gérées dans la couche de persistance.

Nous supposons également que nous ne pouvons pas contrôler le format du mot de passe (par ex. le mot de passe provient de l'API tierce sous la forme deString). Bien qu'il semble évident d'utiliser des objets de typejava.lang.String pour manipuler les mots de passe, il est recommandé par l'équipe Java elle-même d'utiliserchar[] à la place.

Par exemple, si nous regardons lesJPasswordField dejavax.swing, nous pouvons voir que la méthodegetText() qui retourneString est obsolète depuis Java 2 et est remplacée pargetPassword() méthode qui renvoiechar[].

Alors, explorons quelques bonnes raisons pour lesquelles c'est le cas.

2. Les chaînes sont immuables

Strings en Java sont immuables, ce qui signifie que nous ne pouvons pas les modifier en utilisant des API de haut niveau. Tout changement sur un objetString produira un nouveauString, gardant l'ancien en mémoire.

Par conséquent, le mot de passe stocké dans unString sera disponible en mémoire jusqu'à ce que Garbage Collector l'efface. Nous ne pouvons pas contrôler le moment où cela se produit, mais cette période peut être beaucoup plus longue que pour les objets normaux puisqueStrings sont conservés dans un pool de chaînes à des fins de réutilisation.

Par conséquent, toute personne ayant accès au vidage de la mémoire peut récupérer le mot de passe de la mémoire.

Avec un tableauchar[] au lieu desString, nous pouvons explicitement effacer les données après avoir terminé le travail prévu. De cette façon, nous nous assurerons que le mot de passe est supprimé de la mémoire avant même le nettoyage de la mémoire.

Jetons maintenant un œil aux extraits de code, qui illustrent ce dont nous venons de parler.

D'abord pourString:

System.out.print("Original String password value: ");
System.out.println(stringPassword);
System.out.println("Original String password hashCode: "
  + Integer.toHexString(stringPassword.hashCode()));

String newString = "********";
stringPassword.replace(stringPassword, newString);

System.out.print("String password value after trying to replace it: ");
System.out.println(stringPassword);
System.out.println(
  "hashCode after trying to replace the original String: "
  + Integer.toHexString(stringPassword.hashCode()));

La sortie sera:

Original String password value: password
Original String password hashCode: 4889ba9b
String value after trying to replace it: password
hashCode after trying to replace the original String: 4889ba9b

Maintenant pourchar[]:

char[] charPassword = new char[]{'p', 'a', 's', 's', 'w', 'o', 'r', 'd'};

System.out.print("Original char password value: ");
System.out.println(charPassword);
System.out.println(
  "Original char password hashCode: "
  + Integer.toHexString(charPassword.hashCode()));

Arrays.fill(charPassword, '*');

System.out.print("Changed char password value: ");
System.out.println(charPassword);
System.out.println(
  "Changed char password hashCode: "
  + Integer.toHexString(charPassword.hashCode()));

La sortie est:

Original char password value: password
Original char password hashCode: 7cc355be
Changed char password value: ********
Changed char password hashCode: 7cc355be

Comme nous pouvons le voir, après avoir essayé de remplacer le contenu desString d'origine, la valeur reste la même et la méthodehashCode() n'a pas renvoyé une valeur différente dans la même exécution de l'application, ce qui signifie que le LesStringoriginaux sont restés intacts.

Et pour le tableauchar[], nous avons pu modifier les données dans le même objet.

3. Nous pouvons accidentellement imprimer des mots de passe

Un autre avantage de travailler avec des mots de passe dans le tableauchar[] est la prévention de la journalisation accidentelle du mot de passe dans les consoles, les moniteurs ou d'autres endroits plus ou moins non sécurisés.

Voyons le code suivant:

String passwordString = "password";
char[] passwordArray = new char[]{'p', 'a', 's', 's', 'w', 'o', 'r', 'd'};
System.out.println("Printing String password -> " + passwordString);
System.out.println("Printing char[] password -> " + passwordArray);

Avec la sortie:

Printing String password -> password
Printing char[] password -> [[email protected]

On voit que le contenu lui-même est imprimé dans le premier cas, tandis que dans le second cas, les données ne sont pas si utiles, ce qui rendchar[] moins vulnérable.

4. Conclusion

Dans cet article rapide, nous avons souligné plusieurs raisons pour lesquelles nous ne devrions pas utiliserStrings pour collecter les mots de passe et pourquoi nous devrions utiliser les tableauxchar[] à la place.

Comme toujours, des extraits de code peuvent être trouvésover on GitHub.