Шифрование паролей в Py — MailCGI

shifrovanie parolej v py mailcgi Сервер PyMailCGI

Выше мы вкратце обсуждали подход к защите паролей, принятый в Py- MailCGI. Здесь мы рассмотрим его конкретную реализацию. Программа PyMailCGI передает имя пользователя и пароль между страницами с помощью скрытых полей форм и параметров запроса в адресах URL, встраиваемых в разметку HTML страниц. Мы рассмотрели эти приемы в предыдущей главе. Такие данные передаются через сетевые сокеты в виде простого текста — внутри разметки HTML ответа сервера — и в виде параметров в запросах, посылаемых клиентом. При таком подходе возникает проблема защиты секретных данных.

Эта особенность не является проблемой при использовании локального веб-сервера, как и во всех примерах до сих пор. Данные в этом случае передаются между двумя программами, выполняющимися на одном и том же компьютере, и недоступны внешнему миру. Однако если вам потребуется установить PyMailCGI на удаленный веб-сервер, это может стать проблемой. Поскольку эти данные желательно хранить втайне от посторонних, в идеале хотелось бы иметь способ скрывать их при передаче и предотвращать возможность подсмотреть их в файлах журналов на сервере. С появлением новых и уходом старых возможностей приемы решения этой проблемы неоднократно изменялись на протяжении жизни этой книги:

     Во втором издании этой книги был разработан собственный модуль шифрования, использующий модуль шифрования rotor из стандартной библиотеки. Этот модуль использовался для шифрования данных, вставляемых в поток ответа сервера, и затем для расшифровывания данных, возвращаемых клиентом в параметрах. К сожалению, модуль rotor был исключен из стандартной библиотеки в версии Python 2.4 из-за проблем, связанных с безопасностью. Возможно, это было слишком радикальное решение (модуль rotor вполне пригоден для использования в простых приложениях), тем не менее, в последних версиях Python модуль rotor более недоступен.

     В третьем издании модель второго издания была расширена за счет добавления поддержки шифрования паролей с помощью сторонних модулей и открытой системы PyCrypto. К сожалению, эта система доступна только для Python 2.X и к моменту написания этих строк для четвертого издания в середине 2010 года версия для 3.X еще не вышла (хотя некоторый прогресс в этом направлении имеется). Кроме того, классы Python с реализацией веб-сервера, выполняемого локально и используемого в этом издании для опробования примеров, в Python 3.1 все еще не поддерживают защищенный протокол HTTPS — законченное решение, обеспечивающее безопасность в Веб, о котором я расскажу чуть ниже.

     Вследствие всего вышеперечисленного в этом четвертом издании сохранена унаследованная поддержка модуля rotor и системы PyCryp- to, если они будут установлены, а на крайний случай реализовано упрощенное шифрование пароля, алгоритм которого можно изменять для каждой установки PyMailCGI. Поскольку эту версию в целом можно считать лишь прототипом, дальнейшее улучшение этой модели, включая поддержку HTTPS при выполнении под управлением более надежных веб-серверов, я оставляю в качестве самостоятельного упражнения.

В целом существуют различные подходы к шифрованию информации, передаваемой между клиентом и сервером. Но, к сожалению, ни один из них нельзя реализовать настолько просто, чтобы использовать в качестве примера в этой книге, ни один из них не является универсальным и большинство из них требуют использования инструментов и приемов, знакомство с которыми выходит далеко за рамки этой книги. Тем не менее, для общего знакомства в следующем разделе приводится краткое описание некоторых из наиболее распространенных методик.

Шифрование данных вручную: rotor

(более не существующий)

В принципе, сценарии CGI могут вручную шифровать любые данные, добавляемые в поток ответа, как это было реализовано в версии PyMailCGI для второго издания этой книги. Однако с исключением модуля rotor из версии Python 2.4 в стандартной библиотеке не осталось инструментов шифрования для решения этой задачи. Кроме того, использование программного кода из оригинального модуля rotor нежелательно, с точки зрения сопровождения; к тому же задействовать его не так просто, потому что он был написан на языке C (недостаточно будет просто скопировать файл .py из более ранней версии Python). Если только вы не используете старую версию Python, модуль rotor практически недоступен.

Главным образом из исторического интереса и для сравнения с современными приемами ниже демонстрируется, как использовался этот модуль. Он был основан на алгоритме шифрования Enigma: создавался новый объект rotor с ключом (и, при необходимости, со счетчиком циклов) и вызывались его методы encrypt и decrypt:

>  >> import rotor

>  >> r = rotor.newrotor(‘pymailcgi’) # (ключ, [,счетчик])

>  >> r.encrypt(‘abc123′) # может возвращать непечатаемые символы

\323an\021\224′

>  >> x = r.encrypt(‘spam123′) # результат имеет ту же длину, что

>  >> x # и исходная строка

‘* _\344\011pY’

>  >> len(x)

7

>  >> r.decrypt(x)

‘spam123’

Обратите внимание, что один и тот же объект rotor может зашифровывать несколько строк, результат может содержать непечатаемые символы (выводимые как экранированные последовательности \ascii) и длина результата всегда совпадает с длиной исходной строки. Самое главное, что строка, зашифрованная с помощью объекта rotor, может быть расшифрована в другом процессе (например, позднее другим сценарием CGI), если объект rotor создать заново:

>  >> import rotor

>  >> r = rotor.newrotor(‘pymailcgi‘) # может быть расшифрована в др. процессе

>  >> r.decrypt(‘* _\344\011pY‘) # 2 символа представлены экранированными

spam123′ # последовательностями "\ascii"

Наш модуль secret по умолчанию использует для шифрования только объект rotor и не реализует никаких собственных алгоритмов шифрования. Он полагается на экранирование адресов URL при встраивании пароля в параметр URL и экранирование HTML при встраивании пароля в скрытые поля форм. Для URL производятся следующие вызовы:

>   >> from secret import encode, decode

>   >> x = encode(‘abc$#<>&+’) # это делают сценарии CGI

>>> x

\323a\016\317\326\023\0163′

>   >> import urllib.parse # это делает urlencode

>   >> y = urllib.parse.quote_plus(x)

>   >> y

‘+%d3a%0e%cf%d6%13%0e3’

>   >> a = urllib.parse.unquote_plus(y) # это делает cgi.FieldStorage

>>> a

\323a\016\317\326\023\0163′

>   >> decode(a) # это делают сценарии CGI

abc$#<>&+’

Несмотря на то, что в настоящее время модуль rotor используется уже не так широко, те же приемы можно использовать для реализации других алгоритмов шифрования.

Использованная литература:

Марк Лутц — Программирование на Python, 4-е издание, II том, 2011

Каталог сайтов Всего.ру
Оцените статью
Секреты программирования
Добавить комментарий