Come fa Linux a sapere che la nuova password è simile alla precedente?


145

Alcune volte ho provato a cambiare una password utente su varie macchine Linux e quando la nuova password era simile a quella precedente, il sistema operativo si è lamentato del fatto che erano troppo simili.

Mi sono sempre chiesto, come fa il sistema a saperlo? Ho pensato che la password fosse salvata come hash. Ciò significa che quando il sistema è in grado di confrontare la nuova password per somiglianza, quella vecchia viene effettivamente salvata come testo normale?


30
1 ° di sconto: testo in chiaro? no. Se (!) Hai salvato, salvi l'hash e confronta gli hash. In Linux, tuttavia, controlla la password corrente con una nuova password. ENTRAMBI vengono forniti dall'utente durante la modifica delle password.
Rinzwind,

42
@Rinzwind Ma il confronto degli hash non funzionerà perché una differenza di un carattere dovrebbe tradursi in un hash completamente diverso
slhck,

17
Vedi anche Facebook memorizza le password in testo normale? sulla sicurezza delle informazioni per altri modi di rilevare la somiglianza dato solo l'hash della vecchia password e il testo in chiaro della nuova password (nessun testo in chiaro per la vecchia).
Bob,

21
Puoi effettivamente verificare la somiglianza tra una vecchia password con hash e una nuova password in chiaro. Basta generare un elenco di password simile a quello nuovo, cancellarle tutte e confrontare gli hash risultanti con quelli della vecchia password. Se c'è una corrispondenza, allora è simile.
BWG,

2
@BWG: Questa è una leggera semplificazione eccessiva: gli attuali schemi di hash saltano l'hash, quindi prima devi estrarre il sale dal vecchio hash della password e assicurarti di usare quel salt per le tue password simili a nuove. (Lo sto sottolineando perché è possibile che l'API non esponga un modo per forzare un sale specifico.)
Ulrich Schwarz,

Risposte:


156

Dato che è necessario fornire sia la vecchia che la nuova password durante l'utilizzo passwd, possono essere facilmente confrontati in testo normale, in memoria, senza scriverli da qualche parte sul disco.

In effetti la tua password viene cancellata quando viene finalmente memorizzata, ma fino a quando ciò accade, lo strumento in cui stai inserendo la tua password può ovviamente accedervi direttamente come qualsiasi altro programma può accedere alle cose che hai inserito sulla tastiera mentre stava leggendo da STDIN.

Questa è una caratteristica del sistema PAM che viene utilizzato in background sullo passwdstrumento. PAM è utilizzato dalle moderne distribuzioni Linux.

Più specificamente, pam_cracklibè un modulo per PAM che consente di rifiutare le password in base a diversi punti deboli che le renderebbero molto vulnerabili.

Non sono solo le password troppo simili che possono essere considerate non sicure. Il codice sorgente contiene vari esempi di cosa può essere verificato, ad esempio se una password è un palindromo o quale sia la distanza di modifica tra due parole. L'idea è di rendere le password più resistenti agli attacchi del dizionario.

Vedi anche la pam_cracklibmanpage.


hai idee su "come" la tua spiegazione si adatta agli argomenti riportati nella mia risposta? Esistono due approcci diversi, adottati dall'applicazione "passwd", quando l'host non è compatibile con PAM? PS: nessun critico. Mi sto solo chiedendo (visto che PAM, BTW, è stata la mia prima ipotesi ... poco prima di accedere al codice sorgente).
Damiano Verzulli,

27
Più inquietanti sono le regole della password aziendale che ti avvisano se hai utilizzato la stessa password o simile tra una delle ultime quattro.
Nick T,

4
@NickT In che modo (necessariamente) disturba - non potevano semplicemente salvare i tuoi ultimi 4 hash, quindi confrontare ciascuno di quelli con quello nuovo proposto allo stesso modo di questa domanda?
neminem,

1
@neminem "... o simile"
Nick T

1
@NickT Ah, abbastanza giusto, perché in questo caso particolare stai confrontando con la "vecchia password" che è stata inserita dall'utente per cambiare la password, piuttosto che con un hash salvato. Ancora, si potrebbe ipoteticamente utilizzare il metodo BWG ha scritto in un commento, per almeno il controllo modifiche molto semplici (sostituzione di un carattere, un carattere aggiunto / tolto, etc.).
neminem,

