CRYPT(3) | Руководство программиста Linux | CRYPT(3) |
crypt, crypt_r - шифрует пароль и данные
#define _XOPEN_SOURCE /* См. feature_test_macros(7) */ #include <unistd.h>
char *crypt(const char *key, const char *salt); #define _GNU_SOURCE /* смотрите feature_test_macros(7) */ #include <crypt.h>
char *crypt_r(const char *key, const char *salt, struct crypt_data *data);
Компонуется при указании параметра -lcrypt.
crypt() — функция шифрования пароля. Она основана на алгоритме стандарта шифрования данных (Data Encryption Standard) с различными расширениями, нацеленными (помимо прочего) на усложнение задачи поиска ключа при помощи специального оборудования.
key — задаваемый пользователем пароль.
salt (соль) — двухсимвольная строка, выбираемая из набора [a-zA-Z0-9./]. Эта строка используется для направления алгоритма по одному из 4096-и путей.
Если взять младшие 7 битов каждого из первых 8 символов key, то получается 56-битный ключ. Этот ключ используется для многократного шифрования константной строки (обычно строки, состоящей из символов «0»). Возвращаемое значение — указатель на зашифрованный пароль, серия из 13-и печатных ASCII-символов (первые два символа содержат salt). Возвращаемое значение указывает на статические данные, которые перезаписываются при каждом вызове.
Предупреждение: количество ключей равно 2**56 т. е. существует 7.2e16 возможных вариантов. Полный перебор этого множестве возможен с помощью большого количества параллельных компьютеров. Программное обеспечение, такое, как crack(1), способно отыскать часть ключей из этого множества, обычно используемых людьми для создания пароля. Поэтому в качестве пароля не стоит, как минимум, использовать простые слова и имена. Рекомендуется использовать программу passwd(1), которая проверяет сложность пароля уже на стадии ввода.
Алгоритм DES имеет некоторые особенности, которые не позволяют использовать интерфейс crypt() для чего-то кроме аутентификации пользователя по паролю. Если вы планируете использовать интерфейс crypt() в проекте шифрования, то лучше не делайте этого. Вместо этого возьмите хорошую книгу по шифрованию или одну из общедоступных библиотек DES.
Функция crypt_r() является реентерабельной версией crypt(). Для учёта и хранения результата в ней используется структура, на которую указывает data. Перед первым вызовом crypt_r() требуется выделить место под структуру и присвоить data->initialized значение 0.
При успешном выполнении возвращает указатель на шифрованный пароль. При ошибке возвращается NULL.
Описание терминов данного раздела смотрите в attributes(7).
Интерфейс | Атрибут | Значение |
crypt() | Безвредность в нитях | MT-Unsafe race:crypt |
crypt_r() | Безвредность в нитях | MT-Safe |
crypt(): POSIX.1-2001, POSIX.1-2008, SVr4, 4.3BSD. Функция crypt_r() является расширением GNU.
Функции crypt(), encrypt(3) и setkey(3) являются частью POSIX.1-2008 XSI Options Group for Encryption и необязательны. Если интерфейсы недоступны, то символическая константа _XOPEN_CRYPT или не определена, или имеет значение -1 и доступность можно проверить во время выполнения с помощью sysconf(3). Такое может случиться, если дистрибутив переключился с glibc crypt на libxcrypt. При перекомпиляции приложений в таких дистрибутивах программист должен проверять доступность _XOPEN_CRYPT и включать <crypt.h> с прототипами функций; в противном случае использовать libxcrypt как ABI-совместимую замену.
Версия этой функции, реализованная в glibc, содержит дополнительные алгоритмы шифрования.
Если salt является строкой символов, начинающейся с «$id$», за которой следует строка, оканчивающаяся «$», то результатом будет:
$id$salt$encrypted
В id указывается метод шифрования, используемый вместо DES; он определяет как понимать оставшуюся часть строки пароля. Поддерживаются следующие значения id:
ID | Метод |
1 | MD5 |
2a | Blowfish (нет в основной ветви glibc; добавлен в |
| некоторых дистрибутивах Linux) |
5 | SHA-256 (начиная с glibc 2.7) |
6 | SHA-512 (начиная с glibc 2.7) |
Таким образом, $5$salt$encrypted и $6$salt$encrypted содержат пароль, зашифрованный функциями на основе SHA-256 и SHA-512, соответственно.
Значение «salt» представляет собой строку длиной до 16 символов, следующую после «$id$» в соли. Часть строки пароля «encrypted» — действительно вычисленный пароль. Размер этой строки постоянен:
MD5 | 22 символа |
SHA-256 | 43 символа |
SHA-512 | 86 символов |
Символы в «salt» и «encrypted» входят в диапазон [a-zA-Z0-9./]. В реализациях MD5 и SHA учитывается всё значение key (а не только первые 8 байт как в DES).
Начиная с glibc 2.7, реализации SHA-256 и SHA-512 поддерживают задаваемое пользователем количество циклов хеширования, по умолчанию 5000. Если символы "$id$" в соли указываются после "rounds=xxx$", где xxx целое, то результат имеет вид
$id$rounds=yyy$salt$encrypted
где yyy — используемое количество циклов хеширования. Количество циклов равно 1000, если значение xxx меньше 1000, 999999999, если xxx больше 999999999, и равно xxx в остальных случаях.
2018-04-30 |