Question Pourquoi est-ce que char [] est préféré à String pour les mots de passe?


Dans Swing, le champ de mot de passe a un getPassword() (résultats char[]) au lieu de l'habituel getText() (résultats String) méthode. De même, j'ai trouvé une suggestion de ne pas utiliser String gérer les mots de passe

Pourquoi String constituer une menace pour la sécurité lorsqu'il s'agit de mots de passe? Il se sent gênant d'utiliser char[].


2894
2018-01-16 14:20


origine


Réponses:


Les cordes sont immuables. Cela signifie qu'une fois que vous avez créé le String, si un autre processus peut vider la mémoire, il n'y a aucun moyen (à part réflexion) vous pouvez vous débarrasser des données avant collecte des ordures coups de pied dans.

Avec un tableau, vous pouvez effacer explicitement les données une fois que vous avez terminé. Vous pouvez écraser le tableau avec tout ce que vous voulez, et le mot de passe ne sera pas présent dans le système, même avant la récupération de place.

Alors oui, ça est un problème de sécurité - mais même en utilisant char[] réduit seulement la fenêtre d'opportunité pour un attaquant, et c'est seulement pour ce type spécifique d'attaque.

Comme indiqué dans les commentaires, il est possible que les tableaux qui sont déplacés par le garbage collector laisseront des copies parasites des données en mémoire. Je crois que c'est spécifique à la mise en œuvre - le ramasse-miettes mai effacer toute la mémoire comme ça va, pour éviter ce genre de chose. Même si c'est le cas, il reste le temps pendant lequel char[] contient les caractères réels comme une fenêtre d'attaque.


3714
2018-01-16 14:26



Alors que d'autres suggestions semblent valables ici, il y a une autre bonne raison. Avec plaine String vous avez beaucoup plus de chances de l'impression accidentelle du mot de passe dans les journaux, des moniteurs ou un autre endroit dangereux. char[] est moins vulnérable.

Considère ceci:

public static void main(String[] args) {
    Object pw = "Password";
    System.out.println("String: " + pw);

    pw = "Password".toCharArray();
    System.out.println("Array: " + pw);
}

Impressions:

