Содержание страницы
35.5. crypt– Функция для проверки паролей Unix¶crypt – Function to check Unix passwords
Исходный код: Lib/crypt.py
Этот модуль реализует интерфейс к crypt(3), которая является односторонней хэш-функцией на основе модифицированного алгоритма DES; за дополнительными сведениями обратитесь к man-странице Unix. Возможные применения включают хранение хэшированных паролей, чтобы можно было проверять пароли без хранения фактического пароля, или попытку взлома паролей Unix с помощью словаря.
Обратите внимание, что поведение этого модуля зависит от фактической реализации crypt(3) в работающей системе. Поэтому все расширения, доступные в текущей реализации, будут доступны и в этом модуле.
35.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 символов. Это самый слабый метод.
35.5.2. Атрибуты модуля¶Module Attributes
Новое в версии 3.3.
-
crypt.methods¶ Список доступных алгоритмов хеширования паролей в виде объектов
crypt.METHOD_*. Этот список отсортирован от самого надежного к самому слабому.
35.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()).Возвращаемое значение – строка длиной 2 символа для
crypt.METHOD_CRYPT, или 19 символов, начинающаяся с$digit$и 16 случайных символов из набора[./a-zA-Z0-9], подходящая для передачи в качестве аргумента salt вcrypt().Новое в версии 3.3.
35.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")