IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Stockage des mots de passe utilisateur et stockage des secrets de l'application


Sujet :

Python

  1. #1
    Membre averti

    Profil pro
    En reconversion
    Inscrit en
    Novembre 2007
    Messages
    180
    Détails du profil
    Informations personnelles :
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : En reconversion

    Informations forums :
    Inscription : Novembre 2007
    Messages : 180
    Points : 351
    Points
    351
    Par défaut Stockage des mots de passe utilisateur et stockage des secrets de l'application
    Bonjour,

    Après digestion du livre suivant https://www.editions-eni.fr/supports...-9782409006340 et de plusieurs documents de l'OWASP, je réfléchis maintenant à mettre en place tout cela.

    Pour information, je travaille avec le framework web asynchrone Sanic.

    Deux questions se présentent à moi :

    1. D'abord, le stockage du mot de passe des utilisateurs.
    Le support sera une table dans une base de données Postgresql. Je choisis de hasher les mots de passe du côté du code Python, et non directement dans la base de données (avec pgcrypto).
    Evidemment, exit les md5 ou sha1, totalement périmé pour faire cela. J'envisage d'utiliser la bibliothèque passlib avec argon2 ou bcrypt. scrypt est également proposé, mais je l'ai exclus sans raison apparente. J'hésite à utiliser argon2 car cela semble très récent (trop ???), même si je lis ici et là que c'est la solution numéro un.
    Avec bcrypt, il y a un système que je n'ai pas compris totalement qui permet de stocker le sel avec le hash. Il s'agirait d'un sel dynamique, qui change à chaque fois ...
    L'OWASP préconise d'utiliser un sel dynamique, c'est à dire qu'il change à chaque utilisation. On fait cela par exemple en chiffrant en AES l'identifiant qui va avec le mot de passe. On obtient bien ainsi un sel différent qui change à chaque fois, mais qu'il est possible de retrouver facilement.
    Pour chiffrer en AES, j'utiliserai la bibliothèque cryptography.
    Donc ma solution est de concaténer l'identifiant chiffré au mot de passe puis de hasher cela en bcrypt. Qu'en pensez vous ? Est ce une bonne pratique ?


    2. Ensuite, le stockage de tout ce qui est sensible dans la code. Par exemple un sel, les identifiants et mots de passe aux bases de données et autres, etc.
    Mes recherches m'ont conduite principalement vers deux solutions : soit le stockage dans un fichier de configuration, soit le stockage dans des variables d'environnement.
    Pensez vous à d'autres solutions ? Que pensez vous de ces solutions ci-dessus ?
    Bien évidemment, si un pirate expert prend la main sur le serveur, il aura de toute façon accès aux informations sensibles, au moins en lecture, quelque soit l'endroit où on les met.
    J'ai tout de même un petite idée. Et si je mettais dans un fichier séparé (par exemple avec l'aide du module configparser) les données sensibles sous un format chiffré en AES. Ensuite avec l'aide du module argparse je fais en sorte de passer en paramètre la clé de déchiffrement. Il n'y a plus alors qu'un seul secret visible et celui ci sera du côté du paramétrage du démon (sous ubuntu) pour démarrer le serveur si je ne dis pas de bêtises (je ne l'ai jamais fait encore).
    Au lancement du serveur je récupère la clé et je déchiffre toutes les valeurs sensibles qui seront alors chargées en mémoire.
    Qu'en pensez vous ? Quels conseils me donneriez vous ?

    Merci par avance pour votre aide.

  2. #2
    Membre extrêmement actif
    Profil pro
    Développeur
    Inscrit en
    Mars 2012
    Messages
    1 969
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mars 2012
    Messages : 1 969
    Points : 3 375
    Points
    3 375
    Par défaut
    La méthode est de stocker:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    HASH( <password> + <salt> ) => hashed password
    Ca permet de réduire l'utilisation des rainbow tables car il y a autant de possibilités qu'il y a de salt pour un seul mot de passe.

    Le salt doit être long et différent pour chaque mot de passe.
    Si la réponse vous a aidé, pensez à cliquer sur +1

  3. #3
    Membre averti

    Profil pro
    En reconversion
    Inscrit en
    Novembre 2007
    Messages
    180
    Détails du profil
    Informations personnelles :
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : En reconversion

    Informations forums :
    Inscription : Novembre 2007
    Messages : 180
    Points : 351
    Points
    351
    Par défaut
    @hotcryx

    Merci,
    C'est effectivement la préconisation de l'OWASP, mais comment fais tu de ton côté pour avoir un "salt" différent à chaque fois ? Et cette histoire de sel avec bcrypt, est ce suffisant tout seul ?

  4. #4
    Expert éminent

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 300
    Points : 6 780
    Points
    6 780
    Par défaut
    Salut,
    Regarde du côté de Werkzeug, c'est une boîte d'outils en Python. Elle gère le "salted hash".

    Tu ne dois pas t'occuper du "sel" c'est son problème.

    http://werkzeug.pocoo.org/docs/0.12/...kzeug.security

    Edit: un exemple retrouvé dans mes archives:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    from werkzeug.security import generate_password_hash
    pswd = generate_password_hash('déjàvu', method='pbkdf2:sha1', salt_length=8)
    print pswd

  5. #5
    Membre averti

    Profil pro
    En reconversion
    Inscrit en
    Novembre 2007
    Messages
    180
    Détails du profil
    Informations personnelles :
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : En reconversion

    Informations forums :
    Inscription : Novembre 2007
    Messages : 180
    Points : 351
    Points
    351
    Par défaut
    @VinsS

    Merci pour ta proposition.

    werkzeug étant derrière Flask et étant donné que j'ai souvent vu dans les tutoriels de Flask qu'on créait une variable globale contenant une phrase secrète, je pense que le sel provient de là. J'avoue, j'ai la flemme d'aller chercher les sources pour en être sûr.

    J'attire au passage ton attention sur la faiblesse de cette implémentation utilisant 'pbkdf2:sha1'. Même avec sha256 disponible dans werkzeug, cela reste peut recommandé à la vue des lectures que j'ai faite récemment.

    Regarde ici par exemple : https://paragonie.com/blog/2016/02/how-safely-store-password-in-2016

    En fait, il faut distinguer les algorithmes de hashage, pour le stockage des mots de passe, des autres. Les seconds doivent être rapides, alors que les premiers doivent être lents.
    A défaut avec les capacités de l'informatique d'aujourd'hui on peut estimer accessible la possibilité de retrouver la valeur d'origine. Sans compter qu'on a réussi à trouver des collisions dans md5 ou sha1 (ou les deux je ne sais plus). Une collision signifie qu'à partir de deux valeurs d'origine distinctes on a obtenu les mêmes valeurs hashées. Je ne saurai expliquer en détails pourquoi mais cela est une faille importante.
    Les certificats TLS qui utilisait sha1 par exemple ont été bannis.

    Le problème avec les conseils de l'OWASP, c'est qu'ils donnent peu d'indications sur les solutions à mettre en œuvre avec du python. Ils disent surtout ce qu'il ne faut pas faire. Pour moi qui suis novice, j'ai du mal à être sûr de la solution que je choisis, c'est pour cette raison que j'essaie d'avoir des avis sur le forum.

    Merci pour ton aide

  6. #6
    Membre extrêmement actif
    Profil pro
    Développeur
    Inscrit en
    Mars 2012
    Messages
    1 969
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mars 2012
    Messages : 1 969
    Points : 3 375
    Points
    3 375
    Par défaut
    Salut Patic,

    Tu ne dois pas utiliser MD5 et SHA1.
    Passes à SHA2...

    Rem: le salt ne doit pas être court => 8 caractères ça me semble court.

    "werkzeug étant derrière Flask et étant donné que j'ai souvent vu dans les tutoriels de Flask qu'on créait une variable globale contenant une phrase secrète, je pense que le sel provient de là. J'avoue, j'ai la flemme d'aller chercher les sources pour en être sûr."

    Quand tu regardes d'autres frameworks comme Mojolicious (Perl), il fait exactement la même chose pour sécuriser les cookies.
    Si la réponse vous a aidé, pensez à cliquer sur +1

  7. #7
    Membre averti

    Profil pro
    En reconversion
    Inscrit en
    Novembre 2007
    Messages
    180
    Détails du profil
    Informations personnelles :
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : En reconversion

    Informations forums :
    Inscription : Novembre 2007
    Messages : 180
    Points : 351
    Points
    351
    Par défaut
    @hotcryx

    Évidemment que je n'utilise pas md5 ou sha1, c'est d'ailleurs ce que je dis dans mes messages précédents.

    SHA2 n'est plus une solution viable aujourd'hui. Ce n'est d'ailleurs pas initialement un algorithme de hashage fait pour le stockage des mots de passe, si j'ai bien compris. Il faut bien comprendre que dans ce dernier cas, il est nécessaire d'avoir des algorithmes très lent. Ainsi on empêche la constitution de rainbow table, car cela prend trop de temps à générer.

    Selon mes lectures, les algorithmes à utiliser sont : bcrypt, scrypt et argon2. Cependant, sans expérience sur le sujet, je cherche des retours de personne qui ont déjà fait ces expériences.

    Cette histoire de sel trop court m'embête car si je chiffre en AES l'identifiant pour en faire un sel, je pense que le résultat va être un peu court. Il faut que je fasse des tests. Quelle longueur minimale faut il avoir ?

    Le problème des frameworks c'est que je ne sais pas ce qui est fait derrière sans devoir me plonger dans le code source. Ne pas réinventer la roue, je suis d'accord, mais dans le cas des frameworks la surcouche est parfois trop importante et on ne voit plus rien de la machinerie derrière.
    En plus, comment apprendre en utilisant un framework qui fait tout à votre place ... Bien sûr cela est valable pour moi car je ne suis pas dans de l'industrialisation avec de grosses équipes.
    Je me rappelle, il y a plus de dix ans, je lisais un article qui parlait du concepteur de PHP qui critiquait les frameworks car ils empêchaient l'apprentissage du langage et parce qu'ils ralentissaient l’exécution du code.
    Je ne veux pas par exemple de Django car je ne veux pas d'ORM. Ces trucs vous font des tas de requête dans tous les sens pour rien. Je préfère écrire moi même mes procédures stockées et les appeler avec Python ensuite. D'accord c'est plus long mais c'est plus optimisé et sécurisé. En plus, à mon avantage, cela fait longtemps que je travaille avec des base de données et j'aime cela contrairement à la plupart des développeurs que j'ai croisé.

    Tu parles d'utilisation d'algorithme de hashage pour les cookies. J'imagine que c'est pour créer un id de session. Donc il faut que celui-ci soit unique et que les suivants ne puissent pas être deviné (pas de suite logique, des valeurs aléatoires). Alors pourquoi un algorithme de hashage ? Pour l'unicité peut être, mais pas pour le côté aléatoire.
    Pour information, dans Python 3.6, on a maintenant le module secrets qui propose de générer une vraie valeur aléatoire sans faire os.urandom ou quelque chose du genre.

  8. #8
    Membre extrêmement actif
    Profil pro
    Développeur
    Inscrit en
    Mars 2012
    Messages
    1 969
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mars 2012
    Messages : 1 969
    Points : 3 375
    Points
    3 375
    Par défaut
    J'ai déjà utilisé SHA2 mais c'était en Java Android pour vérifier un login.
    Je pense qu'il doit avoir une longueur équivalente au mininum d'un mot de passe relativement complexe (15 caractères) => +30 ou 32 caractères

    Probablement sur ce site que j'ai lu l'info (mon proxy bloque le site maintenant)!
    https://crackstation.net/

    Concernant Mojolicious: c'est pour signer les cookies entre-autres.

    Tu as raison de redévelopper certaines choses.
    Je suis d'avis d'employer les librairies mais pour des parties sécurité il faut être très très prudent.
    J'ai regardé longuement pour la partie sécurité pour stocker mes mots de passe.
    Finalement n'ayant pas confiance aux tools... et trouvant extrêmement compliqué leurs algorythmes (certains ont des failles), j'ai développé le mien
    Ce n'est pas recommandé pour ce sujet sensible mais j'ai été prudent et je pense que ça tient la route.

    Quand tu sens quelque-chose qui pue ou qui rame... => redéveloppe quelque-chose de simple.
    Si la réponse vous a aidé, pensez à cliquer sur +1

  9. #9
    Membre extrêmement actif
    Profil pro
    Développeur
    Inscrit en
    Mars 2012
    Messages
    1 969
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mars 2012
    Messages : 1 969
    Points : 3 375
    Points
    3 375
    Si la réponse vous a aidé, pensez à cliquer sur +1

  10. #10
    Membre averti

    Profil pro
    En reconversion
    Inscrit en
    Novembre 2007
    Messages
    180
    Détails du profil
    Informations personnelles :
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : En reconversion

    Informations forums :
    Inscription : Novembre 2007
    Messages : 180
    Points : 351
    Points
    351
    Par défaut
    Je viens de passer quelques temps à approfondir mes connaissances sur le sujet sur le net.

    Concernant la longueur du "salt", il faut s'aligner avec la longueur des clés de hashage, donc par exemple avec SHA256 (avec pbkdf2) que vous semblez appréciez, il faut mettre 32 caractères (256 bits donnent 32 octets et le plus souvent 8 bits/caractère et 8 bits = 1 octet).

    Concernant les algorithmes qui gèrent eux même le "salt", notamment bcrypt, scrypt, argon2 ou même pbkdf2 (avec au moins SHA256), en fait le "salt" est tout simplement accolé au résultat du hash. Il suffit donc de lire les spécifications de l'algorithme pour savoir comment trouver le "salt".
    De toute manière, l'autre conseil pour stocker le "salt" dynamique, c'est de le stocker dans une colonne spécifique dans la table de la base de données. J'ai du mal à comprendre l'intérêt d'ajouter un sel si on l'inscrit à côté du mot de passe hashé. C'est vrai, l'ajout du sel empêche l'utilisation des rainbowtable, puisqu'il faudrait générer une nouvelle table spécifique au sel donné (mais c'est trop long à construire).

    Pour rappel, l'objectif d'un sel dynamique est d'avoir un sel différent pour chaque ligne de la table dans la base de données. Pas un seul mot de passe (même identique en clair) n'a le même sel.

    Du coup, je crois que mon idée initiale, trouvée dans le livre "Sécurité informatique sur le Web - Apprenez à sécuriser vos applications" si je me rappelle bien, ne semble pas mauvaise. Il faudra juste que je fasse des tests réels pour voir le temps de réponse.
    Par contre je pense utiliser argon2 finalement : http://passlib.readthedocs.io/en/sta...sh.argon2.html.
    La seule question qui se pose encore est : est ce que celle librairie passlib est fiable ?

    Pour info, voici la documentation de l'OWASP sur le sujet, pas très clair je trouve (mais j'ai du mal avec la langue de Shakespeare) : https://www.owasp.org/index.php/Pass...ge_Cheat_Sheet

  11. #11
    Membre extrêmement actif
    Profil pro
    Développeur
    Inscrit en
    Mars 2012
    Messages
    1 969
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mars 2012
    Messages : 1 969
    Points : 3 375
    Points
    3 375
    Par défaut
    Le salt doit être différent pour chaque record.

    Sans connaître le password, le SALTne sert à rien, voilà pourquoi il est stocké et peut être généré par urandom ou par une fonction de la db.
    Maintenant ces SALT peuvent aussi être cryptés avec une clé maison (ex: <identifiant inversé> <premier et dernier caractère du nom> <dernier et premier caractère du prénom> <nombre de caractères du nom et prénom>... )

    "fais-toi plaise...."
    Si la réponse vous a aidé, pensez à cliquer sur +1

  12. #12
    Membre extrêmement actif
    Profil pro
    Développeur
    Inscrit en
    Mars 2012
    Messages
    1 969
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mars 2012
    Messages : 1 969
    Points : 3 375
    Points
    3 375
    Par défaut
    Concernant passlib: difficile de savoir le sérieux de la librairie.
    Il y a peu d'issues (bon point), beaucoup de forks.
    Pourquoi tous ces forks? des hackers, des créateurs de patch...?
    Le sujet est sensible et l'on se doute que plein de vilains tournent autour...
    Pourquoi ne prends-tu pas un algo qui a fait ses preuves dans le temps???

    Pour savoir le sérieux, il faut analyser le code et vérifier les gros points incontournables de la cryptographie.
    Si tu trouves une faille, méfie-toi...
    J'ai lu dans les issues qu'une string était codée dans la lib.
    Peut-être un point de départ.
    Si la réponse vous a aidé, pensez à cliquer sur +1

Discussions similaires

  1. Réponses: 0
    Dernier message: 31/05/2013, 14h06
  2. Stockage des mots de passe de connexion
    Par marcusien dans le forum Entity Framework
    Réponses: 1
    Dernier message: 08/09/2011, 12h19
  3. Réponses: 17
    Dernier message: 12/05/2010, 22h50
  4. Gestion des mots de pass utilisateur
    Par philguio dans le forum VB.NET
    Réponses: 3
    Dernier message: 05/05/2007, 22h42
  5. [Sécurité] Stockage des mots de passe
    Par Jesmar dans le forum Langage
    Réponses: 4
    Dernier message: 29/03/2007, 21h05

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo