Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1345 connectés 

  FORUM HardWare.fr
  Programmation
  PHP

  Meilleure approche pour encryption/décryption de mot de passe

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Meilleure approche pour encryption/décryption de mot de passe

n°2265921
Krismu
Posté le 15-09-2015 à 23:06:03  profilanswer
 

Bonjour,
 
Voilà j'ai une application Java à laquelle l'utilisateur doit se logger avec son nom/mot de passe, rien de bien original. Quand il soumet le formulaire (Java toujours), une requête est faite à un serveur web qui retourne ok/pas ok etc...
 
Ma question est toute simple: comment je dois gérer la sécurité de tout ça pour que ce soit basique mais pas trop pourri.
 
- Sans chiffrage, le mot de passe est en clair dans les requêtes (http) et donc si on écoute le réseau on a le mot de passe.
- Avec un chiffrage côté client, il faut être capable soit de déchiffrer le mot de passe côté serveur, soit de comparer cette version chiffrée à la précédente enregistrée dans la DB (sachant que le chiffrage se doit de donner un résultat différent à chaque fois, sinon ça revient à avoir pas de chiffrage).
 
De plus quoi qu'on fasse côté client (chiffrage avec clé etc...), ce sera accessible via une "simple" décompilation du code Java (je sais pas si c'est toujours aussi facile que quelques années en arrière), et donc il sera facile de remonter au mot de passe en ayant intercepté les paquets réseau.
 
Je ne trouve pas de documentation lisible, je n'ai peut-être pas fait les bonnes recherches, mais je n'arrive que sur des sites qui parlent du sujet de manière très complexe, et je n'ai pas vraiment le temps de devenir expert en sécurité. Je pensais que des trucs simples et fonctionnels seraient trouvables comme souvent avec Java.
 
PS: Je parle pas mal de Java mais c'est un problème mixte Java/PHP et fallait choisir l'un des 2 ...
 
Merci de toute aide qui pourra m'aider à dégrossir cette partie de mon application.

mood
Publicité
Posté le 15-09-2015 à 23:06:03  profilanswer
 

n°2265922
Devil'sTig​er
Posté le 16-09-2015 à 00:09:02  profilanswer
 

Plusieurs approches, la plus classique:
 
Entre le client et le serveur (à configurer côté serveur):
- chiffrage systématique en HTTPS de tout ce qui transite entre un client et ton serveur. Ce qui évitera les attaques type "man in the middle". Il te faut acheter un certificat SSL auprès d'un presta de confiance, il y en a plein, les plus petits commencent vers 50€/an chez OVH ou gandi par ex. Les plus gros sont vers 1500€/an, chez verisign par exemple.
Tout dépend de ce dont tu as besoin comme garantie, ceux à 50€ souvent suffisent largement.
Pour les tests, tu peux chiffrer en local une clef perso, tu auras un message d'alerte de ton navigateur, mais rien d'autre (a éviter d'utiliser cette clef une fois le système mis en place avec de vrais clients)
 
Côté client:
- Rien à faire de spécial, le HTTPS est déjà là pour ca.
 
Côté serveur:
- Quand un client créé un compte, on hash son mot de passe, ya trois niveaux de sécurité assez classiques:
  - le plus sécure: on génère un salt pour chaque user, ce salt est stocké en BDD a côté du mot de passe hashé, il est unique et suffisamment random (il y a dans chaque languages de quoi obtenir des nombres randoms, genre SecureRandom en java), ne pas utiliser des nombres aléatoires classiques, souvent pas assez random justement...
  - le plus classique: un salt pour tous les utilisateurs, c'est le plus classique car celui qui offre le meilleur rendement vitesse/sécurité. Cela dit, si un mec s'attaque réellement à ton système, il peut se mettre à faire des rainbow table avec le salt, vu qu'il ne change pas, c'est donc plutôt pas si sécure que ca, vaut mieux celle du dessus si possible)
  - le plus risqué: on stocke le hash directement sans salt.
 
Rapidos en code ca donne (version sécure):

Code :
  1. $salt = super_hardcore_random_generator();
  2. $password = $_POST["password"];
  3. $hash = hash("sha256", $salt.$password);
  4. // On stocke $salt et $hash qui sont nécessaire pour le login


 
- Quand un utilisateur veut se logger:
  - le plus sécure: on récupère en BDD l'utilisateur qui a le bon loggin. On prend le mdp qu'il vient d'envoyer, on prend le salt venu de la BDD, et on créer le hash comme lors de la création de l'utilisateur, et compare avec le hash venu de la BDD. Si c'est ok, l'utilisateur est loggé.
  - le plus classique: on prend le mdp venu du client, on prend le salt "global", et on créer le hash, on test directement en BDD que l'on a un couple login/password qui va bien, on valide ou non en conséquence.
  - le plus risqué: on prend le mdp venu du client, on le hash, et on compare login/hash dans la base de données...
 
En code (version sécure):

Code :
  1. $login = $_POST["login"];
  2. $password = $_POST["password"];
  3. $user = sql("SELECT login, salt, password FROM user WHERE login = ? LIMIT 0,1", $login);
  4. $hash = hash("sha256", $user["salt"].$password);
  5. // En partant du principe que $user["password"] contient le hash précédemment calculé avec le salt plus haut
  6. if ($hash === $user["password"]) {
  7. }


 
Avantages divers:
 - HTTPS te garantis que, malgré que les données ne soit pas cryptés du côté de l'utilisateur, elles ne sont pas pour autant lisible jusqu'a l'arrivée à ton serveur (l'autre sens, du serveur au client, est tout aussi vrai).
 - un hash, a la particularité de détruire le mot de passe initial, et il n'est pas possible de revenir en arrière, donc, dans ta base de données, tu as une suite de lettres sur le mot de passe, dont personnes ne peut remonter au vrai mot de passe (ni toi/admin d'ailleurs). Ca garanti une bonne qualité.
 
POUR AUTANT, certaines personnes font ce que l'on appelle des rainbow tables: tu prends un algo de hash genre SHA1, et tu génères toutes les possibilités, genre SHA1("a" ), puis SHA1("b" ) et ainsi de suite. Ils stockent ce couple clef/valeur (donc ils stockents "a" = "ALDDMSD..." ), et ainsi de suite.
=> ca fait que si un utilisateur utilise un mot de passe trop court, ou trop facile à deviner, il est possible d'obtenir le mot de passe initial depuis le hash. Soit, pas du tout ce que tu souhaites.
 
Le salt, qu'il soit sécure ou non, sert pour ce point là. En rajoutant une suite de caractère random devant le mot de passe de l'utilisateur, le principe de la rainbow table s'effondre, car il est très dur de faire ca quand, même si l'utilisateur fournit un mot de passe à 1 caractère, le hash en réalité dérive de 10/20 caractères grace au salt que tu as mis devant le mdp...
 
 
 
Voila, avec ca t'a une base digne de ce nom ;)
 
Pour résumer:
- HTTPS entre le client et le serveur
- salt + stockage du hash(salt + password) en BDD, et avec ca tu as un truc qui fait face au attaques intermédiaire, et autres personnes qui pourraient voler la BDD et tenter de se faire passer pour certains utilisateurs.
 
Ah, et quand un utilisateur perd un mot de passe, tu regénères le salt et un nouveau mot de passe, et renvoi un joli mail avec le mot de passe déchiffré sans le salt bien sur ;)


Message édité par Devil'sTiger le 16-09-2015 à 00:17:07
n°2265938
Krismu
Posté le 16-09-2015 à 11:19:22  profilanswer
 

Merci pour cette réponse détaillée.
 
Ceci dit, côté client (une application Java destinée à tourner sous Android) je n'ai pas possibilité en l'état d'utiliser HTTPS (les librairies que j'utilise ne le font pas).
 
Est-ce qu'un chiffrage basé sur un truc style clé publique/clé privée a du sens dans mon cas ?

n°2265940
Devil'sTig​er
Posté le 16-09-2015 à 11:29:48  profilanswer
 

T'es sur que tu n'y a pas accès ?
 
https://developer.android.com/train [...] y-ssl.html
 
Maintenant le refaire, c'est vraiment, vraiment pas évident pour le coups, je serais toi, je tenterais de modifier mon code pour que ca devienne dispo:
- déjà une bibli qui le supporte pas, c'est bof,
- quand bien même elle a une raison précise pour ne pas le supporter, ça n'est pas une si bonne idée de refaire quelque chose à la mano...
 
