web-dev-qa-db-ger.com

Pythons sicherste Methode zum Speichern und Abrufen von Passwörtern aus einer Datenbank

Speichern Sie Benutzernamen und Passwörter in einer Datenbank und fragen Sie sich, was der sicherste Weg ist, dies zu tun. Ich weiß, dass ich irgendwo ein Salt verwenden muss, aber ich bin nicht sicher, wie ich es sicher generieren kann oder wie man es anwendet, um das Passwort zu verschlüsseln. Einige Beispiele für Python-Code wären sehr willkommen. Vielen Dank.

31
ensnare

Speichern Sie das Passwort + Salt als Hash und das Salt. Schauen Sie sich an, wie Django das macht: basic docs und source ..__ In der Datenbank-Datenbank speichern sie <type of hash>$<salt>$<hash> in einem einzigen Zeichenfeld. Sie können die drei Teile auch in separaten Feldern speichern.

Die Funktion zum Einstellen des Passworts:

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)

Das get_hexdigest ist nur ein dünner Wrapper für einige Hash-Algorithmen. Sie können Hashlib dafür verwenden. So etwas wie hashlib.sha1('%s%s' % (salt, hash)).hexdigest()

Und die Funktion, um das Passwort zu überprüfen:

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)
37
rz.

Ich denke, es ist am besten, ein Paket zu verwenden, das Passwörter für Hashing-Zwecke enthält, wie beispielsweise passlib: http://packages.python.org/passlib/ , aus Gründen, die ich hier erläutert habe: https://stackoverflow.com/a/10948614/893857

14
M.D.

Ich habe dies hier beantwortet: https://stackoverflow.com/a/18488878/1661689 und @Koffie auch.

Ich kann nicht genug betonen, dass die akzeptierte Antwort NICHT sicher ist. Es ist besser als reiner Text und besser als ein ungesalzter Hash, aber es ist immer noch extrem verwundbar für Wörterbuch- und sogar Brute-Force-Angriffe. Stattdessen bitte verwenden Sie eine SLOW KDF wie bcrypt (oder mindestens PBKDF2 mit 10.000 Iterationen).

12
Terrel Shumway

Wenn Sie über beide Endpunkte der Anwendung genügend Kontrolle haben, verwenden Sie PAK-Z + .

(Bearbeitet: Originalversion empfohlen SRP , aber PAK-Z + hat einen Sicherheitsnachweis.)

3
Paul Crowley

Dies ist ein einfacherer Weg (aus effbot), vorausgesetzt, Passwörter mit einer Länge von mehr als 8 sind kein Problem *

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)

um das Passwort zu generieren:

crypt.crypt("password", getsalt())

*: Ein Passwort mit einer Länge von mehr als 8 wird von rechts bis auf 8 Zeichen gekürzt

0
llazzaro