Projet

Général

Profil

Development #35533

stockage des mots de passe hashés

Ajouté par Thomas Noël il y a plus de 4 ans. Mis à jour il y a presque 4 ans.

Statut:
Rejeté
Priorité:
Bas
Assigné à:
Version cible:
-
Début:
22 août 2019
Echéance:
% réalisé:

0%

Temps estimé:
Patch proposed:
Oui
Planning:
Non

Description

Actuellement wcs sait stocker les champs mot de passe hashés en md5 et sha1 seulement ; c'est assez faible.

On pourrait ajouter les hashers "bien connus" présents dans Django.


Fichiers


Demandes liées

Lié à Authentic 2 - Development #35482: passer le HASH du mot de passe des nouveaux utilisateurs aux service web d'A2Fermé20 août 2019

Actions

Historique

#1

Mis à jour par Frédéric Péters il y a plus de 4 ans

1/ on dépend de django 1.11, pas besoin de if django.VERSION >= (1, 10, 0):. 2/ je ne serais pas pour l'exhaustivité, uniquement inclure les formats pertinents, voire même uniquement ajouter le hashage par défaut, PBKDF2PasswordHasher (c'est le cas en 1.11, c'est toujours le cas en 2.1).

#2

Mis à jour par Nicolas Roche il y a plus de 4 ans

Merci, tu as lu dans mes pensées !

Je met quand même ici mon patch et mon laïus (au moins pour moi pour m'y retrouver plus tard), mais oui ça me va très bien de n'intégrer que PBKDF2PasswordHasher. On pourra facilement en rajouter d'autres si besoin.

Voici tous les algos disponibles (via Django) en théorie :

$ grep 'algorithm = ' ~/src/django/django/contrib/auth/hashers.py
...
    algorithm = "pbkdf2_sha256" 
    algorithm = "pbkdf2_sha1" 
    algorithm = 'argon2'
    algorithm = "bcrypt_sha256" 
    algorithm = "bcrypt" 
    algorithm = "sha1" 
    algorithm = "md5" 
    algorithm = "unsalted_sha1" 
    algorithm = "unsalted_md5" 
    algorithm = "crypt" 

L'API ne retournent que les algos qui sont déclarés dans les settings :

> from django.conf import global_settings
> global_settings.PASSWORD_HASHERS
[u'django.contrib.auth.hashers.PBKDF2PasswordHasher',
 u'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
 u'django.contrib.auth.hashers.Argon2PasswordHasher',
 u'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
 u'django.contrib.auth.hashers.BCryptPasswordHasher']

> from django.contrib.auth.hashers import get_hashers_by_algorithm
> get_hashers_by_algorithm().keys()
[u'argon2', u'bcrypt', u'pbkdf2_sha1', u'pbkdf2_sha256', u'bcrypt_sha256']

Dans les faits, les algos accessibles via l'API ne sont pas forcément installés :

> get_hasher('argon2')
<django.contrib.auth.hashers.Argon2PasswordHasher object at 0x7f19836be510>
> get_hasher('argon2').encode('secret', hasher.salt())
*** ValueError: Couldn't load 'Argon2PasswordHasher' algorithm library: No module named argon2

$ pip install argon2
> get_hasher('argon2').encode('secret', hasher.salt())
*** AttributeError: 'module' object has no attribute 'low_level'

$ pip install django[argon2]
> get_hasher('argon2').encode('secret', hasher.salt())
(ok)

Par ailleurs, on peut utiliser les algos disponibles sans passer nécessairement par l'API :

> from django.contrib.auth.hashers import SHA1PasswordHasher
> hasher = SHA1PasswordHasher()
> hasher.encode('secret', hasher.salt())

Le patch ci-dessous ajoute tous les algos disponibles dans django.
Pour info, j'ai dû modifier l'encodage du salt générique pour que les hasher salted md5 et sha1 autorisent les mots de passe non ascii.

*** UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 0: ordinal not in range(128)'

Le hasher argon2 n'est disponible que depuis Django 1.10.
Il n'est pas installé par défaut et est succeptible de lever 2 exceptions.
Je simule un encodage en amont pour détecter par avance ces erreurs afin de ne pas le proposer en option dans le back-office.

#3

Mis à jour par Nicolas Roche il y a plus de 4 ans

  • Statut changé de Solution proposée à En cours
#4

Mis à jour par Nicolas Roche il y a plus de 4 ans

Ce patch ajoute le hashage par défaut, PBKDF2PasswordHasher.
Dites-moi si vous en voulez d'autres.

edit: j'ai oublié de modifier le message du commit dans mon patch :

fields: add PBKDF2 hashed password format (#35533)

#5

Mis à jour par Frédéric Péters il y a plus de 4 ans

Ok ça vient d'avant mais le code make_encoder() etc. complique les choses, ça pourrait juste être une simple fonction et dessous 'pbkdf2': lambda x: pbkdf2_encode(x).

Aussi ça serait pas mal de lier ce ticket au besoin fonctionnel qui est à l'origine.

#6

Mis à jour par Nicolas Roche il y a plus de 4 ans

  • Lié à Development #35482: passer le HASH du mot de passe des nouveaux utilisateurs aux service web d'A2 ajouté
#7

Mis à jour par Nicolas Roche il y a plus de 4 ans

le code make_encoder() etc. complique les choses

oui, excès de zèle

besoin fonctionnel qui est à l'origine

il n'y en a pas : évoqué (mais non requis) pour signal-publik, et à priori n'y sera finalement pas utilisé.

#8

Mis à jour par Frédéric Péters il y a plus de 4 ans

Pas très fan d'intégrer du code inutilisé.

Mais à part ça, ok pour le code, mais tant qu'à faire, également modifier le paramétrage par défaut du champ pour exploiter cet algo.

#9

Mis à jour par Nicolas Roche il y a plus de 4 ans

Pas très fan d'intégrer du code inutilisé.

aucun problème, je l'ai fait parque Thomas me l'avais demandé (on peut laisser au chaud ici)

paramétrage par défaut du champ

arf, je ne sais pas où c'est

#10

Mis à jour par Frédéric Péters il y a plus de 4 ans

(on peut laisser au chaud ici)

Non, on intègre ou on rejette le ticket.

C'est le

     formats = ['sha1']

dans les attributs de la classe.

#12

Mis à jour par Nicolas Roche il y a plus de 4 ans

  • Assigné à mis à Nicolas Roche
#13

Mis à jour par Thomas Noël il y a presque 4 ans

  • Statut changé de Solution proposée à Rejeté

Finalement ça ne sera pas utilisé (et certainement jamais) ; annulons cette affaire.

Formats disponibles : Atom PDF