2009-03-14 5 views
6

Nos applications Web ont des comptes utilisateur liés aux utilisateurs avec les mots de passe spécifiés lors de la création du compte. Dans le cas de Java, comment traiter le mot de passe de manière sécurisée, avant de persister dans la base de données? Pour être plus précis, comment s'assurer que la chaîne contenant le mot de passe est récupérée dans un intervalle de temps suffisamment court?Comment stocker un mot de passe de hachage sécurisé en mémoire, lors de la création de comptes?

+0

Cela pourrait aider à la sécurisation du mot de passe lors du processus d'enregistrement. Http://www.wheelersoftware.com/articles/spring-security-hash-salt-passwords.html –

Répondre

6

Si vous avez la possibilité (peut être difficile dans les applications Web), il serait préférable de stocker les mots de passe dans les tableaux de caractères que de les stocker dans des chaînes. Si vous avez terminé le stockage du mot de passe, vous pouvez le remplacer dans la mémoire à l'aide Array.fill() et faire la référence disponible pour le collecteur d'ordures par les jeter:

Arrays.fill(password, ' '); 
password = null; 

Je viens de remarquer que annulant le mot de passe serait un peu paranoïaque, mais vous pouvez faire si cela vous rassure :)

+0

Si cela est possible dans une application Web - lisez le mot de passe du flux d'entrée de la servlet dans un tableau d'octets, puis remplissez le tableau avec des zéros après la persistance du mot de passe, il devrait s'avérer être une approche viable. Le projet Java OWASP l'utilise dans un exemple, mais pas pour les mots de passe persistants. –

+2

Cela ne nécessite-t-il pas que le garbage collector ne compacte pas la pile et laisse donc une copie du tableau ailleurs dans la mémoire? –

+1

@KeeperOfTheSoul: Oui, cela dépend finalement du comportement du GC. Cela dépend également si le tableau sera sérialisé ou non. Dans l'ensemble, j'ai souhaité que Java ait une classe SecureString similaire à celle de Microsoft .Net. –

4

Si vous créez le hachage côté client, vous ne devriez pas avoir à penser à ce problème. Le mot de passe brut n'est jamais soumis au serveur.

+0

Oui, c'est une bonne approche, mais ne serait-ce pas aussi laisser attaquants avec la possibilité d'étudier l'algorithme de hachage en cours d'utilisation? Certes, c'est de la sécurité par l'obscurité d'une certaine manière, mais cela limite la quantité d'informations à la disposition de l'attaquant sur la façon dont les mots de passe sont stockés. –

+0

Ce serait une option, mais un attaquant ne pourrait-il pas intercepter aussi le hachage généré par le client, puis générer à nouveau la même requête HTTP pour se connecter? –

+0

@Markus, HTTPS est toujours utilisé, donc la probabilité d'une attaque MITM est faible ou nulle. –

2

Deux mots: portée locale. Les variables déclarées pour le traitement du mot de passe doivent avoir la plus petite portée absolue possible. Une fois que les variables sont hors de portée, les objets sont éligibles pour la récupération de place.

Souvent, vous choisissez des choses à partir d'une demande. Vous voulez une très, très petite transaction qui accepte la demande, hache le mot de passe, persiste et redirige. La page vers laquelle vous redirigez peut ensuite récupérer du contenu et effectuer tous les autres traitements faisant partie de votre application.

1

Il n'existe aucun moyen de garantir que les mots de passe en clair sont supprimés de la mémoire en Java.

Toutefois, un pirate n'a pas besoin d'accéder à la mémoire d'un programme pour obtenir des mots de passe en texte clair. Il existe des moyens beaucoup plus simples (comme renifler les paquets), il est donc hautement improbable que quiconque se fie à cette approche. La meilleure approche consiste à demander au client de chiffrer le mot de passe comme le suggère @ Mork0075. Cependant, même si cela signifie que vous ne pouvez pas facilement obtenir le mot de passe, un programme peut toujours obtenir la version cryptée des mots de passe et ainsi prétendre être un utilisateur. Un moyen de contourner cela est de crypter toute la connexion en utilisant le protocole SSL. Tout cela est plutôt académique, car l'approche la plus simple pour un hacker est de surveiller les paquets dans la base de données et d'obtenir le mot de passe pour votre base de données. Je soupçonne que l'accès direct à votre base de données est plus préoccupant ... ou peut-être pas. ;)

+0

Je cherche à protéger les mots de passe, pas parce qu'un attaquant tenterait cette approche - la boîte a été compromise s'il est capable de jeter un coup d'œil dans la mémoire, donc il y a de plus grandes choses à s'inquiéter. Je cherche à empêcher les mots de passe d'apparaître dans un vidage de tas Java obtenu pour le diagnostic. –

0

Utilisez un défi de mot de passe:

  1. Server choisit une valeur de défi et l'envoie au client
  2. Serveur effectue une traduction à sens unique avec le mot de passe et le défi, par ex. MD5(CONCAT(challenge, password)) et l'affecte à la session.
  3. Le mot de passe en texte brut est maintenant hors de portée et prêt pour la récupération de place.
  4. Le client effectue également la même traduction et envoie le résultat au serveur.
  5. Si le serveur et le client choisissent la même valeur finale, le client est authentifié.

Cette méthode empêche les attaques par rejeu , mais exige que la valeur défi être très imprévisible (aléatoire) et pas souvent réutilisé (long).

Le mot de passe en texte brut est uniquement dans la portée pendant le traitement de la demande de connexion initiale - pas pendant l'authentification. Peu importe combien de temps le résultat de la traduction unidirectionnelle est dans la portée (pas ramassé) parce qu'il a peu de valeur de rejeu.

+0

Cela fonctionnerait bien pour le processus de connexion, mais l'auteur a demandé l'enregistrement d'un compte, de sorte que vous devez également stocker une valeur de hachage dans une base de données. Ce hachage ne peut pas être généré via une valeur de challenge car il n'a pas pu être restauré lors de la connexion. –

5

Vous n'utilisez pas de chaîne. Vous utilisez un char [] et écrasez le caractère [] lorsque vous avez terminé.

Il n'y a absolument aucune garantie quand il s'agit de garbage collection (mis à part que le finaliseur sera exécuté avant la collecte de l'objet). Le GC peut ne jamais fonctionner, s'il s'exécute il ne peut jamais GC la chaîne qui a le mot de passe dedans.

Questions connexes