crypt — Функція для перевірки паролів Unix

Вихідний код: Lib/crypt.py


Цей модуль реалізує інтерфейс до процедури crypt(3), яка є односторонньою хеш-функцією на основі модифікованого алгоритму DES; подробиці див. на сторінці довідки Unix. Можливе використання включає зберігання хешованих паролів, щоб ви могли перевіряти паролі, не зберігаючи справжній пароль, або спробу зламати паролі Unix за допомогою словника.

Зауважте, що поведінка цього модуля залежить від фактичної реалізації підпрограми crypt(3) у запущеній системі. Тому будь-які розширення, доступні для поточної реалізації, також будуть доступні в цьому модулі.

Availability: Unix. Not available on VxWorks.

Методи хешування

Нове в версії 3.3.

Модуль crypt визначає список методів хешування (не всі методи доступні на всіх платформах):

crypt.METHOD_SHA512

Метод Modular Crypt Format із 16-символьним кодом і 86-символьним хешем на основі хеш-функції SHA-512. Це найсильніший метод.

crypt.METHOD_SHA256

Інший метод Modular Crypt Format із 16-символьною сольовою і 43-символьною хеш-функцією на основі хеш-функції SHA-256.

crypt.METHOD_BLOWFISH

Ще один метод Modular Crypt Format із 22 символами і хеш-кодом із 31 символу на основі шифру Blowfish.

Нове в версії 3.7.

crypt.METHOD_MD5

Інший метод Modular Crypt Format із 8-символьною сольовою і 22-символьною хеш-функцією на основі хеш-функції MD5.

crypt.METHOD_CRYPT

Традиційний метод із 2 символами солі та 13 символами хешу. Це найслабший метод.

Атрибути модуля

Нове в версії 3.3.

crypt.methods

Список доступних алгоритмів хешування паролів у вигляді об’єктів crypt.METHOD_*. Цей список відсортовано від найсильнішого до найслабшого.

Функції модуля

Модуль crypt визначає такі функції:

crypt.crypt(word, salt=None)

word will usually be a user’s password as typed at a prompt or in a graphical interface. The optional salt is either a string as returned from mksalt(), one of the crypt.METHOD_* values (though not all may be available on all platforms), or a full encrypted password including salt, as returned by this function. If salt is not provided, the strongest method will be used (as returned by 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, *, rounds=None)

Return a randomly generated salt of the specified method. If no method is given, the strongest method available as returned by methods() is used.

Повернене значення — це рядок, який можна передати як аргумент salt до crypt().

rounds визначає кількість раундів для METHOD_SHA256, METHOD_SHA512 і METHOD_BLOWFISH. Для METHOD_SHA256 і METHOD_SHA512 воно має бути цілим числом від 1000 до 999_999_999, за замовчуванням 5000. Для METHOD_BLOWFISH це має бути ступінь двох між 16 (24) і 2_147_483_648 (231), за замовчуванням 4096 (212).

Нове в версії 3.3.

Змінено в версії 3.7: Додано параметр rounds.

Приклади

Простий приклад, що ілюструє типове використання (операція порівняння в постійному часі необхідна для обмеження впливу часових атак. 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")