Вопрос: Как Linux знает, что новый пароль похож на предыдущий?


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

Я всегда задавался вопросом, как система знает это? Я думал, что пароль сохранен как хэш. Означает ли это, что, когда система может сравнить новый пароль для сходства, старый фактически сохраняется как обычный текст?


140
2017-12-27 17:22


Источник


1-й выкл: обычный текст? нет. Если (!) Сохранено, вы сохраняете хэш и сравниваете хэши. В Linux, хотя он проверяет текущий пароль с новым паролем. BOTH предоставляется пользователем при смене паролей. - Rinzwind
@Rinzwind. Но сравнение хэшей не будет работать, потому что разница в одном символе должна привести к совершенно другому хэшу - slhck
Смотрите также Удерживает ли Facebook текстовые пароли? на Информационная безопасность для других способов обнаружения сходства, учитывая только хэш старого пароля и открытого текста нового пароля (без открытого текста для старого). - Bob
Фактически вы можете проверить сходство между хэшированным старым паролем и новым паролем открытого текста. Просто создайте список паролей, похожих на новый, хешируйте их все и сравните полученные хэши с старым хэшем пароля. Если какое-либо совпадение, то это похоже. - BWG
@BWG: Это небольшое упрощение - текущие схемы хэширования сольют хеш, поэтому сначала вам нужно извлечь соль из старого хеша пароля и убедиться, что вы используете эту соль для своих похожих на новые пароли. (Я указываю это, потому что возможно, что API не будет выставлять способ принудительного использования соли). - Ulrich Schwarz


Ответы:


Поскольку вам нужно поставлять как старые а также новый пароль при использовании passwd, их можно легко сравнивать в открытом тексте в памяти, не записывая их где-нибудь на диске.

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

Это особенность Система PAM который используется на фоне passwd инструмент. PAM используется современными дистрибутивами Linux.

Более конкретно, pam_cracklib является модулем для PAM, который позволяет отбросить пароли на основе нескольких слабых мест, которые сделают их очень уязвимыми.

Это не просто пароли, которые слишком похожи, что можно считать небезопасными. исходный код  имеет различные примеры того, что можно проверить, например. является ли пароль палиндром или расстояние редактирования между двумя словами. Идея состоит в том, чтобы сделать пароли более устойчивыми к атакам со словарем.

Смотрите также pam_cracklib страница руководства.


154
2017-12-27 19:27



у вас есть идеи в том, «как» ваше объяснение соответствует аргументам, указанным в моем ответе? Существуют ли два разных подхода, предпринятых приложением «passwd», когда хост не PAM-курс? P.S .: Никаких критиков вообще. Мне просто интересно (как PAM, BTW, было мое первое предположение ... прямо перед grepping исходным кодом). - Damiano Verzulli
Более тревожными являются правила корпоративного пароля, которые предупреждают вас, если вы использовали один и тот же или похожий пароль среди любого из последних четырех. - Nick T
@NickT Как это (обязательно) беспокоит - не могли бы они просто сохранить ваши последние 4 хэша, а затем сравнить каждый из них с предложенным вами новым так же, как этот вопрос? - neminem
@neminem "... или подобный" - Nick T
@NickT Ah, справедливо, потому что в этом конкретном случае вы сравниваете с «старым паролем», который вводит пользователь для изменения пароля, а не против сохраненного хэша. Но вы мог гипотетически использовать метод BWG, размещенный в комментарии, по крайней мере, для проверки действительно простых изменений (замена одного символа, добавление / удаление одного символа и т. д.). - neminem


По крайней мере, в моем 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;
}

Я не просмотрел код C. Я ограничился доверием комментарию перед определением функции :-)


Дифференциация между платформами PAM и NAM-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 */

45
2017-12-28 18:14