String: Password
Array: [C@5829428e

1078
2018-01-16 19:37



Pour citer un document officiel, le Java Cryptography Architecture guide dit cela à propos de char[] contre. String les mots de passe (à propos du chiffrement par mot de passe, mais il s'agit plus généralement de mots de passe bien sûr):

Il semblerait logique de collecter et stocker le mot de passe dans un objet   de type java.lang.String. Cependant, voici la mise en garde: Objects de   type String sont immuables, c'est-à-dire qu'il n'y a pas de méthodes définies   vous permet de changer (écraser) ou de mettre à zéro le contenu d'un String   après utilisation. Cette fonctionnalité fait String Objets impropres à   stocker des informations sensibles à la sécurité telles que des mots de passe d'utilisateur. Toi   devrait toujours collecter et stocker des informations sensibles de sécurité dans un    char tableau à la place.

Ligne directrice 2-2 des consignes de codage sécurisé pour le langage de programmation Java, version 4.0 dit aussi quelque chose de similaire (bien qu'il soit à l'origine dans le contexte de la journalisation):

Directive 2-2: Ne consignez pas d'informations très sensibles

Certaines informations, telles que les numéros de sécurité sociale (SSN) et   mots de passe, est très sensible. Cette information ne devrait pas être conservée   pour plus longtemps que nécessaire ni où il peut être vu, même par   administrateurs. Par exemple, il ne devrait pas être envoyé aux fichiers journaux et   sa présence ne devrait pas être détectable par des recherches. Certains transitoires   les données peuvent être conservées dans des structures de données mutables, telles que des tableaux char, et   effacé immédiatement après utilisation. La suppression des structures de données a réduit   l'efficacité sur les systèmes d'exécution Java typiques que les objets sont déplacés   mémoire transparente pour le programmeur.

Cette ligne directrice a également des implications pour la mise en œuvre et l'utilisation de   bibliothèques de niveau inférieur qui n'ont pas de connaissance sémantique des données   ils ont affaire à. À titre d'exemple, une analyse syntaxique de bas niveau   La bibliothèque peut enregistrer le texte sur lequel elle fonctionne. Une application peut analyser un SSN   avec la bibliothèque. Cela crée une situation où les SSN sont   disponible aux administrateurs ayant accès aux fichiers journaux.


610
2018-01-17 03:20



Tableaux de caractères (char[]) peut être effacé après utilisation en mettant chaque caractère à zéro et les chaînes non. Si quelqu'un peut en quelque sorte voir l'image de la mémoire, ils peuvent voir un mot de passe en texte brut si les chaînes sont utilisées, mais si char[] est utilisé, après avoir purgé les données avec 0, le mot de passe est sécurisé.


305
2018-01-16 14:27



Certaines personnes croient que vous devez remplacer la mémoire utilisée pour stocker le mot de passe une fois que vous n'en avez plus besoin. Cela réduit la fenêtre de temps qu'un attaquant doit lire le mot de passe de votre système et ignore complètement le fait que l'attaquant a déjà besoin d'un accès suffisant pour pirater la mémoire JVM pour faire cela. Un attaquant avec autant d'accès peut attraper vos événements clés rendant cela complètement inutile (AFAIK, alors s'il vous plaît corrigez-moi si je me trompe).

Mettre à jour

Merci aux commentaires, je dois mettre à jour ma réponse. Apparemment, il y a deux cas où cela peut ajouter une (très) mineure amélioration de la sécurité car cela réduit le temps qu'un mot de passe pourrait atterrir sur le disque dur. Pourtant, je pense que c'est trop pour la plupart des cas d'utilisation.

  • Votre système cible peut être mal configuré ou vous devez supposer qu'il est et vous devez être paranoïaque à propos des décharges de base (peut être valide si les systèmes ne sont pas gérés par un administrateur).
  • Votre logiciel doit être trop paranoïaque pour empêcher les fuites de données lorsque l'attaquant accède au matériel - en utilisant des choses comme TrueCrypt (interrompu), VeraCrypt, ou CipherShed.

Si possible, la désactivation des fichiers core et du fichier d'échange prend en charge les deux problèmes. Cependant, ils nécessiteraient des droits d'administrateur et pourraient réduire les fonctionnalités (moins de mémoire à utiliser) et tirer de la RAM d'un système en cours d'exécution serait toujours une préoccupation valable.


183
2018-01-16 14:32



  1. Les cordes sont immuables en Java si vous stockez le mot de passe en texte brut, il sera disponible en mémoire jusqu'à ce que Garbage Collector le supprime et comme Strings est utilisé dans String pool pour la réutilisation, il y a de fortes chances qu'il reste en mémoire pendant une longue durée. pose une menace de sécurité. Étant donné que toute personne ayant accès au vidage de la mémoire peut trouver le mot de passe en texte clair
  2. Recommandation Java en utilisant getPassword() méthode de JPasswordField qui retourne un caractère [] et est déconseillé getText() méthode qui renvoie le mot de passe en texte clair indiquant la raison de sécurité.
  3. toString () Il y a toujours un risque d'imprimer du texte brut dans un fichier journal ou une console mais si vous utilisez Array, vous n'imprimerez pas le contenu du tableau à la place de son emplacement mémoire.

    String strPwd = "passwd";
    char[] charPwd = new char[]{'p','a','s','s','w','d'};
    System.out.println("String password: " + strPwd );
    System.out.println("Character password: " + charPwd );
    

    Mot de passe string: passwd

    Mot de passe du personnage: [C @ 110b2345

Dernières pensées: Bien que l'utilisation de char [] ne soit pas suffisante, vous devez effacer le contenu pour le rendre plus sûr. Je suggère également de travailler avec un mot de passe haché ou crypté au lieu du texte brut et de l'effacer de la mémoire dès que l'authentification est terminée.


117
2017-12-27 20:22



Je ne pense pas que ce soit une suggestion valable, mais je peux au moins deviner la raison.

Je pense que la motivation est de vouloir s'assurer que vous pouvez effacer toute trace du mot de passe dans la mémoire rapidement et avec certitude après son utilisation. Avec un char[] vous pourriez écraser chaque élément du tableau avec un blanc ou quelque chose à coup sûr. Vous ne pouvez pas modifier la valeur interne d'un String de cette façon.

Mais cela seul n'est pas une bonne réponse; pourquoi ne pas simplement vous assurer une référence à la char[] ou String n'échappe pas? Ensuite, il n'y a pas de problème de sécurité. Mais la chose est que String les objets peuvent être intern()ed en théorie et maintenu vivant dans le pool constant. Je suppose en utilisant char[] interdit cette possibilité.


72
2018-01-16 14:27