Як Linux знає, що новий пароль схожий на попередній?


145

Кілька разів я намагався змінити пароль користувача на різних машинах Linux, і коли новий пароль був подібний до старого, ОС скаржилася, що вони занадто схожі.

Я завжди цікавився, як система це знає? Я подумав, що пароль зберігається як хеш. Чи означає це, що коли система зможе порівняти новий пароль за подібністю, старий фактично зберігається як звичайний текст?


30
1-й випуск: звичайний текст? немає. Якщо (!) Збережено, ви збережіть хеш і порівняйте хеші. У Linux хоча він перевіряє поточний пароль новим паролем. BOTH надаються користувачем при зміні паролів.
Rinzwind

42
@Rinzwind Але порівнювати хеші не вийде, оскільки одна різниця символів має призвести до зовсім іншого хешу
slhck

17
Дивіться також: Чи зберігає Facebook текстові паролі? щодо інформаційної безпеки для інших способів виявлення подібності з урахуванням лише хешу старого пароля та простого тексту нового пароля (без відкритого тексту для старого).
Боб

21
Насправді ви можете перевірити подібність між старим хешованим паролем та новим паролем простого тексту. Просто генеруйте список паролів, схожих на новий, хеш їх усіх та порівняйте отримані хеші зі старими хешами паролів. Якщо будь-яка відповідність, то це схоже.
BWG

2
@BWG: Це незначне спрощення - поточні схеми хешування солять хеш, тому спочатку вам потрібно витягнути сіль із старого хешу паролів і переконайтеся, що ви використовуєте цю сіль для своїх подібних до нових паролів. (Я вказую на це, тому що можливо, що API не відкриє спосіб примусити конкретну сіль.)
Ульріх Шварц

Відповіді:


156

Оскільки під час використання вам потрібно надати і старий, і новий пароль passwd, їх можна легко порівняти в простому тексті, в пам'яті, не записуючи їх десь на диску.

Дійсно, ваш пароль хеширується, коли він остаточно зберігається, але поки це не станеться, інструмент, де ви вводите свій пароль, звичайно, може просто отримати доступ до нього безпосередньо, як і будь-яка інша програма, може отримати доступ до речей, які ви ввели на клавіатурі під час читання з STDIN.

Це особливість системи PAM, яка використовується у фоновому режимі passwdінструменту. PAM використовується сучасними дистрибутивами Linux.

Більш конкретно, pam_cracklibце модуль для PAM, який дозволяє відхиляти паролі на основі декількох недоліків, які роблять їх дуже вразливими.

Не просто паролі, які занадто схожі, можна вважати небезпечними. У вихідному коді є різні приклади того, що можна перевірити, наприклад, чи є пароль паліндром чи відстань редагування між двома словами. Ідея полягає в тому, щоб зробити паролі більш стійкими проти атак на словники.

Дивіться також сторінку pam_cracklib.


чи є у вас ідеї "як" ваше пояснення відповідає аргументам, повідомленим у моїй відповіді? Чи є два різні підходи, застосовані програмою "passwd", коли хост не знає PAM? PS: Критики взагалі немає. Мені просто цікаво (як PAM, BTW, було моїм першим здогадком ... перед тим, як привітати вихідний код).
Даміано Верзуллі

27
Більш тривожними є правила корпоративного пароля, які попереджають вас, якщо ви використовували той самий чи подібний пароль серед будь-якого з останніх чотирьох.
Нік Т

4
@NickT Як це (обов'язково) тривожно - чи не могли вони просто зберегти останні 4 хеші, а потім порівняти кожен із запропонованих нових так само, як це питання?
neminem

1
@neminem "... або подібне"
Нік Т

1
@NickT Ах, досить чесно, адже в цьому конкретному випадку ви порівнюєте "старий пароль", який вводиться користувачем для зміни пароля, а не проти збереженого хеша. Тим не менш, ви можете гіпотетично використовувати метод BWG, розміщений у коментарі, для принаймні перевірки дійсно простих змін (одна заміна символів, один доданий / видалений символ тощо).
neminem

46

Принаймні в моєму Ubuntu, "надто схожі" повідомлення виписуються коли: "... більше половини символів є різними ...." (детальніше див. нижче). завдяки підтримці PAM, як чітко пояснено у відповіді @slhck.

Для інших платформ, де PAM не використовується, повідомлення "надто схожих" виходять, коли: "... більше половини символів є різними ...." (детальніше див. Нижче)

Щоб додатково перевірити цю заяву самостійно, можна перевірити вихідний код. Ось як.

Програма "passwd" включена в пакет passwd:

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

Оскільки ми маємо справу з технологіями з відкритим кодом, у нас є необмежений доступ до вихідного коду. Отримати це так просто, як:

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

Згодом легко знайти відповідний фрагмент коду:

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");

Швидкий перевір на "obscure.c" дає це (я вирізаю і вставляю лише відповідний фрагмент коду):

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;
}

Отже, тепер ми знаємо, що існує "аналогічна" функція, яка базується на перевірці старого та нового - чи обидва схожі. Ось фрагмент:

