2010-04-03 9 views
28

Cercare di memorizzare nomi utente e password in un database e mi chiedo quale sia il modo più sicuro per farlo. So che devo usare un sale da qualche parte, ma non sono sicuro di come generarlo in modo sicuro o come applicarlo per crittografare la password. Alcuni esempi di codice Python sarebbero molto apprezzati. Grazie.Il metodo più sicuro di Python per archiviare e recuperare password da un database

+0

un sacco di informazioni qui: http://stackoverflow.com/questions/1183161/to-sha512-hash-a- password-in-mysql-database-by-python –

risposta

34

Memorizzare la password + sale come hash e sale. Dai un'occhiata a come Django lo fa: basic docs e source. Nel db memorizzano <type of hash>$<salt>$<hash> in un singolo campo char. È inoltre possibile memorizzare le tre parti in campi separati.

La funzione per impostare la password:

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) 

Il get_hexdigest è solo un wrapper sottile attorno ad alcuni algoritmi di hashing. Puoi usare hashlib per questo. Qualcosa di simile hashlib.sha1('%s%s' % (salt, hash)).hexdigest()

E la funzione di verificare la password:

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) 
+0

Hai un collegamento al file di codice appropriato? –

+0

Questo è stato davvero utile. Grazie mille. – ensnare

+0

@justin ethier: ci sei. @ensnare: sentiti libero di contrassegnarlo come accettato ;-) –

3

Se avete abbastanza controllo su entrambi gli endpoint della domanda, il modo migliore in assoluto sta usando PAK-Z+.

(A cura: la versione originale raccomandata SRP ma PAK-Z + ha una prova di sicurezza.)

0

Ecco un modo più semplice (tratto da effbot), fornito le password con una lunghezza superiore a 8 non sarà un problema *:

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) 

per generare il Password:

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

*: Una password con una lunghezza superiore a 8 è spogliato da destra verso il basso per 8 caratteri lunghi

+0

cripta hanno problemi a crittografare la password di più di 8 caratteri Penso che – llazzaro

10

ho risposto questa qui: https://stackoverflow.com/a/18488878/1661689, e così ha fatto @Koffie.

Non so come sottolineare abbastanza che la risposta accettata NON è sicura. È meglio del semplice testo e migliore di un hash non salato, ma è comunque estremamente vulnerabile allo al dizionario e persino agli attacchi di forza bruta. Invece, si prega di utilizzare un KDF SLOW come bcrypt (o almeno PBKDF2 con 10.000 iterazioni)

+0

Stai suggerendo che la memorizzazione di password correttamente salate e hash è una ** pratica estremamente vulnerabile **? Non è possibile utilizzare un attacco di dizionario su hash salati. – vroomfondel

+0

No. Sto suggerendo che una singola iterazione di SHA-1, come suggerisce il codice sopra, non è "correttamente salata e hash". Puoi * usare * un attacco di dizionario sugli hash salati, e più velocemente l'hash, più velocemente ogni pw può essere provato. Preferiresti che ci sia voluto un giorno o 64.000 giorni perché l'attacco avesse successo? L'hashing SHA-x è * molto * veloce sull'hardware personalizzato (ASIC). https://www.owasp.org/index.php/Password_Storage_Cheat_Sheet#Impose_infeasible_verification_on_attacker http://stackoverflow.com/questions/13545677/python-passlib-what-is-the-best-value-forrounds –

+1

@rz dice "guarda come fa Django" e poi mostra il codice che è completamente diverso. Django * lo fa correttamente: https://github.com/django/django/blob/master/django/contrib/auth/hashers.py#L216 –

Problemi correlati