46

Almeno nel mio Ubuntu, i messaggi "troppo simili" vengono fuori quando: "... più della metà dei personaggi sono diversi ...." (vedi sotto per i dettagli). grazie al supporto PAM, come spiegato chiaramente nella risposta @slhck.

Per altre piattaforme, in cui PAM non viene utilizzato, i messaggi "troppo simili" vengono visualizzati quando: "... più della metà dei personaggi sono diversi ...." (vedi sotto per i dettagli)

Per controllare ulteriormente questa affermazione da solo, è possibile controllare il codice sorgente. Ecco come.

Il programma "passwd" è incluso nel pacchetto passwd:

verzulli@iMac:~$ which passwd
/usr/bin/passwd
verzulli@iMac:~$ dpkg -S /usr/bin/passwd
passwd: /usr/bin/passwd

Dato che abbiamo a che fare con le tecnologie Open Source, abbiamo accesso illimitato al codice sorgente. Ottenere è semplice come:

verzulli@iMac:/usr/local/src/passwd$ apt-get source passwd

Successivamente è facile trovare il frammento di codice rilevante:

verzulli@iMac:/usr/local/src/passwd$ grep -i -r 'too similar' .
[...]
./shadow-4.1.5.1/NEWS:- new password is not "too similar" if it is long enough
./shadow-4.1.5.1/libmisc/obscure.c:     msg = _("too similar");

Un rapido controllo su "obscure.c" dà questo (sto solo incollando il pezzo di codice pertinente):

static const char *password_check (
    const char *old,
    const char *new,
    const struct passwd *pwdp)
{
    const char *msg = NULL;
    char *oldmono, *newmono, *wrapped;

    if (strcmp (new, old) == 0) {
            return _("no change");
    }
    [...]
    if (palindrome (oldmono, newmono)) {
            msg = _("a palindrome");
    } else if (strcmp (oldmono, newmono) == 0) {
            msg = _("case changes only");
    } else if (similar (oldmono, newmono)) {
            msg = _("too similar");
    } else if (simple (old, new)) {
            msg = _("too simple");
    } else if (strstr (wrapped, newmono) != NULL) {
            msg = _("rotated");
    } else {
    }
    [...]
    return msg;
}

Quindi, ora sappiamo che esiste una funzione "simile" che si basa sul vecchio e sul nuovo controllo se entrambi sono simili. Ecco il frammento:

/*
 * more than half of the characters are different ones.
 */
static bool similar (const char *old, const char *new)
{
    int i, j;

    /*
     * XXX - sometimes this fails when changing from a simple password
     * to a really long one (MD5).  For now, I just return success if
     * the new password is long enough.  Please feel free to suggest
     * something better...  --marekm
     */
    if (strlen (new) >= 8) {
            return false;
    }

    for (i = j = 0; ('\0' != new[i]) && ('\0' != old[i]); i++) {
            if (strchr (new, old[i]) != NULL) {
                    j++;
            }
    }

    if (i >= j * 2) {
            return false;
    }

    return true;
}

Non ho rivisto il codice C. Mi sono limitato a fidarmi del commento appena prima della definizione della funzione :-)


La differenziazione tra piattaforme compatibili con PAM e NON-PAM è definita nel file "obscure.c" strutturato come:

#include <config.h>
#ifndef USE_PAM
[...lots of things, including all the above...]
#else                           /* !USE_PAM */
extern int errno;               /* warning: ANSI C forbids an empty source file */
#endif                          /* !USE_PAM */

9
Questa è una risposta lunga che non sembra rispondere direttamente alla domanda su come può essere confrontata con la vecchia password quando le password sono sottoposte a hash.
jamesdlin,

10
@jamesdlin: come indicato nel commento di Rinzwind alla domanda originale, gli hash NON svolgono alcun ruolo in questa materia: quando si emette il comando "passwd" per cambiare la password, è necessario fornire sia la "vecchia" che la "nuova" password. Quindi il codice "passwd" non ha alcun problema nel confrontare / controllare entrambe le password contemporaneamente (in forme chiare, senza hash).
Damiano Verzulli,

