Domanda

Primo, contesto: sto cercando di creare uno strumento basato sulla riga di comando (Linux) richiede il login. Gli account su questo strumento non hanno nulla a che fare con account a livello di sistema - niente di tutto ciò guarda a / etc / passwd.

Sto programmando di archiviare gli account utente in un file di testo usando lo stesso formato (approssimativamente) di / etc / passwd.

Pur non usando i file delle password a livello di sistema, sembrava usare crypt essere una buona pratica da usare, invece di archiviare le password testo chiaro. (Mentre crypt è sicuramente meglio che archiviare le password in testo in chiaro, sono aperto ad altri modi per farlo.)

La mia conoscenza della cripta si basa su questo: https://docs.python.org/2/library/crypt.html

La documentazione sembra chiedere qualcosa che non è possibile: " it si consiglia di utilizzare la password crittografata completa come salt durante il controllo per una password. "

Eh? Se sto creando la password crittografata (come in, durante la creazione di un utente record) come posso usare la password crittografata come salt? esso non esiste ancora. (Presumo che tu debba usare lo stesso sale per creare e controllare una password.)

Ho provato a usare la password in chiaro come salt. Questo fa funziona, ma ha due problemi; uno facilmente superabile e uno serio:

1) Le prime due lettere della password in chiaro sono incluse in password crittografata. Puoi risolvere questo problema non scrivendo i primi due caratteri nel file:

user_record = '%s:%s:%s' % (user_name, crypted_pw[2:], user_type)

2) Usando la password in chiaro come salt, sembreresti esserlo riducendo la quantità di entropia nel sistema. Forse lo sono fraintendere lo scopo del sale.

La migliore pratica che ho potuto derivare è quella di utilizzare i primi due caratteri dal nome utente come il sale. Sarebbe appropriato, o c'è qualcosa che mi è sfuggito che fa una mossa sbagliata?

La mia comprensione di un salt è che impedisce la pre-informatica della password hash da un dizionario. Potrei usare un sale standard per tutti password (come le mie iniziali, "JS", ma che sembrano essere meno di a onere per un utente malintenzionato rispetto all'utilizzo di due caratteri dal nome utente di ciascun utente.

È stato utile?

Soluzione

Per l'uso del modulo crypt:

Quando si GENERA la password crittografata, si fornisce il sale. Potrebbe anche essere casuale aumentare la resistenza alla forza bruta, purché soddisfi le condizioni elencate. Quando VERIFICA una password, dovresti fornire il valore da getpwname, nel caso in cui ti trovi in ??un sistema che supporta dimensioni di sale più grandi e non l'ha generato da solo.

Commenti generali:

Se questo non ha nulla a che fare con gli accessi di sistema effettivi, non c'è nulla che ti impedisca di utilizzare un metodo più forte di crypt. È possibile generare casualmente N caratteri di salt per utente, da combinare con la password dell'utente in un hash SHA-1.

string_to_hash = user.stored_salt + entered_password
successful_login = (sha1(string_to_hash) == user.stored_password_hash)

AGGIORNAMENTO: Anche se questo è molto più sicuro rispetto alle tabelle arcobaleno, il metodo sopra ha ancora punti deboli crittografici. La corretta applicazione di un algoritmo HMAC può ancora aumentare ulteriormente la tua sicurezza, ma va oltre il mio regno di competenza.

Altri suggerimenti

Python's crypt () è un wrapper per la funzione crypt () del sistema. Dalla pagina man crypt () di Linux:

char *crypt(const char *key, const char *salt);

key is a user’s typed password.
salt is a two-character string chosen from the set [a–zA–Z0–9./]. 
This string is used to perturb the algorithm in one of 4096 
different ways.

L'enfasi è su " stringa di due caratteri " ;. Ora, se guardi il comportamento di crypt () in Python:

>>> crypt.crypt("Hello", "World")
'Wo5pEi/H5/mxU'
>>> crypt.crypt("Hello", "ABCDE")
'AB/uOsC7P93EI'

scopri che i primi due caratteri del risultato coincidono sempre con i primi due caratteri del sale originale, che in effetti formano il vero sale a due caratteri stesso. Cioè, il risultato di crypt () ha la forma 2char-salt + crittografato-pass. Pertanto, non vi è alcuna differenza nel risultato se invece di passare il salt a due caratteri o il salt a molti caratteri originale si passa l'intera password crittografata.

Nota: l'insieme [a & # 8211; zA & # 8211; Z0 & # 8211; 9. /] contiene 64 caratteri e 64 * 64 = 4096. Ecco come due caratteri si riferiscono a " 4096 modi diversi " ;.

Stai fraintendendo la documentazione; dice che poiché la lunghezza del salt può variare a seconda dell'implementazione crypt () sottostante, dovresti fornire l'intera password crittografata come valore salt quando controlli le password . Cioè, invece di togliere i primi due caratteri per essere il sale, basta lanciare l'intera cosa.

La tua idea di basare il sale iniziale sul nome utente sembra a posto.

Ecco alcuni consigli generali sulla salatura delle password:

  1. In generale, i sali sono usati per rendere tabelle ranbow troppo costose per il calcolo. Quindi, dovresti aggiungere un po 'di salt randomizzato a tutti gli hash della tua password e archiviarlo in testo normale accanto al valore della password con hash.
  2. Usa HMAC - è un buon standard ed è più sicuro che concatenare la password e sale.
  3. Usa SHA1: MD5 è rotto. Nessuna offesa se lo sapessi, essendo solo accurato. ;)

