Содержание страницы
34.5. crypt – Функция для проверки паролей Unix¶crypt – Function to check Unix passwords
Этот модуль реализует интерфейс к crypt(3), которая является односторонней хэш-функцией на основе модифицированного алгоритма DES; за дополнительными сведениями обратитесь к man-странице Unix. Возможные применения включают хранение хэшированных паролей, чтобы можно было проверять пароли без хранения фактического пароля, или попытку взлома паролей Unix с помощью словаря.
Обратите внимание, что поведение этого модуля зависит от фактической реализации crypt(3) в работающей системе. Поэтому все расширения, доступные в текущей реализации, будут доступны и в этом модуле.
34.5.1. Методы хеширования¶Hashing Methods
Новое в версии 3.3.
Модуль crypt определяет список методов хеширования (не все методы доступны на всех платформах):
- crypt.METHOD_SHA512¶
Метод Modular Crypt Format с 16-символьной солью и 86-символьным хешем. Это самый надёжный метод.
- crypt.METHOD_SHA256¶
Ещё один метод Modular Crypt Format с 16-символьной солью и 43-символьным хешем.
- crypt.METHOD_MD5¶
Ещё один метод Modular Crypt Format с 8-символьной солью и 22-символьным хешем.
- crypt.METHOD_CRYPT¶
Традиционный метод с солью из 2 символов и хешем из 13 символов. Это самый слабый метод.
34.5.2. Атрибуты модуля¶Module Attributes
Новое в версии 3.3.
- crypt.methods¶
Список доступных алгоритмов хеширования паролей в виде объектов crypt.METHOD_*. Этот список отсортирован от самого стойкого к самому слабому и гарантированно содержит как минимум crypt.METHOD_CRYPT.
34.5.3. Функции модуля¶Module Functions
Модуль crypt определяет следующие функции:
- crypt.crypt(word, salt=None)¶
Параметр word обычно содержит пароль пользователя, введённый в командной строке или в графическом интерфейсе. Необязательный параметр salt может быть строкой, возвращённой из mksalt(), одним из значений crypt.METHOD_* (хотя не все могут быть доступны на всех платформах) или полным зашифрованным паролем, включающим соль, как возвращается этой функцией. Если salt не указан, будет использован самый стойкий метод (как возвращается methods()).
Обычно проверка пароля выполняется путём передачи открытого пароля в качестве word и полного результата предыдущего вызова crypt(), который должен совпадать с результатом этого вызова.
Параметр salt (случайная строка из 2 или 16 символов, возможно с префиксом $digit$ для указания метода) используется для модификации алгоритма шифрования. Символы в salt должны принадлежать множеству [./a-zA-Z0-9], за исключением Modular Crypt Format, который добавляет префикс $digit$.
Возвращает хешированный пароль в виде строки, состоящей из символов того же алфавита, что и соль.
Поскольку некоторые расширения crypt(3) допускают различные значения с разными размерами salt, рекомендуется использовать полный зашифрованный пароль в качестве соли при проверке пароля.
Изменено в версии 3.3: Принимает значения crypt.METHOD_* в дополнение к строкам для параметра salt.
- crypt.mksalt(method=None)¶
Возвращает случайно сгенерированную соль для указанного метода. Если параметр method не задан, используется самый стойкий из доступных методов, возвращаемый функцией methods().
Возвращается строка: для crypt.METHOD_CRYPT длиной 2 символа, или 19 символов, начиная с $digit$ и 16 случайных символов из множества [./a-zA-Z0-9]. Такая строка подходит для передачи в качестве аргумента salt в функцию crypt().
Новое в версии 3.3.
34.5.4. Примеры¶Examples
Простой пример, иллюстрирующий типичное использование (требуется операция сравнения за константное время, чтобы ограничить подверженность атакам по времени. Для этой цели подходит hmac.compare_digest()):
import pwd
import crypt
import getpass
from hmac import compare_digest as compare_hash
def login():
username = input('Python login: ')
cryptedpasswd = pwd.getpwnam(username)[1]
if cryptedpasswd:
if cryptedpasswd == 'x' or cryptedpasswd == '*':
raise ValueError('no support for shadow passwords')
cleartext = getpass.getpass()
return compare_hash(crypt.crypt(cleartext, cryptedpasswd), cryptedpasswd)
else:
return True
Чтобы сгенерировать хеш пароля с помощью самого надёжного из доступных методов и проверить его с оригиналом:
import crypt
from hmac import compare_digest as compare_hash
hashed = crypt.crypt(plaintext)
if not compare_hash(hashed, crypt.crypt(plaintext, hashed)):
raise ValueError("hashed version doesn't validate against original")