/*
 * 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;
}

Я не переглянув код С. Я обмежився довірою коментаря перед визначенням функції :-)


Розмежування платформ, відомих PAM та NON-PAM, визначається у файлі "obscure.c", який структурується так:

#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
Це довга відповідь, яка, схоже, не відповідає безпосередньо на питання про те, як вона може порівнюватися зі старим паролем, коли паролі є хешованими.
jamesdlin

10
@jamesdlin: як зазначено в коментарі Rinzwind до оригінального питання, хеші НЕ грають жодної ролі в цьому питанні: коли ви видаєте команду "passwd" для зміни пароля, вам потрібно ввести і "старий", і "новий" пароль. Тож код "passwd" взагалі не має проблем у порівнянні / перевірці обох паролів одразу (у чітких формах; взагалі не хешировано).
Даміано Верзуллі

3
@DamianoVerzulli Тим не менш, це насправді не вирішує питання. Питання було не в тому, "який код С ви використовуєте, щоб сказати, чи схожі дві струни"; це точно так само для паролів, як і для всього іншого. Що стосується паролів, що робить їх цікавими, це те, що вони ніколи не зберігаються в простому тексті, і саме про це задається питання. Це дає відповідь "які критерії використовуються та як це робиться в C", але це занадто довго, щоб "які критерії" та "як би я це робив на C" - це питання, а не питання SU.
cpast

7
@DamianoVerzulli І те, що passwdзапитує і старі, і нові паролі, - це відповідь . Решта цієї відповіді нерелевантна.
jamesdlin

3
+1 за та надзвичайно актуальну та цікаву відповідь! Приємно бачити, що фактичний код порівняння пароля насправді працює на простому тексті і, як очікується, не на хеші.
nico

36

Відповідь набагато простіша, ніж ви думаєте. Насправді це майже кваліфікується як магія, тому що як тільки ви поясните фокус, він пропаде:

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

Password changed successfully

Він знає, що ваш новий пароль схожий ... Тому що ви ввели старий лише за мить до цього.


2
"... або цукерки."
Нік Т

1
Дурний кролик, трикс для дітей!
iAdjunct

1
Чого він не пояснює, коли він знає ваші минулі n паролів :) "Пароль був використаний занадто недавно", що запобігає заміні стільки ж паролів у корпоративному середовищі.
Juha Untinen

3
@Juha Untinen: Це правда, але це можна вирішити, просто запам'ятавши останні N хешів. Ловити "те саме, що й N-й пароль" легко, його " схожий на N-й пароль" важко. Наскільки мені відомо, ці системи перевіряють лише подібність з останнім паролем, і однаковість з останнім N. Якщо вони перевіряють схожість з останнім N ... це справді цікавий трюк, чи не так! Я поняття не маю, як вони це зробили.
Корт Аммон

7

Хоча інші відповіді вірні, можливо, варто згадати, що вам не потрібно вводити старий пароль, щоб це працювало!

Насправді, можна створити купу паролів, подібних до нового пароля, який ви ввели, хеште їх, а потім перевірте, чи відповідає якийсь із цих хешів старому. Якщо це так, то новий пароль оцінюється аналогічно старому! :)


2
Хоча це справді засіб для досягнення цього подвигу (і використовується багатьма веб-сайтами), у цьому випадку це не те, що відбувається.
Брайан S

Це акуратний трюк! Більше трохи обчислювально інтенсивно, але розумно!
Корт Аммон

Ви повинні хоча б дати деяку оцінку, скільки подібних паролів потрібно сформувати, щоб мати значущу перевірку або посилання на зовнішній ресурс. Інакше це лише ідея можливої ​​альтернативи, а не обґрунтована відповідь.
Гайда

@hyde, що залежить від критеріїв, які хтось може придумати. Для мене паролі схожі, якщо було додано / видалено / змінено максимум 3 символи. Отже, це 62 хеші для кожного символу (і це, якщо ми використовуємо лише буквено-цифрові), комбінація разів 3 - тривалість пароля ( n) 62 * (n!)/(6 * (n - 3)!), що становить 13540 для пароля , що триває 12 символів. Але якщо хтось думає про щось інше, рівняння марне, то навіщо турбуватися?
Кілла

Дурна відповідь, але розуміння все-таки. Чому дурний? 1. Вам доведеться генерувати немислиму кількість хешей. 2. Така установка послабить безпеку вихідного пароля. Якщо хтось отримав хеші всіх подібних паролів замість одного хешу, вони мали б набагато простіший час зламати його.
Rok Kralj

5

Один аспект не висвітлювався: історія паролів. Деякі системи це підтримують. Для цього він зберігає історію паролів і зашифровує їх поточним паролем. При зміні пароля він використовує "старий" пароль для розшифрування списку та підтвердження. І коли він встановлює новий пароль, він зберігає список (знову) зашифрований ключем, отриманим з нового пароля.

Так remember=Nпрацює PAM (зберігається в /etc/security/opasswd). Але також Windows та інші постачальники Unix пропонують подібні функції.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.