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.

ОШИБКИ

EINVAL
    Значение salt имеет неверный формат.

ENOSYS
    Функция crypt() не реализована, возможно, из-за запретов США на экспорт алгоритмов шифрования.

EPERM
    Значение /proc/sys/crypto/fips_enabled не равно нулю, но делается попытка использовать нестойкий тип шифрования, такой как DES.

АТРИБУТЫ
Описание терминов данного раздела смотрите в attributes(7).
Интерфейс | Атрибут | Значение
crypt() | Безвредность в нитях | MT-Unsafe race:crypt
crypt_r() | Безвредность в нитях | MT-Safe

СООТВЕТСТВИЕ СТАНДАРТАМ
crypt(): POSIX.1-2001, POSIX.1-2008, SVr4, 4.3BSD. Функция crypt_r() является расширением GNU.

ЗАМЕЧАНИЯ

  Доступность в glibc
Функции 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
Версия этой функции, реализованная в 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 в остальных случаях.

СМОТРИТЕ ТАКЖЕ
login(1), passwd(1), encrypt(3), getpass(3), passwd(5)