Vous souhaitez stocker les noms d'utilisateur et les mots de passe dans une base de données, et je me demande quel est le moyen le plus sûr de le faire. Je sais que je dois utiliser un sel quelque part, mais je ne sais pas comment le générer de manière sécurisée ni comment l’appliquer pour chiffrer le mot de passe. Quelques exemples de code Python seraient grandement appréciés. Merci.
Stockez le mot de passe + sel sous forme de hachage et le sel. Regardez comment Django le fait: docs de base et source . Dans la base de données, ils stockent <type of hash>$<salt>$<hash>
dans un seul champ de caractères. Vous pouvez également stocker les trois parties dans des champs distincts.
La fonction pour définir le mot de passe:
def set_password(self, raw_password):
import random
algo = 'sha1'
salt = get_hexdigest(algo, str(random.random()), str(random.random()))[:5]
hsh = get_hexdigest(algo, salt, raw_password)
self.password = '%s$%s$%s' % (algo, salt, hsh)
Le get_hexdigest est juste une mince enveloppe autour de certains algorithmes de hachage. Vous pouvez utiliser hashlib pour cela. Quelque chose comme hashlib.sha1('%s%s' % (salt, hash)).hexdigest()
Et la fonction pour vérifier le mot de passe:
def check_password(raw_password, enc_password):
"""
Returns a boolean of whether the raw_password was correct. Handles
encryption formats behind the scenes.
"""
algo, salt, hsh = enc_password.split('$')
return hsh == get_hexdigest(algo, salt, raw_password)
Je pense qu'il est préférable d'utiliser un paquet dédié au hachage des mots de passe pour cela comme passlib: http://packages.python.org/passlib/ pour des raisons que j'ai expliquées ici: https://stackoverflow.com/a/10948614/893857
J'ai répondu à ceci ici: https://stackoverflow.com/a/18488878/1661689 , ainsi que @Koffie.
Je ne sais pas comment souligner assez que la réponse acceptée n'est PAS sécurisée. Il vaut mieux que le texte brut et mieux qu’un hachage non salé, mais il reste toujours extrêmement vulnérable attaqué par un dictionnaire et même par la force. S'il vous plait, utilisez utilisez un fichier KDF SLOW comme bcrypt (ou au moins PBKDF2 avec 10 000 itérations)
Voici un moyen plus simple (tiré d’effbot), à condition que les mots de passe d’une longueur supérieure à 8 ne posent aucun problème *:
import crypt
import random, string
def getsalt(chars = string.letters + string.digits):
# generate a random 2-character 'salt'
return random.choice(chars) + random.choice(chars)
pour générer le mot de passe:
crypt.crypt("password", getsalt())
*: Un mot de passe d'une longueur supérieure à 8 est supprimé de la droite à 8 caractères