3
@DamianoVerzulli Tuttavia, questo non risolve davvero la domanda. La domanda non era "quale codice C usi per dire se due stringhe sono simili;" è esattamente lo stesso per le password come per qualsiasi altra cosa. La cosa sulle password che li rende interessanti è che non sono mai archiviati in testo normale, ed è quello che la domanda pone. Questo risponde "quali criteri vengono utilizzati e come viene fatto in C", ma è troppo lungo per "quali criteri" e "come dovrei farlo in C" è una domanda SO, non una domanda SU.
cpast

7
@DamianoVerzulli E il fatto che passwdrichiede password vecchie e nuove è la risposta . Il resto di questa risposta è irrelvant.
jamesdlin,

3
+1 per una risposta estremamente pertinente e interessante! È bello vedere che il codice di confronto della password effettiva funziona effettivamente sul testo in chiaro e, come previsto, non sull'hash.
nico,

36

La risposta è molto più semplice di quanto pensi. In effetti, quasi si qualifica come magia, perché una volta spiegato il trucco, è andato:

$ passwd
Current Password:
New Password:
Repeat New Password:

Password changed successfully

Sa che la tua nuova password è simile ... Perché hai digitato la vecchia solo un momento prima.


2
"... o caramelle."
Nick T,

1
Silly rabbit, trix sono per i bambini!
iAdjunct,

1
Ciò che non spiega è quando conosce le tue passate n password :) "La password è stata utilizzata troppo di recente", il che impedisce di scambiare le stesse poche password in un ambiente aziendale.
Juha Untinen,

3
@Juha Untinen: è vero, ma può essere gestito semplicemente ricordando gli ultimi hash N. Catturare "uguale all'ennesima password" è facile, è " simile all'ennesima password" che è difficile. Per quanto ne so, questi sistemi controllano solo la somiglianza con l'ultima password e l'identità con l'ultimo N. Se controllano la somiglianza con l'ultimo N ... è un trucco davvero interessante ora, non è vero! Non ho idea di come lo farebbero.
Cort Ammon,

7

Anche se le altre risposte sono giuste, potrebbe valere la pena ricordare che non è necessario fornire la vecchia password per farlo funzionare!

In effetti, è possibile generare un gruppo di password simile alla nuova password fornita, l'hash e quindi verificare se uno di questi hash corrisponde a quello precedente. In questo caso, la nuova password viene giudicata simile a quella precedente! :)


2
Anche se questo è davvero un mezzo per raggiungere questa impresa (ed è usato da molti siti Web), non è quello che sta succedendo in questo caso.
Brian S

Questo è un trucco pulito! Un po 'più intensivo dal punto di vista computazionale, ma intelligente!
Cort Ammon,

Dovresti almeno dare una stima di quante password simili dovrebbero essere generate per avere un controllo significativo o un collegamento a una risorsa esterna. Altrimenti questa è solo un'idea di una possibile alternativa, non una risposta motivata.
hyde,

@hyde che dipende da criteri a cui qualcuno potrebbe pensare. Per me le password sono simili se sono stati aggiunti / rimossi / modificati al massimo 3 caratteri. Quindi sono 62 hash per ogni carattere (e questo se usiamo solo caratteri alfanumerici) per una combinazione di 3 dalla lunghezza della password ( n) 62 * (n!)/(6 * (n - 3)!), che equivale a 13540 per una password lunga 12 caratteri. Ma se qualcuno pensa a qualcosa di diverso, l'equazione è inutile, quindi perché preoccuparsi?
Killah,

Risposta stupida, ma comunque un'idea. Perché stupido? 1. Dovresti generare un numero inimmaginabile di hash. 2. Tale impostazione indebolirebbe la sicurezza della password originale. Se qualcuno ottenesse hash di tutte le password simili invece di un solo hash, avrebbero molto più tempo per decifrarlo.
Rok Kralj,

5

Un aspetto non è stato trattato: la cronologia delle password. Alcuni sistemi supportano questo. Per fare ciò, mantiene una cronologia delle password e le crittografa con la password corrente. Quando si modifica la password, utilizza la "vecchia" password per decrittografare l'elenco e verificarlo. E quando imposta una nuova password, salva l'elenco (di nuovo) crittografato con una chiave derivata dalla nuova password.

Ecco come remember=Nfunziona in PAM (memorizzato in /etc/security/opasswd). Ma anche Windows e altri fornitori Unix offrono funzioni simili.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.