Cela dit, il y a très longtemps j'avais eu un pb similaire, et pour le coup, impossible d'avoir HTTPS dans mon cas, je me souviens que j'y étais arrivé (non sans mal), en ré-implémentant une partie du protocole, mais ce fut tellement fastidieux (et pour le coup je pourrais pas t'aider, je sais pas ou est passé le code...).

n°2265941
Krismu
Posté le 16-09-2015 à 11:43:47  profilanswer
 

Je vais essayer d'utiliser les trucs d'Android qui ont l'air pas mal.
Là je travaille avec "LibGDX" qui fournit des helpers sympas pour HTTP mais rien (que j'ai trouvé en tout cas) pour HTTPS.
 
S'il faut faire avec d'autres trucs pour la partie login j'imagine que c'est mieux que de réinventer la roue. Je vais voir ça.
 
Merci

n°2265955
Devil'sTig​er
Posté le 16-09-2015 à 14:54:36  profilanswer
 

A première vue libdgx supporte bien HTTPS:
 
http://www.badlogicgames.com/forum [...] 11&t=19762
 
Mais il te faut un trusted certificate (donc un certificat payant). T'a une maigre chance avec par exemple StartSSL:
https://www.startssl.com/?lang=fr
 
Le soucis est le suivant; souvent les certificats payants sont ceux supportés (chaque device embarque une liste de certificats "roots" trusted), si pour une raison ton device a pas en "root" ceux de StartSSL, t'a seule chance est d'ajouter manuellement un certificat root venant de StartSSL:
http://stackoverflow.com/questions [...] oid-device
 
Ca semble possible à partir d'android 4.0

n°2265972
Krismu
Posté le 16-09-2015 à 17:25:02  profilanswer
 

Merci d'avoir fait la recherche, je suis pas très à l'aise avec tout ça, ça me rend grandement service (je re-découvre le lien entre HTTPS et SSL, c'est dire si je pars de loin :'( ).
 
Je vais faire des tests en local, mais vu que je pars d'une application Java, j'ai un moyen de contrôler que les données sont chiffrées ? J'imagine que tout se fait de manière transparente, mais grosso-modo, si ça fonctionne avec les requêtes sur HTTPS, je peux en conclure que tout est bien chiffré ou il y a une possibilité que ça marche sans pour autant être sécurisé ?
 

n°2266003
Devil'sTig​er
Posté le 17-09-2015 à 12:28:54  profilanswer
 

HTTPS une fois en place c'est transparent, tu "reçois du lisible" et tu "envois du lisible" dans les deux sens sans t'en soucier.
 
Si ca marche pas, tu auras une erreur HTTPS, donc pas vraiment besoin de te soucier du moindre test, tu mets https:// devant les requêtes, et tu croises les doigts pour que la réception soit ce que tu attendais :D

n°2266011
Krismu
Posté le 17-09-2015 à 16:16:19  profilanswer
 

OK merci pour toutes ces infos, va falloir que je digère tout ça et que je vois si j'arrive à en faire quelque chose.

n°2266500
tompouss
Petit chat
Posté le 26-09-2015 à 17:31:59  profilanswer
 

Pour le hashage de mot de passe, partir sur du sha est maintenant déconseillé par la doc PHP elle même.
Vaut mieux utiliser bcrypt qui a été conçu pour sécuriser les mots de passe contrairement aux hashs


---------------
collectionneur de pâtes thermiques
mood
Publicité
Posté le 26-09-2015 à 17:31:59  profilanswer
 

n°2266790
bobe
Posté le 30-09-2015 à 13:37:10  profilanswer
 

À partir de PHP 5.5, il y a l'API password, très simple d'usage :
http://php.net/manual/fr/book.password.php
 
Pour les versions antérieures à PHP 5.5, une librairie de compatibilité existe :
https://github.com/ircmaxell/password_compat
 
Ne jamais stocker de simples hash de mot de passe. Niveau sécurité = 0


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  PHP

  Meilleure approche pour encryption/décryption de mot de passe

 

Sujets relatifs
programme qui génère un mot de passeCherche formation d'une journée approche dev android et android studio
Meilleure spécification du diagramme des classesverouiller un dossier par un mots de passe + cryptage
besoin d'Aide : Python our programmer un mot de passeAide : Python our programmer un mot de passe
Code html pour "connexion" avec identifiant et mot de passeScripts ouverture page web avec mot de passe
exec en PHP qui ne passe pas ... 
Plus de sujets relatifs à : Meilleure approche pour encryption/décryption de mot de passe


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR