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.

ОШИБКИ

Значение salt имеет неверный формат.
Функция crypt() не реализована, возможно, из-за запретов США на экспорт алгоритмов шифрования.
Значение /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)

2018-04-30