Содержание страницы
18.2. ssl – обёртка TLS/SSL для объектов сокетов¶ssl – TLS/SSL wrapper for socket objects
Исходный код: Lib/ssl.py
Этот модуль предоставляет доступ к шифрованию и аутентификации одноранговых узлов с помощью протокола Transport Layer Security (часто называемого «Secure Sockets Layer») для сетевых сокетов, как на стороне клиента, так и на стороне сервера. В этом модуле используется библиотека OpenSSL. Он доступен на всех современных Unix-системах, Windows, Mac OS X и, вероятно, на других платформах, если на них установлен OpenSSL.
Примечание
Некоторое поведение может зависеть от платформы, поскольку вызовы выполняются к API сокетов операционной системы. Установленная версия OpenSSL также может вызывать различия в поведении.
Предупреждение
Не следует использовать этот модуль без ознакомления с рекомендациями по безопасности. В противном случае может возникнуть ложное ощущение безопасности, поскольку настройки по умолчанию модуля ssl не обязательно подходят для конкретного приложения.
В этом разделе описываются объекты и функции модуля ssl; за более общей информацией о TLS, SSL и сертификатах обращайтесь к документам в разделе «См. также» внизу.
Этот модуль предоставляет класс ssl.SSLSocket, который является производным от типа socket.socket и предоставляет подобную сокету обёртку, которая также шифрует и дешифрует данные, передаваемые через сокет с помощью SSL. Он поддерживает дополнительные методы, такие как getpeercert(), который извлекает сертификат другой стороны соединения, и cipher(), который извлекает шифр, используемый для защищённого соединения.
Для более сложных приложений класс ssl.SSLContext помогает управлять настройками и сертификатами, которые затем могут наследоваться SSL-сокетами, созданными через метод SSLContext.wrap_socket().
18.2.1. Функции, константы и исключения¶Functions, Constants, and Exceptions
- exception ssl.SSLError¶
Возникает для сигнализации об ошибке из нижележащей реализации SSL (в настоящее время предоставляемой библиотекой OpenSSL). Это указывает на некоторую проблему в высокоуровневом уровне шифрования и аутентификации, который накладывается на нижележащее сетевое соединение. Эта ошибка является подтипом OSError. Код ошибки и сообщение экземпляров SSLError предоставляются библиотекой OpenSSL.
Изменено в версии 3.3: SSLError раньше был подтипом socket.error.
- library¶
Строковый мнемонический код, обозначающий подмодуль OpenSSL, в котором произошла ошибка, например SSL, PEM или X509. Диапазон возможных значений зависит от версии OpenSSL.
Новое в версии 3.3.
- reason¶
Строковый мнемонический код, обозначающий причину этой ошибки, например CERTIFICATE_VERIFY_FAILED. Диапазон возможных значений зависит от версии OpenSSL.
Новое в версии 3.3.
- exception ssl.SSLZeroReturnError¶
Подкласс SSLError, возникающий при попытке чтения или записи, когда SSL-соединение было корректно закрыто. Обратите внимание, что это не означает, что нижележащий транспорт (читай TCP) был закрыт.
Новое в версии 3.3.
- exception ssl.SSLWantReadError¶
Подкласс SSLError, возбуждаемый неблокирующим SSL-сокетом при попытке чтения или записи данных, когда требуется получить больше данных по нижележащему TCP-транспорту, прежде чем запрос может быть выполнен.
Новое в версии 3.3.
- exception ssl.SSLWantWriteError¶
Подкласс SSLError, возбуждаемый неблокирующим SSL-сокетом при попытке чтения или записи данных, когда требуется отправить больше данных по нижележащему TCP-транспорту, прежде чем запрос может быть выполнен.
Новое в версии 3.3.
- exception ssl.SSLSyscallError¶
Подкласс SSLError, возбуждаемый при возникновении системной ошибки при попытке выполнения операции над SSL-сокетом. К сожалению, нет простого способа проверить исходный номер errno.
Новое в версии 3.3.
- exception ssl.SSLEOFError¶
Подкласс SSLError, возбуждаемый при внезапном завершении SSL-соединения. Как правило, при возникновении этой ошибки не следует пытаться повторно использовать нижележащий транспорт.
Новое в версии 3.3.
- exception ssl.CertificateError¶
Возникает для сигнализации об ошибке с сертификатом (например, несовпадение имени хоста). Однако ошибки сертификата, обнаруженные OpenSSL, возбуждают SSLError.
18.2.1.1. Создание сокета¶Socket creation
Следующая функция позволяет создать сокет независимо. Начиная с Python 3.2, может быть более гибким использование SSLContext.wrap_socket() вместо этого.
- ssl.wrap_socket(sock, keyfile=None, certfile=None, server_side=False, cert_reqs=CERT_NONE, ssl_version={see docs}, ca_certs=None, do_handshake_on_connect=True, suppress_ragged_eofs=True, ciphers=None)¶
Принимает экземпляр sock типа socket.socket и возвращает экземпляр ssl.SSLSocket, подтипа socket.socket, который оборачивает базовый сокет в контекст SSL. sock должен быть сокетом SOCK_STREAM; другие типы сокетов не поддерживаются.
Для клиентских сокетов построение контекста ленивое; если нижележащий сокет ещё не подключен, построение контекста будет выполнено после вызова connect() на сокете. Для серверных сокетов, если сокет не имеет удалённого узла, предполагается, что это слушающий сокет, и серверная SSL-обёртка автоматически выполняется для клиентских соединений, принятых через метод accept(). wrap_socket() может возбуждать SSLError.
Параметры keyfile и certfile задают необязательные файлы, содержащие сертификат, используемый для идентификации локальной стороны соединения. См. обсуждение Certificates для получения дополнительной информации о том, как сертификат хранится в certfile.
Параметр server_side – это логическое значение, которое определяет, требуется ли от этого сокета поведение серверной или клиентской стороны.
Параметр cert_reqs задаёт, требуется ли сертификат от другой стороны соединения и будет ли он проверен, если предоставлен. Он должен быть одним из трёх значений: CERT_NONE (сертификаты игнорируются), CERT_OPTIONAL (не требуется, но проверяется, если предоставлен) или CERT_REQUIRED (требуется и проверяется). Если значение этого параметра не CERT_NONE, то параметр ca_certs должен указывать на файл с сертификатами ЦС.
Файл ca_certs содержит набор объединённых сертификатов «центров сертификации», которые используются для проверки сертификатов, переданных с другого конца соединения. См. обсуждение Certificates для получения дополнительной информации о том, как организовать сертификаты в этом файле.
Параметр ssl_version определяет, какую версию протокола SSL использовать. Обычно сервер выбирает конкретную версию протокола, а клиент должен подстраиваться под выбор сервера. Большинство версий несовместимы друг с другом. Если параметр не задан, по умолчанию используется PROTOCOL_SSLv23; он обеспечивает наилучшую совместимость с другими версиями.
Ниже приведена таблица, показывающая, какие версии на стороне клиента (по вертикали) могут подключаться к каким версиям на стороне сервера (по горизонтали):
клиент / сервер SSLv2 SSLv3 SSLv23 TLSv1 SSLv2 да нет да нет SSLv3 нет да да нет SSLv23 да нет да нет TLSv1 нет нет да да Примечание
Какие соединения будут успешными, зависит от версии OpenSSL. Например, в некоторых старых версиях OpenSSL (таких как 0.9.7l на OS X 10.4) клиент SSLv2 не мог подключиться к серверу SSLv23. Другой пример: начиная с OpenSSL 1.0.0, клиент SSLv23 не будет фактически пытаться устанавливать SSLv2-соединения, если только явно не включить SSLv2-шифры; для этого можно указать "ALL" или "SSLv2" в качестве параметра ciphers.
Параметр ciphers задаёт доступные шифры для этого объекта SSL. Он должен быть строкой в формате списка шифров OpenSSL.
Параметр do_handshake_on_connect определяет, выполнять ли квитирование SSL автоматически после вызова socket.connect(), или же программа должна вызывать его явно с помощью метода SSLSocket.do_handshake(). Явный вызов SSLSocket.do_handshake() даёт программе контроль над блокирующим поведением операций ввода-вывода сокета, участвующих в квитировании.
Параметр suppress_ragged_eofs определяет, как метод SSLSocket.recv() должен сигнализировать о неожиданном конце файла (EOF) с другого конца соединения. Если указано значение True (по умолчанию), он возвращает обычный EOF (пустой объект bytes) в ответ на ошибки неожиданного EOF, возникающие в базовом сокете; если False, он будет пробрасывать исключения обратно вызывающему коду.
Изменено в версии 3.2: Новый необязательный аргумент ciphers.
18.2.1.2. Генерация случайных чисел¶Random generation
- ssl.RAND_bytes(num)¶
Возвращает num криптостойких псевдослучайных байт. Возбуждает SSLError, если PRNG не был инициализирован достаточным количеством данных или если операция не поддерживается текущим методом RAND. RAND_status() можно использовать для проверки состояния PRNG, а RAND_add() – для инициализации PRNG.
Прочитайте статью в Википедии, Криптографически стойкий генератор псевдослучайных чисел (CSPRNG), чтобы узнать требования к криптографическому генератору.
Новое в версии 3.3.
- ssl.RAND_pseudo_bytes(num)¶
Возвращает (bytes, is_cryptographic): bytes – это num псевдослучайных байт, is_cryptographic равно True, если сгенерированные байты являются криптостойкими. Возбуждает SSLError, если операция не поддерживается текущим методом RAND.
Сгенерированные последовательности псевдослучайных байтов будут уникальными, если они имеют достаточную длину, но не обязательно непредсказуемы. Их можно использовать для некриптографических целей и для некоторых целей в криптографических протоколах, но обычно не для генерации ключей и т.д.
Новое в версии 3.3.
- ssl.RAND_status()¶
Возвращает True, если SSL-генератор псевдослучайных чисел был инициализирован «достаточной» случайностью, и False в противном случае. Можно использовать ssl.RAND_egd() и ssl.RAND_add(), чтобы увеличить случайность генератора псевдослучайных чисел.
- ssl.RAND_egd(path)¶
Если где-то запущен демон сбора энтропии (EGD) и path – это имя пути к сокетному соединению, открытому для него, то из сокета будет прочитано 256 байт случайных данных и добавлено в генератор псевдослучайных чисел SSL для повышения безопасности генерируемых секретных ключей. Обычно это необходимо только в системах, где нет более качественных источников случайности.
См. http://egd.sourceforge.net/ или http://prngd.sourceforge.net/ для получения исходных текстов демонов сбора энтропии.
- ssl.RAND_add(bytes, entropy)¶
Смешивает переданные bytes с SSL-генератором псевдослучайных чисел. Параметр entropy (число с плавающей запятой) является нижней границей энтропии, содержащейся в строке (поэтому всегда можно использовать 0.0). См. RFC 1750 для получения дополнительной информации об источниках энтропии.
18.2.1.3. Обработка сертификатов¶Certificate handling
- ssl.match_hostname(cert, hostname)¶
Проверяет, что cert (в декодированном формате, возвращённом функцией SSLSocket.getpeercert()) соответствует заданному hostname. Применяются правила проверки идентичности HTTPS-серверов, описанные в RFC 2818 и RFC 6125, за исключением того, что IP-адреса в настоящее время не поддерживаются. Помимо HTTPS, эта функция подходит для проверки идентичности серверов в различных протоколах на основе SSL, таких как FTPS, IMAPS, POPS и другие.
CertificateError возбуждается при неудаче. В случае успеха функция ничего не возвращает:
>>> cert = {'subject': ((('commonName', 'example.com'),),)} >>> ssl.match_hostname(cert, "example.com") >>> ssl.match_hostname(cert, "example.org") Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/home/py3k/Lib/ssl.py", line 130, in match_hostname ssl.CertificateError: hostname 'example.org' doesn't match 'example.com'
Новое в версии 3.2.
Изменено в версии 3.3.3: Теперь функция следует RFC 6125, разделу 6.4.3, и не сопоставляет ни множественные подстановочные символы (например, *.*.com или *a*.example.org), ни подстановочный символ внутри фрагмента интернационализированного доменного имени (IDN). Метки IDN A-типа, такие как www*.xn--pthon-kva.org, по-прежнему поддерживаются, но x*.python.org больше не соответствует xn--tda.python.org.
- ssl.cert_time_to_seconds(timestring)¶
Возвращает значение с плавающей запятой, содержащее обычное время в секундах от начала эпохи, для строки времени, представляющей дату “notBefore” или “notAfter” из сертификата.
Вот пример:
>>> import ssl >>> ssl.cert_time_to_seconds("May 9 00:00:00 2007 GMT") 1178694000.0 >>> import time >>> time.ctime(ssl.cert_time_to_seconds("May 9 00:00:00 2007 GMT")) 'Wed May 9 00:00:00 2007'
- ssl.get_server_certificate(addr, ssl_version=PROTOCOL_SSLv3, ca_certs=None)¶
По заданному адресу addr SSL-защищённого сервера, в виде пары (hostname, port-number), получает сертификат сервера и возвращает его в виде строки в кодировке PEM. Если указан ssl_version, используется эта версия протокола SSL для попытки подключения к серверу. Если указан ca_certs, это должен быть файл, содержащий список корневых сертификатов, в том же формате, который используется для одноимённого параметра в wrap_socket(). Вызов попытается проверить сертификат сервера по этому набору корневых сертификатов, и завершится неудачей, если проверка не пройдёт.
Изменено в версии 3.3: Эта функция теперь совместима с IPv6.
- ssl.DER_cert_to_PEM_cert(DER_cert_bytes)¶
Принимая сертификат в виде набора байтов в кодировке DER, возвращает версию того же сертификата в виде строки в кодировке PEM.
- ssl.PEM_cert_to_DER_cert(PEM_cert_string)¶
Принимая сертификат в виде строки ASCII в формате PEM, возвращает последовательность байтов в кодировке DER для того же сертификата.
18.2.1.4. Константы¶Constants
- ssl.CERT_NONE¶
Возможное значение для SSLContext.verify_mode или параметра cert_reqs для wrap_socket(). В этом режиме (по умолчанию) от другой стороны сокетного соединения не требуется сертификатов. Если сертификат получен от другой стороны, никаких попыток его проверки не предпринимается.
См. обсуждение соображений безопасности ниже.
- ssl.CERT_OPTIONAL¶
Возможное значение для SSLContext.verify_mode или параметра cert_reqs для wrap_socket(). В этом режиме от другой стороны сокетного соединения не требуется сертификатов; но если они предоставлены, будет предпринята попытка проверки, и при неудаче будет возбуждено SSLError.
Использование этого параметра требует передачи корректного набора сертификатов ЦС – либо в SSLContext.load_verify_locations(), либо в качестве значения параметра ca_certs в wrap_socket().
- ssl.CERT_REQUIRED¶
Возможное значение для SSLContext.verify_mode или параметра cert_reqs для wrap_socket(). В этом режиме от другой стороны сокетного соединения требуются сертификаты; SSLError будет возбуждено, если сертификат не предоставлен или его проверка не пройдена.
Использование этого параметра требует передачи корректного набора сертификатов ЦС – либо в SSLContext.load_verify_locations(), либо в качестве значения параметра ca_certs в wrap_socket().
- ssl.PROTOCOL_SSLv2¶
Выбирает SSL версии 2 в качестве протокола шифрования канала.
Этот протокол недоступен, если OpenSSL скомпилирован с флагом OPENSSL_NO_SSL2 .
Предупреждение
SSL версии 2 небезопасен. Его использование крайне не рекомендуется.
- ssl.PROTOCOL_SSLv23¶
Выбирает SSL версии 2 или 3 в качестве протокола шифрования канала. Это настройка для использования с серверами для максимальной совместимости с другой стороной SSL-соединения, но может привести к выбору довольно низкокачественных шифров для шифрования.
- ssl.PROTOCOL_SSLv3¶
Выбирает SSL версии 3 в качестве протокола шифрования канала. Для клиентов это максимально совместимый вариант SSL.
- ssl.PROTOCOL_TLSv1¶
Выбирает TLS версии 1 в качестве протокола шифрования канала. Это самая современная версия и, вероятно, лучший выбор для максимальной защиты, если обе стороны её поддерживают.
- ssl.OP_ALL¶
Включает обходные решения для различных ошибок, присутствующих в других реализациях SSL. Этот параметр установлен по умолчанию. Он не обязательно устанавливает те же флаги, что и константа SSL_OP_ALL в OpenSSL.
Новое в версии 3.2.
- ssl.OP_NO_SSLv2¶
Запрещает соединение SSLv2. Этот параметр применим только в сочетании с PROTOCOL_SSLv23. Он не позволяет одноранговым узлам выбирать SSLv2 в качестве версии протокола.
Новое в версии 3.2.
- ssl.OP_NO_SSLv3¶
Запрещает соединение SSLv3. Этот параметр применим только в сочетании с PROTOCOL_SSLv23. Он не позволяет одноранговым узлам выбирать SSLv3 в качестве версии протокола.
Новое в версии 3.2.
- ssl.OP_NO_TLSv1¶
Запрещает соединение TLSv1. Этот параметр применим только в сочетании с PROTOCOL_SSLv23. Он не позволяет одноранговым узлам выбирать TLSv1 в качестве версии протокола.
Новое в версии 3.2.
- ssl.OP_CIPHER_SERVER_PREFERENCE¶
Использовать порядок шифров, заданный на сервере, а не на клиенте. Этот параметр не влияет на клиентские сокеты и сокеты сервера SSLv2.
Новое в версии 3.3.
- ssl.OP_SINGLE_DH_USE¶
Предотвращает повторное использование одного и того же DH-ключа для разных SSL-сессий. Это улучшает прямую секретность, но требует больше вычислительных ресурсов. Данная опция применяется только к серверным сокетам.
Новое в версии 3.3.
- ssl.OP_SINGLE_ECDH_USE¶
Предотвращает повторное использование одного и того же ECDH-ключа для разных SSL-сессий. Это улучшает прямую секретность, но требует больше вычислительных ресурсов. Данная опция применяется только к серверным сокетам.
Новое в версии 3.3.
- ssl.OP_NO_COMPRESSION¶
Отключает сжатие в SSL-канале. Это полезно, если прикладной протокол поддерживает собственный механизм сжатия.
Эта опция доступна только в OpenSSL 1.0.0 и более поздних версиях.
Новое в версии 3.3.
- ssl.HAS_ECDH¶
Определяет, имеет ли библиотека OpenSSL встроенную поддержку обмена ключами Диффи-Хеллмана на основе эллиптических кривых. Должно быть истинно, если только эта возможность не была явно отключена распространителем.
Новое в версии 3.3.
- ssl.HAS_SNI¶
Определяет, имеет ли библиотека OpenSSL встроенную поддержку расширения Server Name Indication для протоколов SSLv3 и TLSv1 (как определено в RFC 4366). Если истина, можно использовать аргумент server_hostname с SSLContext.wrap_socket().
Новое в версии 3.2.
- ssl.HAS_NPN¶
Поддерживает ли библиотека OpenSSL встроенную поддержку Next Protocol Negotiation, как описано в черновике спецификации NPN. Если значение истинно, можно использовать метод SSLContext.set_npn_protocols() для указания поддерживаемых протоколов.
Новое в версии 3.3.
- ssl.CHANNEL_BINDING_TYPES¶
Список поддерживаемых типов привязки каналов TLS. Строки из этого списка можно использовать в качестве аргументов для SSLSocket.get_channel_binding().
Новое в версии 3.3.
- ssl.OPENSSL_VERSION¶
Строка с версией библиотеки OpenSSL, загруженной интерпретатором:
>>> ssl.OPENSSL_VERSION 'OpenSSL 0.9.8k 25 Mar 2009'
Новое в версии 3.2.
- ssl.OPENSSL_VERSION_INFO¶
Кортеж из пяти целых чисел, содержащий информацию о версии библиотеки OpenSSL:
>>> ssl.OPENSSL_VERSION_INFO (0, 9, 8, 11, 15)
Новое в версии 3.2.
- ssl.OPENSSL_VERSION_NUMBER¶
Сырой номер версии библиотеки OpenSSL в виде целого числа:
>>> ssl.OPENSSL_VERSION_NUMBER 9470143 >>> hex(ssl.OPENSSL_VERSION_NUMBER) '0x9080bf'
Новое в версии 3.2.
18.2.2. SSL-сокеты¶SSL Sockets
SSL-сокеты предоставляют следующие методы объектов сокетов:
- accept()
- bind()
- close()
- connect()
- detach()
- fileno()
- getpeername(), getsockname()
- getsockopt(), setsockopt()
- gettimeout(), settimeout(), setblocking()
- listen()
- makefile()
- recv(), recv_into() (но передача ненулевого аргумента flags не допускается)
- send(), sendall() (с тем же ограничением)
- shutdown()
Однако, поскольку протокол SSL (и TLS) имеет собственную структуру поверх TCP, абстракция SSL-сокетов может в некоторых аспектах отличаться от спецификации обычных сокетов на уровне ОС. Особенно см. примечания о неблокирующих сокетах.
SSL-сокеты также имеют следующие дополнительные методы и атрибуты:
- SSLSocket.do_handshake()¶
Выполняет рукопожатие для настройки SSL.
- SSLSocket.getpeercert(binary_form=False)¶
Если на другом конце соединения нет сертификата у удаленной стороны, возвращается None.
If the binary_form parameter is False, and a certificate was received from the peer, this method returns a dict instance. If the certificate was not validated, the dict is empty. If the certificate was validated, it returns a dict with several keys, amongst them subject (the principal for which the certificate was issued) and issuer (the principal issuing the certificate). If a certificate contains an instance of the Subject Alternative Name extension (see RFC 3280), there will also be a subjectAltName key in the dictionary.
Поля subject и issuer являются кортежами, содержащими последовательность относительных уникальных имен (RDN), указанных в структуре данных сертификата для соответствующих полей. Каждый RDN представляет собой последовательность пар «имя-значение». Вот пример из реального мира:
{'issuer': ((('countryName', 'IL'),), (('organizationName', 'StartCom Ltd.'),), (('organizationalUnitName', 'Secure Digital Certificate Signing'),), (('commonName', 'StartCom Class 2 Primary Intermediate Server CA'),)), 'notAfter': 'Nov 22 08:15:19 2013 GMT', 'notBefore': 'Nov 21 03:09:52 2011 GMT', 'serialNumber': '95F0', 'subject': ((('description', '571208-SLe257oHY9fVQ07Z'),), (('countryName', 'US'),), (('stateOrProvinceName', 'California'),), (('localityName', 'San Francisco'),), (('organizationName', 'Electronic Frontier Foundation, Inc.'),), (('commonName', '*.eff.org'),), (('emailAddress', 'hostmaster@eff.org'),)), 'subjectAltName': (('DNS', '*.eff.org'), ('DNS', 'eff.org')), 'version': 3}
Примечание
Для проверки сертификата для конкретной службы можно использовать функцию match_hostname().
Если параметр binary_form равен True и сертификат был предоставлен, этот метод возвращает DER-кодированную форму всего сертификата в виде последовательности байт или None, если узел не предоставил сертификат. Предоставляет ли узел сертификат, зависит от роли SSL-сокета:
- для клиентского SSL-сокета сервер всегда предоставляет сертификат, независимо от того, требовалась ли проверка;
- для серверного SSL-сокета клиент предоставляет сертификат только по запросу сервера; поэтому getpeercert() вернет None, если было использовано CERT_NONE (а не CERT_OPTIONAL или CERT_REQUIRED).
Изменено в версии 3.2: Возвращаемый словарь включает дополнительные элементы, такие как issuer и notBefore.
- SSLSocket.cipher()¶
Возвращает кортеж из трех значений, содержащий название используемого шифра, версию протокола SSL, которая определяет его использование, и количество используемых секретных битов. Если соединение не установлено, возвращает None.
- SSLSocket.compression()¶
Возвращает используемый алгоритм сжатия в виде строки или None, если соединение не сжато.
Если протокол более высокого уровня поддерживает собственный механизм сжатия, можно использовать OP_NO_COMPRESSION для отключения сжатия на уровне SSL.
Новое в версии 3.3.
- SSLSocket.get_channel_binding(cb_type="tls-unique")¶
Получает данные привязки канала для текущего соединения в виде объекта bytes. Возвращает None, если соединение не установлено или рукопожатие не завершено.
Параметр cb_type позволяет выбрать желаемый тип привязки канала. Допустимые типы привязки канала перечислены в списке CHANNEL_BINDING_TYPES. В настоящее время поддерживается только привязка канала «tls-unique», определенная в RFC 5929. Если запрошен неподдерживаемый тип привязки канала, будет возбуждено ValueError.
Новое в версии 3.3.
- SSLSocket.selected_npn_protocol()¶
Возвращает протокол, выбранный во время рукопожатия TLS/SSL. Если SSLContext.set_npn_protocols() не была вызвана, или другая сторона не поддерживает NPN, или рукопожатие ещё не произошло, возвращается None.
Новое в версии 3.3.
- SSLSocket.unwrap()¶
Выполняет рукопожатие завершения SSL, которое удаляет слой TLS из базового сокета и возвращает объект базового сокета. Это можно использовать для перехода от зашифрованной работы по соединению к незашифрованной. Возвращённый сокет всегда следует использовать для дальнейшего обмена данными с другой стороной соединения, а не исходный сокет.
- SSLSocket.context¶
Объект SSLContext, к которому привязан данный SSL-сокет. Если SSL-сокет был создан с помощью функции верхнего уровня wrap_socket() (а не SSLContext.wrap_socket()), то это пользовательский объект контекста, созданный для данного SSL-сокета.
Новое в версии 3.2.
18.2.3. SSL-контексты¶SSL Contexts
Новое в версии 3.2.
Контекст SSL хранит различные данные, которые живут дольше, чем отдельные SSL-соединения, такие как параметры конфигурации SSL, сертификат(ы) и закрытый(е) ключ(и). Он также управляет кешем SSL-сессий для серверных сокетов, чтобы ускорить повторные подключения от одних и тех же клиентов.
- class ssl.SSLContext(protocol)¶
Создает новый SSL-контекст. Необходимо передать протокол, который должен быть одной из констант PROTOCOL_*, определенных в этом модуле. Для максимальной совместимости рекомендуется использовать PROTOCOL_SSLv23.
Объекты SSLContext имеют следующие методы и атрибуты:
- SSLContext.load_cert_chain(certfile, keyfile=None, password=None)¶
Загружает закрытый ключ и соответствующий сертификат. Строка certfile должна быть путём к одному файлу в формате PEM, содержащему сертификат, а также любое количество сертификатов УЦ, необходимых для подтверждения подлинности сертификата. Строка keyfile, если указана, должна указывать на файл, содержащий закрытый ключ. В противном случае закрытый ключ также будет взят из certfile. Смотрите обсуждение Certificates для получения дополнительной информации о том, как сертификат хранится в certfile.
Аргумент password может быть функцией, вызываемой для получения пароля для расшифровки закрытого ключа. Она будет вызвана только в том случае, если закрытый ключ зашифрован и требуется пароль. Она будет вызвана без аргументов, и должна возвращать строку, bytes или bytearray. Если возвращаемое значение – строка, она будет закодирована в UTF-8 перед использованием для расшифровки ключа. В качестве альтернативы, строка, bytes или bytearray могут быть переданы напрямую в качестве аргумента password. Этот аргумент будет проигнорирован, если закрытый ключ не зашифрован и пароль не требуется.
Если аргумент password не указан и требуется пароль, будет использован встроенный механизм запроса пароля OpenSSL для интерактивного запроса пароля у пользователя.
Исключение SSLError возбуждается, если закрытый ключ не соответствует сертификату.
Изменено в версии 3.3: Новый необязательный аргумент password.
- SSLContext.load_verify_locations(cafile=None, capath=None)¶
Загружает набор сертификатов «удостоверяющего центра» (CA), используемых для проверки сертификатов других участников, когда verify_mode отличен от CERT_NONE. Должен быть указан хотя бы один из параметров cafile или capath.
Строка cafile, если присутствует, содержит путь к файлу, содержащему объединённые сертификаты CA в формате PEM. См. обсуждение Сертификаты для получения дополнительной информации о том, как организовать сертификаты в этом файле.
Строка capath, если присутствует, задаёт путь к каталогу, содержащему несколько сертификатов CA в формате PEM, согласно специфической структуре OpenSSL.
- SSLContext.set_default_verify_paths()¶
Загружает набор сертификатов по умолчанию “certification authority” (CA) из пути файловой системы, заданного при сборке библиотеки OpenSSL. К сожалению, нет простого способа узнать, успешно ли выполняется этот метод: ошибка не возвращается, если сертификаты не найдены. Однако, если библиотека OpenSSL поставляется как часть операционной системы, она, скорее всего, настроена правильно.
- SSLContext.set_ciphers(ciphers)¶
Устанавливает доступные шифры для сокетов, созданных с этим контекстом. Это должна быть строка в формате списка шифров OpenSSL. Если ни один шифр не может быть выбран (из-за опций компиляции или других настроек, запрещающих использование всех указанных шифров), будет возбуждено исключение SSLError.
Примечание
при подключении метод SSLSocket.cipher() SSL-сокетов вернёт текущий выбранный шифр.
- SSLContext.set_npn_protocols(protocols)¶
Определяет, какие протоколы сокет будет объявлять во время рукопожатия SSL/TLS. Это должен быть список строк, например ['http/1.1', 'spdy/2'], упорядоченный по предпочтению. Выбор протокола произойдёт во время рукопожатия и будет выполняться в соответствии с черновиком спецификации NPN. После успешного рукопожатия метод SSLSocket.selected_npn_protocol() вернёт согласованный протокол.
Этот метод возбудит NotImplementedError, если HAS_NPN равен False.
Новое в версии 3.3.
- SSLContext.load_dh_params(dhfile)¶
Загружает параметры генерации ключей для обмена ключами Диффи-Хеллмана (DH). Использование обмена ключами DH улучшает прямую секретность за счет вычислительных ресурсов (как на сервере, так и на клиенте). Параметр dhfile должен быть путем к файлу, содержащему параметры DH в формате PEM.
Этот параметр не применяется к клиентским сокетам. Для дальнейшего повышения безопасности можно также использовать опцию OP_SINGLE_DH_USE.
Новое в версии 3.3.
- SSLContext.set_ecdh_curve(curve_name)¶
Устанавливает имя кривой для обмена ключами на основе эллиптических кривых Diffie-Hellman (ECDH). ECDH значительно быстрее обычного DH и при этом, по-видимому, столь же безопасен. Параметр curve_name должен быть строкой, описывающей известную эллиптическую кривую, например prime256v1 для широко поддерживаемой кривой.
Этот параметр не применяется к клиентским сокетам. Для дальнейшего повышения безопасности можно также использовать опцию OP_SINGLE_ECDH_USE.
Этот метод недоступен, если HAS_ECDH равен False.
Новое в версии 3.3.
См. также
- SSL/TLS и совершенная прямая секретность
- Vincent Bernat.
- SSLContext.wrap_socket(sock, server_side=False, do_handshake_on_connect=True, suppress_ragged_eofs=True, server_hostname=None)¶
Оборачивает существующий сокет Python sock и возвращает объект SSLSocket. sock должен быть сокетом типа SOCK_STREAM; другие типы сокетов не поддерживаются.
Возвращаемый SSL-сокет привязан к контексту, его настройкам и сертификатам. Параметры server_side, do_handshake_on_connect и suppress_ragged_eofs имеют тот же смысл, что и в функции верхнего уровня wrap_socket().
При клиентских подключениях необязательный параметр server_hostname задает имя хоста службы, к которой осуществляется подключение. Это позволяет одному серверу обслуживать несколько SSL-сервисов с разными сертификатами, по аналогии с виртуальными хостами HTTP. Указание server_hostname приведет к возбуждению ValueError, если библиотека OpenSSL не поддерживает эту возможность (то есть если HAS_SNI равно False). Указание server_hostname также приведет к ValueError, если server_side имеет значение true.
- SSLContext.session_stats()¶
Получает статистику о сеансах SSL, созданных или управляемых этим контекстом. Возвращается словарь, который сопоставляет названия каждого фрагмента информации с их числовыми значениями. Например, вот общее количество попаданий и промахов в кэше сеансов с момента создания контекста:
>>> stats = context.session_stats() >>> stats['hits'], stats['misses'] (0, 0)
- SSLContext.options¶
Целое число, представляющее набор SSL-опций, включённых в этом контексте. Значение по умолчанию – OP_ALL, но можно задать другие опции, например OP_NO_SSLv2, объединяя их логическим ИЛИ.
Примечание
В версиях OpenSSL старше 0.9.8m можно только устанавливать опции, но не сбрасывать их. Попытка сбросить опцию (путём сброса соответствующих битов) вызовет ValueError.
- SSLContext.protocol¶
Версия протокола, выбранная при создании контекста. Этот атрибут доступен только для чтения.
- SSLContext.verify_mode¶
Определяет, следует ли пытаться проверять сертификаты других одноранговых узлов и как себя вести при неудачной проверке. Этот атрибут должен быть одним из CERT_NONE, CERT_OPTIONAL или CERT_REQUIRED.
18.2.4. Сертификаты¶Certificates
Сертификаты в целом являются частью системы открытых и закрытых ключей. В этой системе каждому субъекту (которым может быть машина, человек или организация) присваивается уникальный двухчастный ключ шифрования. Одна часть ключа является открытой и называется открытым ключом; другая часть хранится в секрете и называется закрытым ключом. Две части связаны так, что если зашифровать сообщение одной частью, его можно расшифровать только другой частью, и только другой частью.
Сертификат содержит информацию о двух субъектах. Он содержит имя субъекта и его открытый ключ. Также он содержит утверждение второго субъекта, издателя, о том, что субъект является тем, за кого себя выдаёт, и что это действительно открытый ключ субъекта. Утверждение издателя подписано закрытым ключом издателя, который известен только издателю. Однако любой может проверить утверждение издателя, найдя его открытый ключ, расшифровав им утверждение и сравнив его с другой информацией в сертификате. Сертификат также содержит информацию о периоде времени, в течение которого он действителен. Это выражается двумя полями, называемыми «notBefore» и «notAfter».
При использовании сертификатов в Python клиент или сервер может использовать сертификат для подтверждения своей личности. Другая сторона сетевого соединения также может быть обязана предоставить сертификат, и этот сертификат может быть проверен к удовлетворению клиента или сервера, требующего такой проверки. Можно настроить попытку соединения так, чтобы она вызывала исключение, если проверка не удалась. Проверка выполняется автоматически базовым фреймворком OpenSSL; приложению не нужно вникать в её механику. Но приложению обычно необходимо предоставить наборы сертификатов, чтобы этот процесс мог происходить.
Python uses files to contain certificates. They should be formatted as “PEM” (see RFC 1422), which is a base-64 encoded form wrapped with a header line and a footer line:
-----BEGIN CERTIFICATE-----
... (certificate in base64 PEM encoding) ...
-----END CERTIFICATE-----
18.2.4.1. Цепочки сертификатов¶Certificate chains
The Python files which contain certificates can contain a sequence of certificates, sometimes called a certificate chain. This chain should start with the specific certificate for the principal who “is” the client or server, and then the certificate for the issuer of that certificate, and then the certificate for the issuer of that certificate, and so on up the chain till you get to a certificate which is self-signed, that is, a certificate which has the same subject and issuer, sometimes called a root certificate. The certificates should just be concatenated together in the certificate file. For example, suppose we had a three certificate chain, from our server certificate to the certificate of the certification authority that signed our server certificate, to the root certificate of the agency which issued the certification authority’s certificate:
-----BEGIN CERTIFICATE-----
... (certificate for your server)...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
... (the certificate for the CA)...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
... (the root certificate for the CA's issuer)...
-----END CERTIFICATE-----
18.2.4.2. Сертификаты УЦ¶CA certificates
Если требуется проверка сертификата другой стороны соединения, необходимо предоставить файл «CA certs», содержащий цепочки сертификатов для каждого издателя, которому вы готовы доверять. Этот файл просто содержит эти цепочки, объединённые вместе. Для проверки Python будет использовать первую подходящую цепочку в файле. Некоторые «стандартные» корневые сертификаты доступны от различных центров сертификации: CACert.org, Thawte, Verisign, Positive SSL (используется python.org), Equifax и GeoTrust.
В общем случае, если вы используете SSL3 или TLS1, не нужно помещать полную цепочку в файл «CA certs»; достаточно корневых сертификатов, а удалённый узел должен предоставить остальные сертификаты, необходимые для построения цепочки от своего сертификата до корневого. См. RFC 4158 для более подробного обсуждения способов построения цепочек сертификатов.
18.2.4.3. Совмещённый ключ и сертификат¶Combined key and certificate
Часто закрытый ключ хранится в том же файле, что и сертификат; в этом случае нужно передать только параметр certfile в SSLContext.load_cert_chain() и wrap_socket(). Если закрытый ключ хранится вместе с сертификатом, он должен располагаться перед первым сертификатом в цепочке сертификатов:
-----BEGIN RSA PRIVATE KEY-----
... (private key in base64 encoding) ...
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
... (certificate in base64 PEM encoding) ...
-----END CERTIFICATE-----
18.2.4.4. Самоподписанные сертификаты¶Self-signed certificates
Если планируется создать сервер, предоставляющий услуги SSL-защищённого соединения, потребуется приобрести сертификат для этой службы. Существует много способов получения подходящих сертификатов, например покупка в удостоверяющем центре. Ещё одна распространённая практика – сгенерировать самоподписанный сертификат. Самый простой способ сделать это – использовать пакет OpenSSL, примерно следующим образом:
% openssl req -new -x509 -days 365 -nodes -out cert.pem -keyout cert.pem
Generating a 1024 bit RSA private key
.......++++++
.............................++++++
writing new private key to 'cert.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:MyState
Locality Name (eg, city) []:Some City
Organization Name (eg, company) [Internet Widgits Pty Ltd]:My Organization, Inc.
Organizational Unit Name (eg, section) []:My Group
Common Name (eg, YOUR name) []:myserver.mygroup.myorganization.com
Email Address []:ops@myserver.mygroup.myorganization.com
%
Недостаток самоподписанного сертификата в том, что он является собственным корневым сертификатом, и никто другой не будет иметь его в своём кэше известных (и доверенных) корневых сертификатов.
18.2.5. Примеры¶Examples
18.2.5.1. Проверка поддержки SSL¶Testing for SSL support
Чтобы проверить наличие поддержки SSL в установке Python, в пользовательском коде следует использовать следующую идиому:
try:
import ssl
except ImportError:
pass
else:
... # сделать что-то, что требует поддержки SSL
18.2.5.2. Работа на стороне клиента¶Client-side operation
Этот пример подключается к SSL-серверу и выводит его сертификат:
import socket, ssl, pprint
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# требовать сертификат от сервера
ssl_sock = ssl.wrap_socket(s,
ca_certs="/etc/ca_certs_file",
cert_reqs=ssl.CERT_REQUIRED)
ssl_sock.connect(('www.verisign.com', 443))
pprint.pprint(ssl_sock.getpeercert())
# закрытие SSLSocket также закроет нижележащий сокет
ssl_sock.close()
По состоянию на 6 января 2012 года сертификат, выводимый этой программой, выглядит следующим образом:
{'issuer': ((('countryName', 'US'),),
(('organizationName', 'VeriSign, Inc.'),),
(('organizationalUnitName', 'VeriSign Trust Network'),),
(('organizationalUnitName',
'Terms of use at https://www.verisign.com/rpa (c)06'),),
(('commonName',
'VeriSign Class 3 Extended Validation SSL SGC CA'),)),
'notAfter': 'May 25 23:59:59 2012 GMT',
'notBefore': 'May 26 00:00:00 2010 GMT',
'serialNumber': '53D2BEF924A7245E83CA01E46CAA2477',
'subject': ((('1.3.6.1.4.1.311.60.2.1.3', 'US'),),
(('1.3.6.1.4.1.311.60.2.1.2', 'Delaware'),),
(('businessCategory', 'V1.0, Clause 5.(b)'),),
(('serialNumber', '2497886'),),
(('countryName', 'US'),),
(('postalCode', '94043'),),
(('stateOrProvinceName', 'California'),),
(('localityName', 'Mountain View'),),
(('streetAddress', '487 East Middlefield Road'),),
(('organizationName', 'VeriSign, Inc.'),),
(('organizationalUnitName', ' Production Security Services'),),
(('commonName', 'www.verisign.com'),)),
'subjectAltName': (('DNS', 'www.verisign.com'),
('DNS', 'verisign.com'),
('DNS', 'www.verisign.net'),
('DNS', 'verisign.net'),
('DNS', 'www.verisign.mobi'),
('DNS', 'verisign.mobi'),
('DNS', 'www.verisign.eu'),
('DNS', 'verisign.eu')),
'version': 3}
Другой пример сначала создаёт контекст SSL, указывает ему проверять сертификаты, отправляемые узлами, и передаёт ему набор известных центров сертификации (CA):
>>> context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
>>> context.verify_mode = ssl.CERT_REQUIRED
>>> context.load_verify_locations("/etc/ssl/certs/ca-bundle.crt")
(предполагается, что ваша операционная система помещает набор всех сертификатов CA в /etc/ssl/certs/ca-bundle.crt; если нет, вы получите ошибку и придётся изменить путь)
При использовании контекста для подключения к серверу CERT_REQUIRED проверяет сертификат сервера: он гарантирует, что сертификат сервера был подписан одним из сертификатов ЦС, и проверяет корректность подписи:
>>> conn = context.wrap_socket(socket.socket(socket.AF_INET))
>>> conn.connect(("linuxfr.org", 443))
Затем следует получить сертификат и проверить его поля на соответствие:
>>> cert = conn.getpeercert()
>>> ssl.match_hostname(cert, "linuxfr.org")
Визуальная проверка показывает, что сертификат действительно идентифицирует нужный сервис (а именно, HTTPS-хост linuxfr.org):
>>> pprint.pprint(cert)
{'issuer': ((('organizationName', 'CAcert Inc.'),),
(('organizationalUnitName', 'http://www.CAcert.org'),),
(('commonName', 'CAcert Class 3 Root'),)),
'notAfter': 'Jun 7 21:02:24 2013 GMT',
'notBefore': 'Jun 8 21:02:24 2011 GMT',
'serialNumber': 'D3E9',
'subject': ((('commonName', 'linuxfr.org'),),),
'subjectAltName': (('DNS', 'linuxfr.org'),
('othername', '<unsupported>'),
('DNS', 'linuxfr.org'),
('othername', '<unsupported>'),
('DNS', 'dev.linuxfr.org'),
('othername', '<unsupported>'),
('DNS', 'prod.linuxfr.org'),
('othername', '<unsupported>'),
('DNS', 'alpha.linuxfr.org'),
('othername', '<unsupported>'),
('DNS', '*.linuxfr.org'),
('othername', '<unsupported>')),
'version': 3}
Теперь, убедившись в его подлинности, можно приступать к общению с сервером:
>>> conn.sendall(b"HEAD / HTTP/1.0\r\nHost: linuxfr.org\r\n\r\n")
>>> pprint.pprint(conn.recv(1024).split(b"\r\n"))
[b'HTTP/1.1 302 Found',
b'Date: Sun, 16 May 2010 13:43:28 GMT',
b'Server: Apache/2.2',
b'Location: https://linuxfr.org/pub/',
b'Vary: Accept-Encoding',
b'Connection: close',
b'Content-Type: text/html; charset=iso-8859-1',
b'',
b'']
См. обсуждение соображений безопасности ниже.
18.2.5.3. Работа на стороне сервера¶Server-side operation
Для работы сервера обычно нужен сертификат сервера и закрытый ключ, каждый в отдельном файле. Сначала создаётся контекст, содержащий ключ и сертификат, чтобы клиенты могли проверить вашу подлинность. Затем открывается сокет, привязывается к порту, вызывается listen(), и начинается ожидание подключения клиентов:
import socket, ssl
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
context.load_cert_chain(certfile="mycertfile", keyfile="mykeyfile")
bindsocket = socket.socket()
bindsocket.bind(('myaddr.mydomain.com', 10023))
bindsocket.listen(5)
Когда клиент подключается, вызывается accept() на сокете, чтобы получить новый сокет от другой стороны, и используется метод контекста SSLContext.wrap_socket() для создания серверного SSL-сокета для соединения:
while True:
newsocket, fromaddr = bindsocket.accept()
connstream = context.wrap_socket(newsocket, server_side=True)
try:
deal_with_client(connstream)
finally:
connstream.shutdown(socket.SHUT_RDWR)
connstream.close()
Затем считываются данные из connstream и выполняется с ними какая-то работа, пока не завершится взаимодействие с клиентом (или клиент с вами):
def deal_with_client(connstream):
data = connstream.recv(1024)
# пустые данные означают, что клиент закончил работу с нами
while data:
if not do_something(connstream, data):
# будем считать, что do_something возвращает False
# когда мы закончили с клиентом
break
data = connstream.recv(1024)
# закончили с клиентом
И возврат к ожиданию новых клиентских подключений (конечно, настоящий сервер, вероятно, обрабатывал бы каждое клиентское соединение в отдельном потоке или переводил сокеты в неблокирующий режим и использовал цикл событий).
18.2.6. Замечания о неблокирующих сокетах¶Notes on non-blocking sockets
При работе с неблокирующими сокетами необходимо учитывать несколько моментов:
Вызов select() сообщает, что сокет на уровне ОС можно читать (или писать), но это не означает, что на верхнем уровне SSL имеется достаточно данных. Например, может прийти только часть SSL-фрейма. Поэтому необходимо быть готовым обработать ошибки SSLSocket.recv() и SSLSocket.send() и повторить попытку после очередного вызова select().
(разумеется, аналогичные положения применимы при использовании других примитивов, таких как poll())
Само рукопожатие SSL будет неблокирующим: метод SSLSocket.do_handshake() нужно повторять до успешного завершения. Вот краткий пример с использованием select() для ожидания готовности сокета:
while True: try: sock.do_handshake() break except ssl.SSLWantReadError: select.select([sock], [], []) except ssl.SSLWantWriteError: select.select([], [sock], [])
18.2.7. Рекомендации по безопасности¶Security considerations
18.2.7.1. Проверка сертификатов¶Verifying certificates
CERT_NONE является значением по умолчанию. Поскольку он не аутентифицирует другую сторону, это может быть небезопасно, особенно в клиентском режиме, где в большинстве случаев требуется убедиться в подлинности сервера, с которым идёт общение. Поэтому в клиентском режиме настоятельно рекомендуется использовать CERT_REQUIRED. Однако сам по себе он недостаточен; необходимо также проверить, что сертификат сервера, который можно получить вызовом SSLSocket.getpeercert(), соответствует нужному сервису. Для многих протоколов и приложений сервис может быть идентифицирован по имени хоста; в этом случае можно использовать функцию match_hostname().
В серверном режиме, если требуется аутентифицировать клиентов с помощью SSL-слоя (а не через механизм аутентификации более высокого уровня), также нужно указать CERT_REQUIRED и аналогично проверять клиентский сертификат.
Примечание
В клиентском режиме CERT_OPTIONAL и CERT_REQUIRED эквивалентны, если не включены анонимные шифры (по умолчанию они отключены).
18.2.7.2. Версии протоколов¶Protocol versions
SSL версии 2 считается небезопасным, и поэтому его использование опасно. Если требуется максимальная совместимость между клиентами и серверами, рекомендуется использовать PROTOCOL_SSLv23 в качестве версии протокола, а затем явно отключить SSLv2 с помощью атрибута SSLContext.options:
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
context.options |= ssl.OP_NO_SSLv2
Созданный выше контекст SSL будет разрешать соединения SSLv3 и TLSv1, но не SSLv2.
18.2.7.3. Выбор шифров¶Cipher selection
Если у вас повышенные требования к безопасности, точную настройку шифров, разрешённых при согласовании SSL-сеанса, можно выполнить с помощью метода SSLContext.set_ciphers(). Начиная с Python 3.2.3, модуль ssl по умолчанию отключает некоторые слабые шифры, но можно дополнительно ограничить выбор шифров. Например:
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
context.set_ciphers('HIGH:!aNULL:!eNULL')
Часть спецификации шифров !aNULL:!eNULL необходима для отключения шифров, которые не обеспечивают одновременно шифрование и аутентификацию. Обязательно прочитайте документацию OpenSSL о формате списка шифров. Чтобы проверить, какие шифры включены заданным списком, используйте команду openssl ciphers в вашей системе.
18.2.7.4. Многопроцессорность¶Multi-processing
Если этот модуль используется в составе многопроцессного приложения (например, с модулями multiprocessing или concurrent.futures), следует учитывать, что внутренний генератор случайных чисел OpenSSL некорректно обрабатывает порождённые процессы. Приложения должны изменять состояние PRNG родительского процесса, если они используют любые функции SSL с os.fork(). Любой успешный вызов RAND_add(), RAND_bytes() или RAND_pseudo_bytes() считается достаточным.
См. также
- Класс socket.socket
- Документация базового класса socket
- SSL/TLS: надёжное шифрование. Введение
- Введение из документации веб-сервера Apache
- RFC 1422: Улучшение конфиденциальности для интернет-электронной почты: Часть II: Управление ключами на основе сертификатов
- Steve Kent
- RFC 1750: Рекомендации по случайности для безопасности
- D. Eastlake et. al.
- RFC 3280: Инфраструктура открытых ключей Internet X.509 – профиль сертификатов и списков отзыва
- Housley et. al.
- RFC 4366: Расширения безопасности транспортного уровня (TLS)
- Blake-Wilson et. al.