Это длинный ответ, который, похоже, не отвечает на вопрос о том, как он может сравниваться со старым паролем, когда пароли становятся хэшированными. - jamesdlin
@jamesdlin: как указано в комментарии Rinzwind к исходному вопросу, хеши делают НЕ играйте любую роль в этом вопросе: когда вы выдаете команду «passwd» для смены пароля, вам необходимо предоставить как «старый», так и «новый» пароль. Таким образом, код «passwd» вообще не имеет проблем при сравнении / проверке пароля одновременно (в ясных формах, а не в хэшировании вообще). - Damiano Verzulli
@DamianoVerzulli Тем не менее, это на самом деле не затрагивает вопрос. Вопрос не в том, «какой код C вы используете, чтобы определить, схожи ли две строки»; это точно так же для паролей, как и для всего остального. Дело в том, что пароли что делает их интересными, так это то, что они никогда не хранятся в открытом тексте, и об этом и спрашивается. Это отвечает «какие критерии используются и как это делается на C», но слишком долго для «каких критериев» и «как бы я это делал в C» является вопросом SO, а не вопросом SU. - cpast
@DamianoVerzulli И тот факт, что passwd запрашивает как старые, так и новые пароли это ответ, Остальная часть этого ответа безответственна. - jamesdlin
+1 за и очень актуальный и интересный ответ! Приятно видеть, что фактический код, сравнивающий пароль, фактически работает с открытым текстом и, как и ожидалось, не на хеше. - nico


Ответ намного проще, чем вы думаете. Фактически, он почти квалифицируется как волшебство, потому что, как только вы объясняете трюк, он ушел:

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

Password changed successfully

Он знает, что ваш новый пароль похож ... Потому что вы набрали старый за мгновение раньше.


37
2017-12-29 13:41



«... или конфеты». - Nick T
Глупый кролик, трикс для детей! - iAdjunct
Это не объясняет, когда он знает ваши прошлые n паролей :) «Пароль был использован слишком недавно», что предотвращает замену нескольких паролей в корпоративной среде. - Juha Untinen
@Juha Untinen: Это правда, но это можно решить, просто вспомнив последние х хэши. Ловить «то же, что и N-й пароль», легко, его "аналогичный до N-го пароля ". Насколько мне известно, эти системы проверяют только на сходство с последним паролем и одинаковость с последним N. Если они проверяют сходство с последним N ... это действительно интересно трюк сейчас, не так ли? Я понятия не имею, как они это сделают. - Cort Ammon


Хотя другие ответы правильные, может быть стоит упомянуть, что вам не нужно предоставлять старый пароль для этого!

Фактически, можно создать кучу паролей, похожих на новый пароль, который вы указали, слить их, а затем проверить, соответствует ли какой-либо из этих хэшей старый. Если это так, то новый пароль считается похожим на старый! :)


8
2018-01-02 11:06



Хотя это действительно средство для достижения этого успеха (и используется многими веб-сайтами), это не то, что происходит в этом случае. - Brian S
Это аккуратный трюк! Слишком много вычислительных, но умных! - Cort Ammon
Вы должны хотя бы дать некоторую оценку того, сколько подобных паролей нужно будет генерировать, чтобы иметь значимую проверку или ссылку на внешний ресурс. В противном случае это всего лишь идея возможной альтернативы, а не обоснованный ответ. - hyde
@hyde, который зависит от критериев, которые кто-то может придумать. Для меня пароли похожи, если было добавлено максимум 3 символа / удалено / изменено. Так что это 62 хэша для каждого персонажа (и это если мы используем только буквенно-цифровые символы), умножая комбинацию из 3 по длине пароля (n), который 62 * (n!)/(6 * (n - 3)!), что равно 13540 для пароля на 12 символов. Но если кто-то думает о чем-то другом, то уравнение бесполезно, так зачем беспокоиться? - Killah
Глупый ответ, но все же проницательность. Почему глупо? 1. Вам нужно создать невообразимое количество хэшей. 2. Такая настройка ослабит безопасность исходного пароля. Если бы кто-то получил хэши всех подобных паролей, а не только один хэш, у них было бы намного легче взломать его. - Rok Kralj


Один аспект не был рассмотрен: история паролей. Некоторые системы поддерживают это. Для этого он хранит историю паролей и шифрует их с помощью текущего пароля. Когда вы меняете свой пароль, он использует «старый» пароль для расшифровки списка и проверки. И когда он устанавливает новый пароль, он сохраняет список (заново) зашифрованным ключом, полученным из нового пароля.

Вот как remember=N работает в PAM (хранится в /etc/security/opasswd). Но и Windows и другие производители Unix предлагают аналогичные функции.


4