I non vorrei che il sale fosse una funzione della password. Un utente malintenzionato dovrebbe generare una tabella arcobaleno per disporre di un database di password di ricerca istantanea, ma dovrebbe farlo una sola volta. Se scegli un numero intero casuale a 32 bit, dovrebbero generare 2 ^ 32 tabelle, che (a differenza di un sale deterministico) costa molto, troppa memoria (e tempo).

Per un po 'di forza in più, puoi far sì che il modulo crypt usi md5 usando un salt nel formato.

$1$ABCDEFGH$

dove ABCDEFGH è la tua stringa di sale.

>>> p = crypt.crypt('password', '$1$s8Ty3/f

(nota che questa è un'estensione gnu per crypt, vedi "man crypt" su un sistema linux). MD5 (e ora anche SHA1) potrebbe essere "rotto", ma sono ancora relativamente buoni per gli hash delle password, e md5 è ancora lo standard per le password locali di Linux.

) >>> p Out: '$1$s8Ty3/f<*>H/M0JswK9pl3X/e.n55G1' >>> p == crypt.crypt('password', p) Out: True

(nota che questa è un'estensione gnu per crypt, vedi "man crypt" su un sistema linux). MD5 (e ora anche SHA1) potrebbe essere "rotto", ma sono ancora relativamente buoni per gli hash delle password, e md5 è ancora lo standard per le password locali di Linux.

La password, o qualsiasi cosa derivata dalla password, non dovrebbe mai essere usata come salt. Il sale per una determinata password dovrebbe essere imprevedibile.

Un nome utente o parte del nome utente è tollerabile, ma ancora meglio sarebbe byte casuali da un RNG crittografico.

Usa PBKDF2, vedi questo commento su un thread diverso ( include l'implementazione di Python).

Dai un'occhiata all'articolo TrueCrypt spiegato di Bj & # 246; rn Edstr & # 246; m. Contiene una spiegazione di facile comprensione di come funziona TrueCrypt e una semplice implementazione in Python di alcune funzionalità di TrueCrypt inclusa la gestione delle password .

  

Sta parlando del modulo Python crypt (), non di TrueCrypt in Python

predefinito crypt.crypt () in Python 2 non è molto sicuro e l'articolo spiega come potrebbero funzionare alternative più sicure.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top