Spec-Zone.ru › Python 3.6

ssl — Обёртка TLS/SSL для сокетов

Исходный код: Lib/ssl.py

Этот модуль предоставляет доступ к шифрованию Transport Layer Security (часто известному как «Secure Sockets Layer») и средствам проверки подлинности узлов для сетевых сокетов, как со стороны клиента, так и со стороны сервера. Этот модуль использует библиотеку OpenSSL. Он доступен на всех современных Unix-системах, Windows, Mac OS X и, вероятно, на дополнительных платформах, при условии установки OpenSSL на этой платформе.

Примечание

Некоторые особенности могут зависеть от платформы, так как вызовы выполняются к API сокетов операционной системы. Установленная версия OpenSSL также может вызывать различия в поведении. Например, TLSv1.1 и TLSv1.2 поставляются с openssl версии 1.0.1.

Предупреждение

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

В этом разделе документированы объекты и функции в модуле ssl; для получения более общей информации о TLS, SSL и сертификатах читатель обращается к документации в разделе «См. также» внизу.

Этот модуль предоставляет класс ssl.SSLSocket, который наследуется от типа socket.socket и предоставляет обёртку для сокета, которая также шифрует и расшифровывает данные, передаваемые по сокету с помощью SSL. Он поддерживает дополнительные методы, такие как getpeercert(), который извлекает сертификат другой стороны соединения, и cipher(), который извлекает шифр, используемый для защищённого соединения.

Для более сложных приложений класс ssl.SSLContext помогает управлять настройками и сертификатами, которые затем могут быть унаследованы сокетами SSL, созданными с помощью метода SSLContext.wrap_socket().

Изменено в версии 3.5.3: Обновлено для поддержки связывания с OpenSSL 1.1.0

Изменено в версии 3.6: OpenSSL 0.9.8, 1.0.0 и 1.0.1 устарели и больше не поддерживаются. В будущем модуль ssl будет требовать по крайней мере OpenSSL 1.0.2 или 1.1.0.

18.2.1. Функции, константы и исключения

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. Создание сокета

Следующая функция позволяет создавать автономные сокеты. Начиная с 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 задают необязательные файлы, содержащие сертификат, который будет использоваться для идентификации локальной стороны подключения. Дополнительную информацию о том, как сертификат хранится в certfile, см. в разделе Сертификаты.

Параметр server_side — это логическое значение, указывающее, нужно ли поведение сокета для серверной или клиентской стороны.

Параметр cert_reqs определяет, требуется ли сертификат с другой стороны соединения и будет ли он проверен при предоставлении. Он должен быть одним из трёх значений: CERT_NONE (сертификаты игнорируются), CERT_OPTIONAL (необязательно, но проверяется при предоставлении) или CERT_REQUIRED (требуется и проверяется). Если значение этого параметра не CERT_NONE, то параметр ca_certs должен указывать на файл с сертификатами центров сертификации.

Файл ca_certs содержит набор конкатенированных сертификатов «центра сертификации», используемых для проверки сертификатов, переданных с другой стороны соединения. Дополнительную информацию о том, как организовать сертификаты в этом файле, см. в разделе Сертификаты.

Параметр ssl_version указывает, какую версию протокола SSL использовать. Как правило, сервер выбирает определённую версию протокола, а клиент должен адаптироваться к выбору сервера. Большинство версий не совместимы друг с другом. Если не указано иное, по умолчанию используется PROTOCOL_TLS, обеспечивающий наибольшую совместимость с другими версиями.

В следующей таблице показано, какие версии клиента (по вертикали) могут подключаться к каким версиям сервера (по горизонтали):

клиент / сервер

SSLv2

SSLv3

TLS 3

TLSv1

TLSv1.1

TLSv1.2

SSLv2

да

нет

нет 1

нет

нет

нет

SSLv3

нет

да

нет 2

нет

нет

нет

TLS (SSLv23) 3

нет 1

нет 2

да

да

да

да

TLSv1

нет

нет

да

да

нет

нет

TLSv1.1

нет

нет

да

нет

да

нет

TLSv1.2

нет

нет

да

нет

нет

да

Примечания

1(1,2)

SSLContext по умолчанию отключает SSLv2 с помощью OP_NO_SSLv2.

2(1,2)

SSLContext по умолчанию отключает SSLv3 с помощью OP_NO_SSLv3.

3(1,2)

Протокол TLS 1.3 будет доступен с PROTOCOL_TLS в OpenSSL >= 1.1.1. Нет специальной константы PROTOCOL для только TLS 1.3.

Примечание

Успешность подключений будет зависеть от версии OpenSSL. Например, до OpenSSL 1.0.0 клиент SSLv23 всегда пытался подключиться по протоколу SSLv2.

Параметр ciphers устанавливает доступные шифры для этого объекта SSL. Он должен быть строкой в формате списка шифров OpenSSL .

Параметр do_handshake_on_connect указывает, следует ли автоматически выполнить рукопожатие SSL после выполнения socket.connect(), или приложение должно вызвать его явно, вызвав метод SSLSocket.do_handshake(). Явное вызов метода SSLSocket.do_handshake() даёт программе контроль над блокирующим поведением операций ввода-вывода сокета, участвующих в рукопожатии.

Параметр suppress_ragged_eofs определяет, как метод SSLSocket.recv() должен сигнализировать о неожиданном конце файла (EOF) с другой стороны соединения. Если задано значение True (по умолчанию), он возвращает нормальный EOF (пустой байтовый объект) в ответ на неожиданные ошибки EOF, поднятые базовым сокетом; если False, он передаст исключения вызывающей стороне.

Изменено в версии 3.2: Новый необязательный аргумент ciphers.

18.2.1.2. Создание контекста

Функция-удобство помогает создавать объекты SSLContext для общих целей.

ssl.create_default_context(purpose=Purpose.SERVER_AUTH, cafile=None, capath=None, cadata=None)

Возвращает новый объект SSLContext с настройками по умолчанию для заданного назначения. Настройки выбираются модулем ssl и обычно представляют более высокий уровень безопасности, чем при непосредственном вызове конструктора SSLContext.

cafile, capath, cadata представляют необязательные сертификаты УЦ для проверки сертификатов, как в SSLContext.load_verify_locations(). Если все три параметра равны None, эта функция может выбрать доверие к сертификатам УЦ по умолчанию системы.

Настройки включают: PROTOCOL_TLS, OP_NO_SSLv2 и OP_NO_SSLv3 с высокошифровальными наборами шифров без RC4 и без ненастроенных наборов шифров. Передача значения SERVER_AUTH в качестве назначения устанавливает verify_mode в значение CERT_REQUIRED и либо загружает сертификаты УЦ (если хотя бы один из cafile, capath или cadata задан), либо использует SSLContext.load_default_certs() для загрузки сертификатов УЦ по умолчанию.

Примечание

Протокол, опции, шифры и другие настройки могут быть изменены на более строгие значения в любое время без предварительного уведомления. Эти значения представляют разумный баланс между совместимостью и безопасностью.

Если вашему приложению нужны определенные настройки, вы должны создать объект SSLContext и применить настройки самостоятельно.

Примечание

Если вы обнаружите, что некоторые старые клиенты или серверы при попытке подключения к SSLContext, созданному этой функцией, получают ошибку «Несовпадение протокола или набора шифров», возможно, они поддерживают только SSL3.0, который эта функция исключает с помощью OP_NO_SSLv3. SSL3.0 широко считается полностью небезопасным. Если вы по-прежнему хотите использовать эту функцию, но все же разрешить подключения SSL 3.0, вы можете снова включить их, используя:

ctx = ssl.create_default_context(Purpose.CLIENT_AUTH)
ctx.options &= ~ssl.OP_NO_SSLv3

Новая версия с 3.4.

Изменено в версии 3.4.4: RC4 был исключён из строковой спецификации шифрования по умолчанию.

Изменено в версии 3.6: Было добавлено ChaCha20/Poly1305 в строковую спецификацию шифрования по умолчанию.

3DES был исключён из строковой спецификации шифрования по умолчанию.

18.2.1.3. Генерация случайных чисел

ssl.RAND_bytes(num)

Возвращает num криптографически сильных псевдослучайных байтов. Возбуждает SSLError, если генератор псевдослучайных чисел (ПСПЧ) не был инициализирован достаточным количеством данных или если операция не поддерживается текущим методом RAND. RAND_status() можно использовать для проверки состояния ПСПЧ, а RAND_add() можно использовать для инициализации ПСПЧ.

Для почти всех приложений предпочтительнее os.urandom().

Прочтите статью Википедии Cryptographically secure pseudorandom number generator (CSPRNG), чтобы ознакомиться с требованиями к криптографически-безопасному генератору.

Новая версия с 3.3.

ssl.RAND_pseudo_bytes(num)

Возвращает (байты, is_cryptographic): байты — это num псевдослучайных байтов, is_cryptographic — True, если сгенерированные байты являются криптографически сильными. Возбуждает SSLError, если операция не поддерживается текущим методом RAND.

Сгенерированные псевдослучайные последовательности байтов будут уникальными, если они достаточно длинные, но не обязательно предсказуемыми. Их можно использовать для некриптографических целей и для определённых целей в криптографических протоколах, но обычно не для генерации ключей и т. д.

Для почти всех приложений предпочтительнее os.urandom().

Новая версия с 3.3.

Устарело начиная с версии 3.6: OpenSSL устарел ssl.RAND_pseudo_bytes(), используйте ssl.RAND_bytes() вместо него.

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/ для источников демонов сбора энтропии.

Доступность: недоступно с LibreSSL и OpenSSL > 1.1.0

ssl.RAND_add(bytes, entropy)

Смешивает предоставленные байты в генератор псевдослучайных чисел SSL. Параметр entropy (число с плавающей запятой) — это нижняя граница энтропии, содержащейся в строке (поэтому вы всегда можете использовать 0.0). См. RFC 1750 для получения дополнительной информации о источниках энтропии.

Изменено в версии 3.5: Теперь принимается объект типа bytes-like object.

18.2.1.4. Обработка сертификатов

ssl.match_hostname(cert, hostname)

Проверяет, соответствует ли cert (в декодированном формате, возвращаемом SSLSocket.getpeercert()) заданному hostname. Применяемые правила соответствуют проверке личности HTTPS-серверов, описанной в RFC 2818, RFC 5280 и RFC 6125. Кроме 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.

Изменено в версии 3.5: Теперь поддерживается сопоставление IP-адресов, когда они присутствуют в поле subjectAltName сертификата.

ssl.cert_time_to_seconds(cert_time)

Возвращает время в секундах с начала эпохи, заданное строкой cert_time «notBefore» или «notAfter» из сертификата в формате "%b %d %H:%M:%S %Y %Z" strptime (региональные настройки C).

Вот пример:

>>> import ssl
>>> timestamp = ssl.cert_time_to_seconds("Jan  5 09:34:43 2018 GMT")
>>> timestamp
1515144883
>>> from datetime import datetime
>>> print(datetime.utcfromtimestamp(timestamp))
2018-01-05 09:34:43

Даты «notBefore» или «notAfter» должны использовать GMT (RFC 5280).

Изменено в версии 3.5: Интерпретирует входное время как время в UTC, как указано в строке ввода параметром «GMT». Прежде использовалось локальное часовое пояс. Возвращается целое число (нет дробных секунд в формате входных данных)

ssl.get_server_certificate(addr, ssl_version=PROTOCOL_TLS, ca_certs=None)

При заданном адресе addr защищенного SSL-сервера, как пары (имя_хоста, номер_порта), извлекает сертификат сервера и возвращает его в формате PEM. Если ssl_version указан, используется указанная версия протокола SSL для подключения к серверу. Если ca_certs указан, он должен содержать список корневых сертификатов в том же формате, что и для этого параметра в wrap_socket(). Вызов попытается проверить сертификат сервера по отношению к этому набору корневых сертификатов и завершится ошибкой, если проверка не пройдёт.

Изменено в версии 3.3: Эта функция теперь совместима с IPv6.

Изменено в версии 3.5: Значение по умолчанию для ssl_version изменено с PROTOCOL_SSLv3 на PROTOCOL_TLS для максимальной совместимости с современными серверами.

ssl.DER_cert_to_PEM_cert(DER_cert_bytes)

При заданном сертификате в формате DER-кодированного блока байтов возвращает строку в формате PEM для того же сертификата.

ssl.PEM_cert_to_DER_cert(PEM_cert_string)

При заданном сертификате в формате ASCII PEM возвращает закодированную последовательность байтов DER для этого же сертификата.

ssl.get_default_verify_paths()

Возвращает кортеж с именами путей к файлам по умолчанию cafile и capath OpenSSL. Пути такие же, как и используемые SSLContext.set_default_verify_paths(). Возвращаемое значение представляет собой именованный кортеж DefaultVerifyPaths.

  • cafile - разрешённый путь к cafile или None если файл не существует,
  • capath - разрешённый путь к capath или None если директория не существует,
  • openssl_cafile_env - переменная окружения OpenSSL, указывающая на cafile,
  • openssl_cafile - жёстко заданный путь к cafile,
  • openssl_capath_env - переменная окружения OpenSSL, указывающая на capath,
  • openssl_capath - жёстко заданный путь к каталогу capath

Доступность: LibreSSL игнорирует переменные окружения openssl_cafile_env и openssl_capath_env.

Введено в версии 3.4.

ssl.enum_certificates(store_name)

Извлечение сертификатов из хранилища сертификатов системы Windows. store_name может быть одним из CA, ROOT или MY. Windows может предоставлять и другие хранилища сертификатов.

Функция возвращает список кортежей (cert_bytes, encoding_type, trust). Encoding_type указывает кодировку cert_bytes. Это либо x509_asn для данных ASN.1 X.509, либо pkcs_7_asn для данных ASN.1 PKCS#7. Trust определяет назначение сертификата как набор OIDS или точно True если сертификат является надёжным для всех целей.

Пример:

>>> ssl.enum_certificates("CA")
[(b'data...', 'x509_asn', {'1.3.6.1.5.5.7.3.1', '1.3.6.1.5.5.7.3.2'}),
 (b'data...', 'x509_asn', True)]

Доступность: Windows.

Введено в версии 3.4.

ssl.enum_crls(store_name)

Извлечение CRL из хранилища сертификатов системы Windows. store_name может быть одним из CA, ROOT или MY. Windows может предоставлять и другие хранилища сертификатов.

Функция возвращает список кортежей (cert_bytes, encoding_type, trust). Encoding_type указывает кодировку cert_bytes. Это либо x509_asn для данных ASN.1 X.509, либо pkcs_7_asn для данных ASN.1 PKCS#7.

Доступность: Windows.

Введено в версии 3.4.

18.2.1.5. Постоянные значения

Все константы теперь являются коллекциями enum.IntEnum или enum.IntFlag.

Введено в версии 3.6.

ssl.CERT_NONE

Возможные значения для SSLContext.verify_mode или параметра cert_reqs для wrap_socket(). За исключением PROTOCOL_TLS_CLIENT, это режим по умолчанию. При работе с клиентскими сокетами принимается практически любой сертификат. Ошибки проверки, такие как недоверенный или просроченный сертификат, игнорируются и не прерывают установление соединения TLS/SSL.

В режиме сервера не запрашивается сертификат клиента, поэтому клиент не отправляет его для проверки сертификата клиента.

См. обсуждение Соображения по безопасности ниже.

ssl.CERT_OPTIONAL

Возможные значения для SSLContext.verify_mode или параметра cert_reqs для wrap_socket(). В режиме клиента CERT_OPTIONAL имеет то же значение, что и CERT_REQUIRED. Рекомендуется использовать CERT_REQUIRED для клиентских сокетов.

В режиме сервера запрос на сертификат клиента отправляется клиенту. Клиент может либо проигнорировать запрос, либо отправить сертификат, чтобы выполнить проверку сертификата клиента TLS. Если клиент выбирает отправку сертификата, он проверяется. Любая ошибка проверки немедленно прерывает установление соединения TLS.

Использование этого значения требует наличия набора действительных сертификатов CA, которые передаются либо в SSLContext.load_verify_locations(), либо в качестве значения параметра ca_certs для wrap_socket().

ssl.CERT_REQUIRED

Возможные значения для SSLContext.verify_mode или параметра cert_reqs для wrap_socket(). В этом режиме сертификаты требуются от другого конца соединения сокета; если сертификат не предоставлен или его проверка завершается ошибкой, будет поднята ошибка SSLError. Этот режим недостаточен для проверки сертификата в режиме клиента, так как не соответствует именам хостов. Необходимо также включить check_hostname для проверки подлинности сертификата. PROTOCOL_TLS_CLIENT использует CERT_REQUIRED и по умолчанию включает check_hostname.

Для серверного сокета этот режим обеспечивает обязательную проверку сертификата клиента TLS. Запрос на сертификат клиента отправляется клиенту, и клиент должен предоставить действительный и надёжный сертификат.

Использование этого значения требует наличия набора действительных сертификатов CA, которые передаются либо в SSLContext.load_verify_locations(), либо в качестве значения параметра ca_certs для wrap_socket().

class ssl.VerifyMode

Коллекция enum.IntEnum констант CERT_*.

Введено в версии 3.6.

ssl.VERIFY_DEFAULT

Возможные значения для SSLContext.verify_flags. В этом режиме списки отзыва сертификатов (CRL) не проверяются. По умолчанию OpenSSL не требует и не проверяет CRL.

Введено в версии 3.4.

ssl.VERIFY_CRL_CHECK_LEAF

Возможные значения для SSLContext.verify_flags. В этом режиме проверяется только сертификат peer, но не промежуточные сертификаты CA. Этот режим требует действительный CRL, подписанный издателем сертификата peer (его прямым предком CA). Если не загружен соответствующий сертификат SSLContext.load_verify_locations, проверка завершится неудачей.

Введено в версии 3.4.

ssl.VERIFY_CRL_CHECK_CHAIN

Возможные значения для SSLContext.verify_flags. В этом режиме проверяются CRL всех сертификатов в цепочке сертификатов peer.

Введено в версии 3.4.

ssl.VERIFY_X509_STRICT

Возможная величина для SSLContext.verify_flags для отключения обходных путей для повреждённых сертификатов X.509.

Новое в версии 3.4.

ssl.VERIFY_X509_TRUSTED_FIRST

Возможная величина для SSLContext.verify_flags. Она указывает OpenSSL на предпочтение проверенных сертификатов при построении цепочки доверия для проверки сертификата. Этот флаг включён по умолчанию.

Новое в версии 3.4.4.

class ssl.VerifyFlags

enum.IntFlag коллекция констант VERIFY_*.

Новое в версии 3.6.

ssl.PROTOCOL_TLS

Выбирает самую высокую версию протокола, поддерживаемую как клиентом, так и сервером. Несмотря на название, этот параметр может выбрать как протоколы «SSL», так и «TLS».

Новое в версии 3.6.

ssl.PROTOCOL_TLS_CLIENT

Автоматически подбирает самую высокую версию протокола, как и PROTOCOL_TLS, но поддерживает только подключения типа клиентских SSLSocket. Протокол включает CERT_REQUIRED и check_hostname по умолчанию.

Новое в версии 3.6.

ssl.PROTOCOL_TLS_SERVER

Автоматически подбирает самую высокую версию протокола, как и PROTOCOL_TLS, но поддерживает только подключения типа серверных SSLSocket.

Новое в версии 3.6.

ssl.PROTOCOL_SSLv23

Псевдоним для данных:PROTOCOL_TLS.

Устаревшее с версии 3.6: Используйте PROTOCOL_TLS вместо этого.

ssl.PROTOCOL_SSLv2

Выбирает SSL версии 2 в качестве протокола шифрования канала.

Этот протокол недоступен, если OpenSSL скомпилирован с флагом OPENSSL_NO_SSL2.

Предупреждение

SSL версии 2 небезопасен. Его использование крайне не рекомендуется.

Устаревшее с версии 3.6: OpenSSL удалил поддержку SSLv2.

ssl.PROTOCOL_SSLv3

Выбирает SSL версию 3 в качестве протокола шифрования канала.

Этот протокол недоступен, если OpenSSL скомпилирован с флагом OPENSSL_NO_SSLv3.

Предупреждение

SSL версии 3 небезопасен. Его использование крайне не рекомендуется.

Устаревшее с версии 3.6: OpenSSL устарел все протоколы, специфичные для версии. Используйте протокол по умолчанию PROTOCOL_TLS с флагами, такими как OP_NO_SSLv3 вместо этого.

ssl.PROTOCOL_TLSv1

Выбирает TLS версию 1.0 в качестве протокола шифрования канала.

Устаревшее с версии 3.6: OpenSSL устарел все протоколы, специфичные для версии. Используйте протокол по умолчанию PROTOCOL_TLS с флагами, такими как OP_NO_SSLv3 вместо этого.

ssl.PROTOCOL_TLSv1_1

Выбирает TLS версию 1.1 в качестве протокола шифрования канала. Доступен только с openssl версией 1.0.1+.

Новое в версии 3.4.

Устаревшее с версии 3.6: OpenSSL устарел все протоколы, специфичные для версии. Используйте протокол по умолчанию PROTOCOL_TLS с флагами, такими как OP_NO_SSLv3 вместо этого.

ssl.PROTOCOL_TLSv1_2

Выбирает TLS версию 1.2 в качестве протокола шифрования канала. Это самая современная версия, и, вероятно, лучший выбор для максимальной защиты, если обе стороны её поддерживают. Доступен только с openssl версией 1.0.1+.

Новое в версии 3.4.

Устаревшее с версии 3.6: OpenSSL устарел все протоколы, специфичные для версии. Используйте протокол по умолчанию PROTOCOL_TLS с флагами, такими как OP_NO_SSLv3 вместо этого.

ssl.OP_ALL

Включает обходные пути для различных ошибок, присутствующих в других реализациях SSL. Этот параметр установлен по умолчанию. Он не обязательно устанавливает те же флаги, что и постоянная OpenSSL SSL_OP_ALL.

Новое в версии 3.2.

ssl.OP_NO_SSLv2

Предотвращает подключение SSLv2. Этот параметр применим только в сочетании с PROTOCOL_TLS. Он предотвращает выбор SSLv2 в качестве версии протокола.

Новое в версии 3.2.

Устаревшее с версии 3.6: SSLv2 устарел

ssl.OP_NO_SSLv3

Предотвращает подключение SSLv3. Этот параметр применим только в сочетании с PROTOCOL_TLS. Он предотвращает выбор SSLv3 в качестве версии протокола.

Новое в версии 3.2.

Устаревшее с версии 3.6: SSLv3 устарел

ssl.OP_NO_TLSv1

Предотвращает подключение TLSv1. Этот параметр применим только в сочетании с PROTOCOL_TLS. Он предотвращает выбор TLSv1 в качестве версии протокола.

Новое в версии 3.2.

ssl.OP_NO_TLSv1_1

Предотвращает подключение TLSv1.1. Этот параметр применим только в сочетании с PROTOCOL_TLS. Он предотвращает выбор TLSv1.1 в качестве версии протокола. Доступен только с openssl версией 1.0.1+.

Новое в версии 3.4.

ssl.OP_NO_TLSv1_2

Предотвращает подключение TLSv1.2. Этот параметр применим только в сочетании с PROTOCOL_TLS. Он предотвращает выбор TLSv1.2 в качестве версии протокола. Доступен только с openssl версией 1.0.1+.

Новое в версии 3.4.

ssl.OP_NO_TLSv1_3

Предотвращает подключение TLSv1.3. Этот параметр применим только в сочетании с PROTOCOL_TLS. Он предотвращает выбор TLSv1.3 в качестве версии протокола. TLS 1.3 доступен с OpenSSL 1.1.1 или более поздней версией. Когда Python был скомпилирован с более старой версией OpenSSL, флаг по умолчанию равен 0.

Новое в версии 3.6.3.

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.

END_OF_DOCUMENT_MARKER
ssl.OP_ENABLE_MIDDLEBOX_COMPAT

Отправить фиктивные сообщения Change Cipher Spec (CCS) в рукопожатии TLS 1.3, чтобы соединение TLS 1.3 выглядело более похожим на соединение TLS 1.2.

Этот параметр доступен только с OpenSSL 1.1.1 и более поздними версиями.

Новая версия 3.6.7.

ssl.OP_NO_COMPRESSION

Отключить сжатие на канале SSL. Это полезно, если протокол приложения поддерживает собственную схему сжатия.

Этот параметр доступен только с OpenSSL 1.0.0 и более поздними версиями.

Новая версия 3.3.

class ssl.Options

enum.IntFlag коллекция констант OP_*.

ssl.OP_NO_TICKET

Запретить клиенту запрашивать билет сессии.

Новая версия 3.6.

ssl.HAS_ALPN

Поддерживает ли библиотека OpenSSL встроенную поддержку расширения TLS Application-Layer Protocol Negotiation, как описано в RFC 7301.

Новая версия 3.5.

ssl.HAS_ECDH

Поддерживает ли библиотека OpenSSL встроенную поддержку обмена ключами Diffie-Hellman на основе эллиптических кривых. Это должно быть истинно, если функция не была явно отключена дистрибутивом.

Новая версия 3.3.

ssl.HAS_SNI

Поддерживает ли библиотека OpenSSL встроенную поддержку расширения Server Name Indication (как определено в RFC 6066).

Новая версия 3.2.

ssl.HAS_NPN

Поддерживает ли библиотека OpenSSL встроенную поддержку Next Protocol Negotiation, как описано в спецификации черновика NPN. Если значение истинно, можно использовать метод SSLContext.set_npn_protocols(), чтобы указать поддерживаемые протоколы.

Новая версия 3.3.

ssl.HAS_TLSv1_3

Поддерживает ли библиотека OpenSSL встроенную поддержку протокола TLS 1.3.

Новая версия 3.6.3.

ssl.CHANNEL_BINDING_TYPES

Список поддерживаемых типов привязки канала TLS. Строки в этом списке могут быть использованы в качестве аргументов для SSLSocket.get_channel_binding().

Новая версия 3.3.

ssl.OPENSSL_VERSION

Строка версии загруженной библиотеки OpenSSL:

>>> ssl.OPENSSL_VERSION
'OpenSSL 1.0.2k  26 Jan 2017'

Новая версия 3.2.

ssl.OPENSSL_VERSION_INFO

Кортеж из пяти целых чисел, представляющих информацию о версии библиотеки OpenSSL:

>>> ssl.OPENSSL_VERSION_INFO
(1, 0, 2, 11, 15)

Новая версия 3.2.

ssl.OPENSSL_VERSION_NUMBER

Исходное число версии библиотеки OpenSSL, как целое число:

>>> ssl.OPENSSL_VERSION_NUMBER
268443839
>>> hex(ssl.OPENSSL_VERSION_NUMBER)
'0x100020bf'

Новая версия 3.2.

ssl.ALERT_DESCRIPTION_HANDSHAKE_FAILURE
ssl.ALERT_DESCRIPTION_INTERNAL_ERROR
ALERT_DESCRIPTION_*

Описание сигналов тревоги из RFC 5246 и других. Реестр сигналов тревоги TLS IANA содержит этот список и ссылки на RFC, где определено их значение.

Используется как возвращаемое значение функции обратного вызова в SSLContext.set_servername_callback().

Новая версия 3.4.

class ssl.AlertDescription

enum.IntEnum коллекция констант ALERT_DESCRIPTION_*.

Новая версия 3.6.

Purpose.SERVER_AUTH

Параметр для create_default_context() и SSLContext.load_default_certs(). Это значение указывает, что контекст может использоваться для аутентификации веб-серверов (следовательно, он будет использоваться для создания сокетов клиента).

Новая версия 3.4.

Purpose.CLIENT_AUTH

Параметр для create_default_context() и SSLContext.load_default_certs(). Это значение указывает, что контекст может использоваться для аутентификации веб-клиентов (следовательно, он будет использоваться для создания сокетов сервера).

Новая версия 3.4.

class ssl.SSLErrorNumber

enum.IntEnum коллекция констант SSL_ERROR_*.

Новая версия 3.6.

18.2.2. SSL Сокеты

class ssl.SSLSocket(socket.socket)

Сокеты SSL предоставляют следующие методы Объектов сокета:

  • accept()
  • bind()
  • close()
  • connect()
  • detach()
  • fileno()
  • getpeername(), getsockname()
  • getsockopt(), setsockopt()
  • gettimeout(), settimeout(), setblocking()
  • listen()
  • makefile()
  • recv(), recv_into() (но передача аргумента flags отличного от нуля запрещена)
  • send(), sendall() (с тем же ограничением)
  • sendfile() (но os.sendfile будет использоваться только для текстовых сокетов, в противном случае будет использоваться send())
  • shutdown()

Однако, так как протокол SSL (и TLS) имеет свою собственную структуру поверх TCP, абстракция сокетов SSL может в определённых отношениях отличаться от спецификации обычных сокетов на уровне ОС. Обратите особое внимание на примечания о неблокирующих сокетах.

Обычно SSLSocket не создаются напрямую, а с помощью метода SSLContext.wrap_socket().

Изменено в версии 3.5: Метод sendfile() был добавлен.

Изменено в версии 3.5: shutdown() не сбрасывает таймаут сокета каждый раз, когда принимаются или отправляются байты. Таймаут сокета теперь представляет максимальное общее время закрытия.

Устаревшее начиная с версии 3.6: Не рекомендуется создавать экземпляр SSLSocket напрямую, используйте SSLContext.wrap_socket() для обертывания сокета.

Сокеты SSL также имеют следующие дополнительные методы и атрибуты:

SSLSocket.read(len=1024, buffer=None)

Прочитать до len байт данных из сокета SSL и вернуть результат как экземпляр bytes. Если buffer указан, то прочитать в буфер вместо этого и вернуть количество прочитанных байтов.

Вызовите SSLWantReadError или SSLWantWriteError, если сокет неблокирующий и чтение заблокирует выполнение.

Поскольку в любое время возможна повторная настройка, вызов read() может также вызвать операции записи.

Изменено в версии 3.5: Таймаут сокета больше не сбрасывается каждый раз, когда принимаются или отправляются байты. Таймаут сокета теперь представляет максимальное общее время чтения до len байтов.

Устаревшее начиная с версии 3.6: Используйте recv() вместо read().

SSLSocket.write(buf)

Записать buf в сокет SSL и вернуть количество записанных байтов. Аргумент buf должен быть объектом, поддерживающим интерфейс буфера.

Вызовите SSLWantReadError или SSLWantWriteError, если сокет неблокирующий и запись заблокирует выполнение.

Поскольку в любое время возможна повторная настройка, вызов write() может также вызвать операции чтения.

Изменено в версии 3.5: Таймаут сокета больше не сбрасывается каждый раз, когда принимаются или отправляются байты. Таймаут сокета теперь представляет максимальное общее время записи buf.

Устаревшее начиная с версии 3.6: Используйте send() вместо write().

Примечание

Методы read() и write() — это низкоуровневые методы, которые считывают и записывают нешифрованные данные прикладного уровня и дешифруют/шифруют их в шифрованные данные уровня сети. Эти методы требуют активного соединения SSL, т. е. рукопожатие было завершено и SSLSocket.unwrap() не был вызван.

Обычно вы должны использовать методы API сокета, такие как recv() и send(), вместо этих методов.

SSLSocket.do_handshake()

Выполнить рукопожатие SSL.

Изменено в версии 3.4: Метод рукопожатия также выполняет match_hostname(), когда атрибут check_hostname сокета context равен true.

Изменено в версии 3.5: Таймаут сокета больше не сбрасывается каждый раз, когда принимаются или отправляются байты. Таймаут сокета теперь представляет максимальное общее время рукопожатия.

SSLSocket.getpeercert(binary_form=False)

Если для узла на другом конце соединения нет сертификата, возвращается None. Если рукопожатие SSL ещё не завершено, генерируется исключение ValueError.

Если параметр binary_form равен False, а сертификат был получен от узла, этот метод возвращает экземпляр dict. Если сертификат не был проверен, возвращается пустой словарь. Если сертификат был проверен, возвращается словарь с несколькими ключами, среди которых subject (субъект, для которого был выпущен сертификат) и issuer (субъект, выпустивший сертификат). Если сертификат содержит экземпляр расширения Subject Alternative Name (см. RFC 3280), в словаре также будет ключ subjectAltName.

Поля subject и issuer представляют собой кортежи, содержащие последовательность относительных отличительных имён (RDNs), указанных в структуре данных сертификата для соответствующих полей, а каждое 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.

Изменено в версии 3.4: Исключение ValueError генерируется, если рукопожатие не завершено. Возвращаемый словарь включает дополнительные элементы расширений X509v3, такие как crlDistributionPoints, caIssuers и URI OCSP.

SSLSocket.cipher()

Возвращает кортеж из трёх значений: имя используемого шифра, версия протокола SSL, определяющего его использование, и количество используемых секретных бит. Если соединение не установлено, возвращает None.

SSLSocket.shared_ciphers()

Возвращает список шифров, общих для клиента во время рукопожатия. Каждый элемент возвращаемого списка — это кортеж из трёх значений: имя шифра, версия протокола SSL, определяющего его использование, и количество используемых секретных бит. shared_ciphers() возвращает None если соединение не установлено или сокет является клиентским.

Добавлена в версии 3.5.

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_alpn_protocol()

Возвращает протокол, выбранный во время рукопожатия TLS. Если SSLContext.set_alpn_protocols() не вызывался, если другая сторона не поддерживает ALPN, если этот сокет не поддерживает ни один из предложенных клиентом протоколов или если рукопожатие ещё не произошло, возвращается None.

Добавлена в версии 3.5.

SSLSocket.selected_npn_protocol()

Возвращает протокол более высокого уровня, выбранный во время рукопожатия TLS/SSL. Если SSLContext.set_npn_protocols() не вызывался или если другая сторона не поддерживает NPN, или если рукопожатие ещё не произошло, возвращается None.

Добавлена в версии 3.3.

SSLSocket.unwrap()

Выполняет рукопожатие завершения SSL, удаляя слой TLS из базового сокета и возвращая базовый объект сокета. Это можно использовать для перехода от зашифрованной работы по соединению к незашифрованной. Возвращённый сокет всегда следует использовать для дальнейшего общения с другой стороной соединения, а не исходный сокет.

SSLSocket.verify_client_post_handshake()

Запрашивает аутентификацию после рукопожатия (PHA) от клиента TLS 1.3. PHA может быть инициирована только для соединения TLS 1.3 с серверного сокета после начального рукопожатия TLS и с включённой PHA с обеих сторон, см. SSLContext.post_handshake_auth.

Метод не выполняет обмен сертификатами немедленно. Серверная сторона отправляет CertificateRequest во время следующего события записи и ожидает ответа клиента с сертификатом во время следующего события чтения.

Если не соблюдается какое-либо условие (например, не TLS 1.3, PHA не включена), генерируется исключение SSLError.

Добавлена в версии 3.6.7.

Примечание

Доступно только с OpenSSL 1.1.1 и включённым TLS 1.3. Без поддержки TLS 1.3 метод генерирует исключение NotImplementedError.

SSLSocket.version()

Возвращает фактическую версию протокола SSL, согласованную соединением, в виде строки или None при отсутствии защищённого соединения. Возможные значения, возвращаемые на момент написания, включают "SSLv2", "SSLv3", "TLSv1", "TLSv1.1" и "TLSv1.2". Более поздние версии OpenSSL могут определять дополнительные значения возврата.

Добавлена в версии 3.5.

SSLSocket.pending()

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

SSLSocket.context

Объект SSLContext, к которому привязан этот сокет SSL. Если сокет SSL был создан с использованием функции верхнего уровня wrap_socket() (а не SSLContext.wrap_socket()), это пользовательский объект контекста, созданный для этого сокета SSL.

Добавлена в версии 3.2.

SSLSocket.server_side

Булево значение, равное True для серверных сокетов и False для клиентских сокетов.

Добавлена в версии 3.2.

SSLSocket.server_hostname

Имя хоста сервера: тип str, или None для серверных сокетов или если имя хоста не было указано в конструкторе.

Добавлена в версии 3.2.

SSLSocket.session

Объект SSLSession для этого SSL-соединения. Сессия доступна для сокетов клиента и сервера после выполнения рукопожатия TLS. Для сокетов клиента сессия может быть установлена перед вызовом do_handshake() для повторного использования сессии.

Добавлена в версии 3.6.

SSLSocket.session_reused

Добавлена в версии 3.6.

18.2.3. Контексты SSL

Добавлена в версии 3.2.

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

class ssl.SSLContext(protocol=PROTOCOL_TLS)

Создает новый контекст SSL. Можно передать protocol, которое должно быть одним из PROTOCOL_* констант, определенных в этом модуле. PROTOCOL_TLS в настоящее время рекомендуется для максимальной совместимости и является значением по умолчанию.

См. также

create_default_context() позволяет модулю ssl выбирать настройки безопасности для заданной цели.

Изменено в версии 3.6: Контекст создается со значениями по умолчанию, соответствующими безопасности. Параметры OP_NO_COMPRESSION, OP_CIPHER_SERVER_PREFERENCE, OP_SINGLE_DH_USE, OP_SINGLE_ECDH_USE, OP_NO_SSLv2 (кроме PROTOCOL_SSLv2) и OP_NO_SSLv3 (кроме PROTOCOL_SSLv3) устанавливаются по умолчанию. Начальный список наборов шифров содержит только HIGH шифры, не содержит NULL шифров и не содержит MD5 шифров (кроме PROTOCOL_SSLv2).

Объекты SSLContext имеют следующие методы и атрибуты:

SSLContext.cert_store_stats()

Получает статистику по количеству загруженных сертификатов X.509, количеству сертификатов X.509, помеченных как сертификаты CA, и спискам отозванных сертификатов в виде словаря.

Пример для контекста с одним сертификатом CA и одним другим сертификатом:

>>> context.cert_store_stats()
{'crl': 0, 'x509_ca': 1, 'x509': 2}

Добавлена в версии 3.4.

SSLContext.load_cert_chain(certfile, keyfile=None, password=None)

Загружает закрытый ключ и соответствующий сертификат. Строка certfile должна указывать путь к файлу в формате PEM, содержащему сертификат и любое количество сертификатов CA, необходимых для проверки подлинности сертификата. Строка keyfile, если указана, должна указывать путь к файлу, содержащему закрытый ключ. В противном случае закрытый ключ будет взят из certfile. Дополнительная информация о хранении сертификата в certfile приведена в разделе Сертификаты.

Аргумент password может быть функцией, вызываемой для получения пароля для дешифрования закрытого ключа. Она будет вызвана только в том случае, если закрытый ключ зашифрован и необходим пароль. Она будет вызвана без аргументов и должна вернуть строку, байты или массив байтов. Если возвращаемое значение является строкой, оно будет закодировано в UTF-8 перед использованием для дешифрования ключа. В качестве альтернативы можно напрямую указать строку, байты или массив байтов в качестве аргумента password. Он будет проигнорирован, если закрытый ключ не зашифрован и пароль не нужен.

Если аргумент password не указан и необходим пароль, будет использоваться встроенный механизм запроса пароля OpenSSL для интерактивного запроса пароля у пользователя.

Если закрытый ключ не соответствует сертификату, будет поднято исключение SSLError.

Изменено в версии 3.3: Добавлен необязательный аргумент password.

SSLContext.load_default_certs(purpose=Purpose.SERVER_AUTH)

Загружает набор стандартных сертификатов «центра сертификации» (CA) из стандартных расположений. В Windows он загружает сертификаты CA из системных хранилищ CA и ROOT. В других системах он вызывает SSLContext.set_default_verify_paths(). В будущем метод может загружать сертификаты CA и из других расположений.

Флаг purpose определяет, какие сертификаты CA загружаются. Параметры по умолчанию Purpose.SERVER_AUTH загружают сертификаты, которые помечены и доверяются для проверки подлинности веб-сервера TLS (сокеты со стороны клиента). Purpose.CLIENT_AUTH загружает сертификаты CA для проверки сертификата клиента на стороне сервера.

Добавлена в версии 3.4.

SSLContext.load_verify_locations(cafile=None, capath=None, cadata=None)

Загружает набор сертификатов «центра сертификации» (CA), используемых для проверки сертификатов других узлов, когда verify_mode отличается от CERT_NONE. Должен быть указан хотя бы один из cafile или capath.

Этот метод также может загрузить списки отозванных сертификатов (CRL) в форматах PEM или DER. Для использования CRL необходимо правильно настроить SSLContext.verify_flags.

Строка cafile, если указана, представляет путь к файлу, содержащему конкатенированные сертификаты CA в формате PEM. Подробности о расположении сертификатов в этом файле см. в разделе Сертификаты.

Строка capath, если указана, представляет путь к каталогу, содержащему несколько сертификатов CA в формате PEM, следуя специфической структуре OpenSSL.

Объект cadata, если указан, представляет собой строку ASCII с одним или несколькими сертификатами PEM или объект-подобный байтам с сертификатами DER. Как и в случае с capath, лишние строки вокруг сертификатов PEM игнорируются, но должен быть присутствовать хотя бы один сертификат.

Изменено в версии 3.4: Добавлен необязательный аргумент cadata

SSLContext.get_ca_certs(binary_form=False)

Возвращает список загруженных сертификатов «центра сертификации» (CA). Если параметр binary_form равен False, каждое значение списка — это словарь, подобный выводу из SSLSocket.getpeercert(). В противном случае метод возвращает список сертификатов в формате DER. Возвращаемый список не содержит сертификаты из capath, если сертификат не был запрошен и загружен SSL-соединением.

Примечание

Сертификаты из каталога capath не загружаются, пока они не были использованы хотя бы один раз.

Добавлена в версии 3.4.

SSLContext.get_ciphers()

Возвращает список включенных шифров. Список упорядочен по приоритету шифра. См. SSLContext.set_ciphers().

Пример:

>>> ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
>>> ctx.set_ciphers('ECDHE+AESGCM:!ECDSA')
>>> ctx.get_ciphers()  # OpenSSL 1.0.x
[{'alg_bits': 256,
  'description': 'ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH     Au=RSA  '
                 'Enc=AESGCM(256) Mac=AEAD',
  'id': 50380848,
  'name': 'ECDHE-RSA-AES256-GCM-SHA384',
  'protocol': 'TLSv1/SSLv3',
  'strength_bits': 256},
 {'alg_bits': 128,
  'description': 'ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH     Au=RSA  '
                 'Enc=AESGCM(128) Mac=AEAD',
  'id': 50380847,
  'name': 'ECDHE-RSA-AES128-GCM-SHA256',
  'protocol': 'TLSv1/SSLv3',
  'strength_bits': 128}]
В OpenSSL 1.1 и более поздних версиях словарь шифра содержит дополнительные поля::
>>> ctx.get_ciphers()  # OpenSSL 1.1+
[{'aead': True,
  'alg_bits': 256,
  'auth': 'auth-rsa',
  'description': 'ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH     Au=RSA  '
                 'Enc=AESGCM(256) Mac=AEAD',
  'digest': None,
  'id': 50380848,
  'kea': 'kx-ecdhe',
  'name': 'ECDHE-RSA-AES256-GCM-SHA384',
  'protocol': 'TLSv1.2',
  'strength_bits': 256,
  'symmetric': 'aes-256-gcm'},
 {'aead': True,
  'alg_bits': 128,
  'auth': 'auth-rsa',
  'description': 'ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH     Au=RSA  '
                 'Enc=AESGCM(128) Mac=AEAD',
  'digest': None,
  'id': 50380847,
  'kea': 'kx-ecdhe',
  'name': 'ECDHE-RSA-AES128-GCM-SHA256',
  'protocol': 'TLSv1.2',
  'strength_bits': 128,
  'symmetric': 'aes-128-gcm'}]

Доступно: OpenSSL 1.0.2+

Добавлена в версии 3.6.

SSLContext.set_default_verify_paths()

Загружает набор стандартных сертификатов «центра сертификации» (CA) из пути к файловой системе, определенного при построении библиотеки OpenSSL. К сожалению, нет простого способа узнать, удался ли этот метод: ошибка не возвращается, если сертификаты не найдены. Если библиотека OpenSSL предоставляется в составе операционной системы, то, скорее всего, она настроена должным образом.

SSLContext.set_ciphers(ciphers)

Установите доступные шифры для сокетов, созданных с этим контекстом. Он должен быть строкой в формате списка шифров OpenSSL OpenSSL cipher list format. Если ни один шифр не может быть выбран (потому что опции времени компиляции или другие настройки запрещают использование всех указанных шифров), будет поднято исключение SSLError.

Примечание

при подключении метод SSLSocket.cipher() сокетов SSL вернёт текущий выбранный шифр.

В OpenSSL 1.1.1 наборы шифров TLS 1.3 включены по умолчанию. Их нельзя отключить с помощью set_ciphers().

SSLContext.set_alpn_protocols(protocols)

Укажите, какие протоколы должен рекламировать сокет во время рукопожатия SSL/TLS. Это должен быть список строк ASCII, таких как ['http/1.1', 'spdy/2'], упорядоченных по приоритету. Выбор протокола происходит во время рукопожатия и происходит в соответствии с RFC 7301. После успешного рукопожатия метод SSLSocket.selected_alpn_protocol() вернёт согласованный протокол.

Этот метод вызовет NotImplementedError, если HAS_ALPN равно False.

OpenSSL 1.1.0 до 1.1.0e прервёт рукопожатие и вызовет SSLError, когда обе стороны поддерживают ALPN, но не могут договориться о протоколе. Версии 1.1.0f и выше ведут себя как 1.0.2, SSLSocket.selected_alpn_protocol() возвращает None.

Добавлена в версии 3.5.

SSLContext.set_npn_protocols(protocols)

Укажите, какие протоколы должен рекламировать сокет во время рукопожатия SSL/TLS. Это должен быть список строк, таких как ['http/1.1', 'spdy/2'], упорядоченных по приоритету. Выбор протокола происходит во время рукопожатия и происходит в соответствии с NPN draft specification. После успешного рукопожатия метод SSLSocket.selected_npn_protocol() вернёт согласованный протокол.

Этот метод вызовет NotImplementedError, если HAS_NPN равно False.

Добавлена в версии 3.3.

SSLContext.set_servername_callback(server_name_callback)

Зарегистрируйте функцию обратного вызова, которая будет вызываться после получения сообщения TLS Client Hello сервером SSL/TLS, когда клиент TLS указывает указание имени сервера. Механизм указания имени сервера описан в RFC 6066 разделе 3 - Указание имени сервера.

Только один обратный вызов может быть установлен на SSLContext. Если server_name_callback равно None, обратный вызов отключён. Вызов этой функции в последующий раз отключит ранее зарегистрированный обратный вызов.

Функция обратного вызова, server_name_callback, вызывается с тремя аргументами: первый — ssl.SSLSocket, второй — строка, представляющая имя сервера, с которым клиент намерен общаться (или None, если TLS Client Hello не содержит имени сервера), и третий — исходный SSLContext. Аргумент имени сервера — имя сервера, декодированное с помощью IDNA.

Типичное использование этого обратного вызова — изменение атрибута ssl.SSLSocket’s SSLSocket.context на новый объект типа SSLContext, представляющий цепочку сертификатов, соответствующую имени сервера.

Из-за ранней фазы согласования TLS доступны только ограниченные методы и атрибуты, такие как SSLSocket.selected_alpn_protocol() и SSLSocket.context. Методы SSLSocket.getpeercert(), SSLSocket.getpeercert(), SSLSocket.cipher() и SSLSocket.compress() требуют, чтобы соединение TLS продвинулось за пределы TLS Client Hello, поэтому они не будут содержать значимых значений и не могут быть безопасно вызваны.

Функция server_name_callback должна возвращать None, чтобы разрешить продолжение переговоров TLS. Если требуется ошибка TLS, можно вернуть константу ALERT_DESCRIPTION_INTERNAL_ERROR. Другие возвращаемые значения приведут к ошибке TLS с фатальным сообщением ALERT_DESCRIPTION_INTERNAL_ERROR.

Если при декодировании имени сервера IDNA произошла ошибка, соединение TLS завершится с фатальным TLS-сообщением об ошибке ALERT_DESCRIPTION_INTERNAL_ERROR клиенту.

Если из функции server_name_callback возникает исключение, соединение TLS завершится фатальным TLS-сообщением об ошибке ALERT_DESCRIPTION_HANDSHAKE_FAILURE.

Этот метод вызовет NotImplementedError, если в библиотеке OpenSSL была определена OPENSSL_NO_TLSEXT при её сборке.

Добавлена в версии 3.4.

SSLContext.load_dh_params(dhfile)

Загрузите параметры генерации ключей для обмена ключами Диффи-Хеллмана (DH). Использование обмена ключами DH улучшает конфиденциальность вперёд за счёт вычислительных ресурсов (как на сервере, так и на клиенте). Параметр dhfile должен быть путём к файлу, содержащему параметры DH в формате PEM.

Эта настройка не применяется к клиентским сокетам. Также можно использовать опцию OP_SINGLE_DH_USE для повышения безопасности.

Добавлена в версии 3.3.

SSLContext.set_ecdh_curve(curve_name)

Установите имя кривой для обмена ключами Диффи-Хеллмана на основе эллиптических кривых (ECDH). ECDH значительно быстрее, чем обычный DH, при примерно такой же безопасности. Параметр curve_name должен быть строкой, описывающей известную эллиптическую кривую, например prime256v1 для широко поддерживаемой кривой.

Эта настройка не применяется к клиентским сокетам. Также можно использовать опцию OP_SINGLE_ECDH_USE для повышения безопасности.

Этот метод недоступен, если HAS_ECDH равно False.

Добавлена в версии 3.3.

См. также

SSL/TLS & Perfect Forward Secrecy

Винсент Бернат.

SSLContext.wrap_socket(sock, server_side=False, do_handshake_on_connect=True, suppress_ragged_eofs=True, server_hostname=None, session=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, если server_side имеет значение true.

session, см. session.

Изменено в версии 3.5: Всегда разрешено передавать server_hostname, даже если OpenSSL не имеет SNI.

Изменено в версии 3.6: Добавлен аргумент session.

END_OF_DOCUMENT_MARKER
SSLContext.wrap_bio(incoming, outgoing, server_side=False, server_hostname=None, session=None)

Создать новый экземпляр SSLObject, обернув BIO-объекты incoming и outgoing. SSL-процедуры будут считывать входные данные из BIO incoming и записывать данные в BIO outgoing.

Параметры server_side, server_hostname и session имеют такое же значение, как и в SSLContext.wrap_socket().

Изменено в версии 3.6: Добавлен аргумент session.

SSLContext.session_stats()

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

>>> stats = context.session_stats()
>>> stats['hits'], stats['misses']
(0, 0)
SSLContext.check_hostname

Определяет, нужно ли сопоставлять имя хоста сертификата удаленного узла с помощью match_hostname() в SSLSocket.do_handshake(). В контексте verify_mode необходимо установить значение CERT_OPTIONAL или CERT_REQUIRED, а параметр server_hostname необходимо передать в wrap_socket() для сопоставления имени хоста.

Пример:

import socket, ssl

context = ssl.SSLContext()
context.verify_mode = ssl.CERT_REQUIRED
context.check_hostname = True
context.load_default_certs()

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ssl_sock = context.wrap_socket(s, server_hostname='www.verisign.com')
ssl_sock.connect(('www.verisign.com', 443))

Введено в версии 3.4.

Примечание

Эта функция требует OpenSSL 0.9.8f или более поздней версии.

SSLContext.options

Целое число, представляющее набор SSL-параметров, включенных в этом контексте. Значение по умолчанию — OP_ALL, но вы можете указать другие параметры, такие как OP_NO_SSLv2, объединяя их с помощью операции побитового ИЛИ.

Примечание

С версиями OpenSSL, более ранними чем 0.9.8m, можно только устанавливать параметры, а не очищать их. Попытка очистить параметр (сбросить соответствующие биты) вызовет ValueError.

Изменено в версии 3.6: SSLContext.options возвращает флаги Options:

>>> ssl.create_default_context().options
<Options.OP_ALL|OP_NO_SSLv3|OP_NO_SSLv2|OP_NO_COMPRESSION: 2197947391>
SSLContext.post_handshake_auth

Включить пост-рукопожатие аутентификацию клиента TLS 1.3. По умолчанию аутентификация после рукопожатия отключена, и сервер может запросить сертификат TLS-клиента только во время начального рукопожатия. При включении сервер может запросить сертификат TLS-клиента в любое время после рукопожатия.

При включении на стороне клиентских сокетов клиент сигнализирует серверу, что он поддерживает аутентификацию после рукопожатия.

При включении на стороне серверных сокетов, SSLContext.verify_mode также должен быть установлен на CERT_OPTIONAL или CERT_REQUIRED. Фактический обмен сертификатами клиента откладывается до вызова SSLSocket.verify_client_post_handshake() и выполнения некоторых операций ввода-вывода.

Введено в версии 3.6.7.

Примечание

Доступно только с OpenSSL 1.1.1 и включенным TLS 1.3. Без поддержки TLS 1.3 значение свойства равно None и его нельзя изменить

SSLContext.protocol

Версия протокола, выбранная при построении контекста. Это свойство является только для чтения.

SSLContext.verify_flags

Флаги для операций проверки сертификатов. Можно задавать флаги, такие как VERIFY_CRL_CHECK_LEAF, объединяя их с помощью операции побитового ИЛИ. По умолчанию OpenSSL не требует и не проверяет списки отзыва сертификатов (CRL). Доступен только с openssl версией 0.9.8+.

Введено в версии 3.4.

Изменено в версии 3.6: SSLContext.verify_flags возвращает флаги VerifyFlags:

>>> ssl.create_default_context().verify_flags
<VerifyFlags.VERIFY_X509_TRUSTED_FIRST: 32768>
SSLContext.verify_mode

Определяет, следует ли пытаться проверить сертификаты других узлов и как вести себя при неудачной проверке. Это свойство должно быть одним из CERT_NONE, CERT_OPTIONAL или CERT_REQUIRED.

Изменено в версии 3.6: SSLContext.verify_mode возвращает перечисление VerifyMode:

>>> ssl.create_default_context().verify_mode
<VerifyMode.CERT_REQUIRED: 2>

18.2.4. Сертификаты

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

Сертификат содержит информацию о двух субъектах. Он содержит имя субъекта и открытый ключ субъекта. Он также содержит утверждение второго субъекта, выдающего органа, что субъект является тем, за кого себя выдает, и что это действительно открытый ключ субъекта. Утверждение выдающего органа подписано закрытым ключом выдающего органа, который известен только выдающему органу. Однако любой может проверить утверждение выдающего органа, найдя его открытый ключ, расшифровав утверждение с помощью него и сравнив его с другой информацией в сертификате. Сертификат также содержит информацию о периоде его действия. Это выражается в двух полях, называемых «notBefore» и «notAfter».

При использовании сертификатов в Python клиент или сервер может использовать сертификат, чтобы доказать свою личность. От другой стороны сетевого подключения также может потребоваться предъявить сертификат, и этот сертификат может быть проверен клиентом или сервером, требующим такой проверки. Если проверка завершится неудачно, попытка подключения может вызвать исключение. Проверка выполняется автоматически, основополагающей системой OpenSSL; приложение не должно беспокоиться о ее механизме. Но приложение обычно должно предоставлять наборы сертификатов, чтобы этот процесс мог быть осуществлен.

Python использует файлы для хранения сертификатов. Они должны быть отформатированы в формате «PEM» (см. RFC 1422), представляющем собой закодированную в формате base-64 форму, обернутую заголовком и футером:

-----BEGIN CERTIFICATE-----
... (certificate in base64 PEM encoding) ...
-----END CERTIFICATE-----

18.2.4.1. Цепочки сертификатов

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

-----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. Сертификаты центров сертификации

Если вам требуется проверка сертификата другой стороны подключения, вам необходимо предоставить файл «сертификатов центров сертификации», заполненный цепочками сертификатов для каждого выдающего органа, которому вы доверяете. Этот файл также содержит конкатенацию этих цепочек. При проверке Python будет использовать первую цепочку в файле, которая совпадает. Файл сертификатов платформы может быть использован вызовом SSLContext.load_default_certs(), это делается автоматически с помощью create_default_context().

18.2.4.3. Объединенный ключ и сертификат

Часто закрытый ключ хранится в том же файле, что и сертификат; в этом случае, необходимо передать только параметр 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. Самозаверяющие сертификаты

Если вы собираетесь создать сервер, предоставляющий услуги 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. Примеры

18.2.5.1. Проверка поддержки SSL

Для проверки наличия поддержки SSL в установке Python код пользователя должен использовать следующий идиом:

try:
    import ssl
except ImportError:
    pass
else:
    ...  # do something that requires SSL support

18.2.5.2. Операция на стороне клиента

Этот пример создаёт контекст SSL с рекомендуемыми настройками безопасности для сокетов клиента, включая автоматическую проверку сертификатов:

>>> context = ssl.create_default_context()

Если вы предпочитаете настраивать параметры безопасности самостоятельно, вы можете создать контекст с нуля (но будьте осторожны, что вы можете не угадать настройки):

>>> context = ssl.SSLContext()
>>> context.verify_mode = ssl.CERT_REQUIRED
>>> context.check_hostname = True
>>> context.load_verify_locations("/etc/ssl/certs/ca-bundle.crt")

(Этот фрагмент предполагает, что ваша операционная система размещает набор всех сертификатов центров сертификации в /etc/ssl/certs/ca-bundle.crt; если нет, вы получите ошибку и должны будете настроить расположение)

Когда вы используете контекст для подключения к серверу, CERT_REQUIRED проверяет сертификат сервера: он гарантирует, что сертификат сервера был подписан одним из сертификатов центров сертификации и проверяет правильность подписи:

>>> conn = context.wrap_socket(socket.socket(socket.AF_INET),
...                            server_hostname="www.python.org")
>>> conn.connect(("www.python.org", 443))

Затем вы можете получить сертификат:

>>> cert = conn.getpeercert()

Визуальный осмотр показывает, что сертификат действительно идентифицирует желаемую службу (то есть хост HTTPS www.python.org):

>>> pprint.pprint(cert)
{'OCSP': ('http://ocsp.digicert.com',),
 'caIssuers': ('http://cacerts.digicert.com/DigiCertSHA2ExtendedValidationServerCA.crt',),
 'crlDistributionPoints': ('http://crl3.digicert.com/sha2-ev-server-g1.crl',
                           'http://crl4.digicert.com/sha2-ev-server-g1.crl'),
 'issuer': ((('countryName', 'US'),),
            (('organizationName', 'DigiCert Inc'),),
            (('organizationalUnitName', 'www.digicert.com'),),
            (('commonName', 'DigiCert SHA2 Extended Validation Server CA'),)),
 'notAfter': 'Sep  9 12:00:00 2016 GMT',
 'notBefore': 'Sep  5 00:00:00 2014 GMT',
 'serialNumber': '01BB6F00122B177F36CAB49CEA8B6B26',
 'subject': ((('businessCategory', 'Private Organization'),),
             (('1.3.6.1.4.1.311.60.2.1.3', 'US'),),
             (('1.3.6.1.4.1.311.60.2.1.2', 'Delaware'),),
             (('serialNumber', '3359300'),),
             (('streetAddress', '16 Allen Rd'),),
             (('postalCode', '03894-4801'),),
             (('countryName', 'US'),),
             (('stateOrProvinceName', 'NH'),),
             (('localityName', 'Wolfeboro,'),),
             (('organizationName', 'Python Software Foundation'),),
             (('commonName', 'www.python.org'),)),
 'subjectAltName': (('DNS', 'www.python.org'),
                    ('DNS', 'python.org'),
                    ('DNS', 'pypi.org'),
                    ('DNS', 'docs.python.org'),
                    ('DNS', 'testpypi.org'),
                    ('DNS', 'bugs.python.org'),
                    ('DNS', 'wiki.python.org'),
                    ('DNS', 'hg.python.org'),
                    ('DNS', 'mail.python.org'),
                    ('DNS', 'packaging.python.org'),
                    ('DNS', 'pythonhosted.org'),
                    ('DNS', 'www.pythonhosted.org'),
                    ('DNS', 'test.pythonhosted.org'),
                    ('DNS', 'us.pycon.org'),
                    ('DNS', 'id.python.org')),
 'version': 3}

Теперь SSL-канал установлен и сертификат проверен, вы можете продолжить общение с сервером:

>>> 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 200 OK',
 b'Date: Sat, 18 Oct 2014 18:27:20 GMT',
 b'Server: nginx',
 b'Content-Type: text/html; charset=utf-8',
 b'X-Frame-Options: SAMEORIGIN',
 b'Content-Length: 45679',
 b'Accept-Ranges: bytes',
 b'Via: 1.1 varnish',
 b'Age: 2188',
 b'X-Served-By: cache-lcy1134-LCY',
 b'X-Cache: HIT',
 b'X-Cache-Hits: 11',
 b'Vary: Cookie',
 b'Strict-Transport-Security: max-age=63072000; includeSubDomains',
 b'Connection: close',
 b'',
 b'']

См. обсуждение Соображения по безопасности ниже.

18.2.5.3. Операция на стороне сервера

Для работы на стороне сервера обычно необходимо иметь сертификат сервера и закрытый ключ, каждый в отдельном файле. Сначала вы создадите контекст, содержащий ключ и сертификат, чтобы клиенты могли проверить вашу подлинность. Затем вы откроете сокет, привяжете его к порту, вызовете listen() на нём и начнёте ожидать подключения клиентов:

import socket, ssl

context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
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)
    # empty data means the client is finished with us
    while data:
        if not do_something(connstream, data):
            # we'll assume do_something returns False
            # when we're finished with client
            break
        data = connstream.recv(1024)
    # finished with client

И возвращайтесь к прослушиванию новых подключений клиентов (конечно, реальный сервер, вероятно, обрабатывал бы каждое подключение клиента в отдельном потоке или помещал бы сокеты в неблокирующий режим и использовал цикл событий).

18.2.6. Примечания по неблокирующим сокетам

SSL-сокеты ведут себя немного иначе, чем обычные сокеты в неблокирующем режиме. При работе с неблокирующими сокетами вам необходимо учитывать несколько моментов:

  • Большинство методов SSLSocket будут генерировать либо SSLWantWriteError, либо SSLWantReadError вместо BlockingIOError, если операция ввода-вывода заблокируется. SSLWantReadError будет вызвано, если требуется операция чтения на базовом сокете, а SSLWantWriteError — для операции записи на базовом сокете. Обратите внимание, что попытки записать в SSL-сокет могут потребовать чтения из базового сокета предварительно, а попытки прочитать из SSL-сокета могут потребовать предварительной записи в базовый сокет.

    Изменено в версии 3.5: В более ранних версиях Python метод SSLSocket.send() возвращал ноль вместо генерации SSLWantWriteError или SSLWantReadError.

  • Вызов select() указывает, что сокет на уровне ОС может быть прочитан (или записан в), но это не подразумевает, что в верхнем слое SSL достаточно данных. Например, может прибыть только часть SSL-фрейма. Поэтому вы должны быть готовы обработать SSLSocket.recv() и SSLSocket.send() ошибки и повторить попытку после следующего вызова select().
  • Напротив, поскольку в SSL-слое есть собственная структура, SSL-сокет может иметь доступные данные для чтения без того, чтобы select() об этом знал. Поэтому вы должны сначала вызвать SSLSocket.recv() для слива потенциально доступных данных, а затем блокировать вызов select() только в случае необходимости.

    (разумеется, аналогичные положения применяются при использовании других примитивов, таких как poll(), или тех, что в модуле selectors)

  • Сам SSL-установление будет неблокирующим: метод SSLSocket.do_handshake() должен повторяться до тех пор, пока он не вернётся успешно. Вот краткий обзор использования select() для ожидания готовности сокета:

    while True:
        try:
            sock.do_handshake()
            break
        except ssl.SSLWantReadError:
            select.select([sock], [], [])
        except ssl.SSLWantWriteError:
            select.select([], [sock], [])
    

См. также

Модуль asyncio поддерживает неблокирующие SSL-сокеты и предоставляет API более высокого уровня. Он отслеживает события с использованием модуля selectors и обрабатывает исключения SSLWantWriteError, SSLWantReadError и BlockingIOError. Он также выполняет SSL-установление асинхронно.

18.2.7. Поддержка BIO в памяти

Новое в версии 3.5.

С тех пор, как модуль SSL был представлен в Python 2.6, класс SSLSocket предоставляет две связанные, но отличные области функциональности:

  • Обработка протокола SSL
  • Сетевой ввод-вывод

API сетевого ввода-вывода идентичен API, предоставляемому socket.socket, от которого SSLSocket также наследует. Это позволяет использовать SSL-сокет как прямую замену обычного сокета, что значительно упрощает добавление поддержки SSL в существующее приложение.

Комбинирование обработки протокола SSL и сетевого ввода-вывода обычно работает хорошо, но есть некоторые случаи, когда это не так. Пример — асинхронные фреймворки ввода-вывода, которые хотят использовать другую модель мультиплексирования ввода-вывода, отличную от модели «select/poll на дескрипторе файла» (базирующейся на готовности), которая предполагается socket.socket и внутренними OpenSSL-сокетами IO. Это в основном актуально для платформ, таких как Windows, где эта модель неэффективна. Для этой цели предоставляется сокращённая версия SSLSocket с именем SSLObject.

class ssl.SSLObject

Упрощённая версия SSLSocket, представляющая собой экземпляр протокола SSL, не содержащий методов сетевого ввода-вывода. Этот класс обычно используется разработчиками фреймворков, которые хотят реализовать асинхронный ввод-вывод для SSL через буферы памяти.

Этот класс реализует интерфейс поверх низкоуровневого объекта SSL, реализованного в OpenSSL. Этот объект сохраняет состояние соединения SSL, но не предоставляет собственный сетевой ввод-вывод. Ввод-вывод должен выполняться через отдельные объекты «BIO», которые являются уровнем абстракции ввода-вывода OpenSSL.

Экземпляр SSLObject можно создать, используя метод wrap_bio(). Этот метод создаст экземпляр SSLObject и свяжет его с парой BIO. Входящий BIO используется для передачи данных из Python в экземпляр протокола SSL, а исходящий BIO — для передачи данных в обратном направлении.

Доступны следующие методы:

  • context
  • server_side
  • server_hostname
  • session
  • session_reused
  • read()
  • write()
  • getpeercert()
  • selected_npn_protocol()
  • cipher()
  • shared_ciphers()
  • compression()
  • pending()
  • do_handshake()
  • unwrap()
  • get_channel_binding()

По сравнению с SSLSocket, этот объект не имеет следующих функций:

  • Любой формы сетевого ввода-вывода; recv() и send() читают и записывают только в базовые буферы MemoryBIO.
  • Нет механизма do_handshake_on_connect. Вы всегда должны вручную вызвать do_handshake() для начала рукопожатия.
  • Нет обработки suppress_ragged_eofs. Все условия конца файла, нарушающие протокол, сообщаются с помощью исключения SSLEOFError.
  • Вызов метода unwrap() ничего не возвращает, в отличие от сокета SSL, где он возвращает базовый сокет.
  • Обратный вызов server_name_callback, переданный в SSLContext.set_servername_callback(), получит экземпляр SSLObject вместо экземпляра SSLSocket в качестве первого параметра.

Некоторые замечания, связанные с использованием SSLObject:

  • Все операции ввода-вывода с SSLObject являются неоперативными. Это означает, что, например, read() вызовет SSLWantReadError, если ему потребуется больше данных, чем доступно в входящем BIO.
  • Нет вызова wrap_bio() на уровне модуля, как для wrap_socket(). Экземпляр SSLObject всегда создаётся с помощью SSLContext.

SSLObject взаимодействует с внешним миром с помощью буферов памяти. Класс MemoryBIO предоставляет буфер памяти, который можно использовать для этой цели. Он оборачивает объект памяти OpenSSL BIO (Basic IO):

class ssl.MemoryBIO

Буфер памяти, который можно использовать для передачи данных между Python и экземпляром протокола SSL.

pending

Возвращает количество байтов, в настоящее время находящихся в буфере памяти.

eof

Булево значение, указывающее, находится ли текущее состояние памяти BIO в конце файла.

read(n=-1)

Считывает до n байтов из буфера памяти. Если n не указано или отрицательно, возвращаются все байты.

write(buf)

Записывает байты из buf в память BIO. Аргумент buf должен быть объектом, поддерживающим протокол буфера.

Значение возврата — количество записанных байтов, которое всегда равно длине buf.

write_eof()

Записывает маркер конца файла в память BIO. После вызова этого метода вызов write() запрещён. Атрибут eof станет истинным после считывания всех данных, в настоящее время находящихся в буфере.

18.2.8. Сессия SSL

Введено в версии 3.6.

class ssl.SSLSession

Объект сессии, используемый в session.

id
time
timeout
ticket_lifetime_hint
has_ticket

18.2.9. Учёт безопасности

18.2.9.1. Наилучшие значения по умолчанию

Для использования клиентом, если у вас нет особых требований к политике безопасности, настоятельно рекомендуется использовать функцию create_default_context() для создания контекста SSL. Она загрузит доверенные сертификаты CA системы, включит проверку сертификатов и имени хоста и попытается выбрать разумно безопасные настройки протокола и шифрования.

Например, вот как вы бы использовали класс smtplib.SMTP для создания надёжного, защищённого соединения с SMTP-сервером:

>>> import ssl, smtplib
>>> smtp = smtplib.SMTP("mail.python.org", port=587)
>>> context = ssl.create_default_context()
>>> smtp.starttls(context=context)
(220, b'2.0.0 Ready to start TLS')

Если для подключения требуется сертификат клиента, его можно добавить с помощью SSLContext.load_cert_chain().

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

18.2.9.2. Настройка вручную

18.2.9.2.1. Проверка сертификатов

При прямом вызове конструктора SSLContext, по умолчанию используется значение CERT_NONE. Поскольку это не выполняет аутентификацию другого узла, это может быть небезопасно, особенно в режиме клиента, где в большинстве случаев необходимо гарантировать подлинность сервера, с которым вы взаимодействуете. Поэтому в режиме клиента настоятельно рекомендуется использовать CERT_REQUIRED. Однако этого недостаточно; необходимо также проверить, что сертификат сервера, который можно получить, вызвав SSLSocket.getpeercert(), соответствует требуемому сервису. Для многих протоколов и приложений сервис можно определить по имени хоста; в этом случае можно использовать функцию match_hostname(). Эта общая проверка автоматически выполняется при включении SSLContext.check_hostname.

В режиме сервера, если вы хотите аутентифицировать своих клиентов с помощью SSL-слоя (вместо использования механизма аутентификации более высокого уровня), вам также необходимо указать CERT_REQUIRED и аналогично проверить сертификат клиента.

18.2.9.2.2. Версии протоколов

SSL-версии 2 и 3 считаются небезопасными и поэтому их опасно использовать. Если вы хотите максимальную совместимость между клиентами и серверами, рекомендуется использовать PROTOCOL_TLS_CLIENT или PROTOCOL_TLS_SERVER в качестве версии протокола. SSLv2 и SSLv3 отключены по умолчанию.

>>> client_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
>>> client_context.options |= ssl.OP_NO_TLSv1
>>> client_context.options |= ssl.OP_NO_TLSv1_1

Созданный выше контекст SSL будет разрешать подключения к серверу только по протоколу TLSv1.2 и более поздним версиям (если это поддерживается вашей системой). PROTOCOL_TLS_CLIENT по умолчанию подразумевает проверку сертификатов и проверки имени хоста. Вам необходимо загрузить сертификаты в контекст.

18.2.9.2.3. Выбор шифров

Если у вас есть расширенные требования к безопасности, то тонкую настройку шифров, используемых при установлении SSL-сессии, можно выполнить с помощью метода SSLContext.set_ciphers(). Начиная с Python 3.2.3, модуль ssl по умолчанию отключает определённые слабые шифры, но вы можете ещё более ограничить выбор шифров. Обязательно ознакомьтесь с документацией OpenSSL по формату списка шифров. Если вы хотите проверить, какие шифры включены в данном списке шифров, воспользуйтесь SSLContext.get_ciphers() или командой openssl ciphers на вашей системе.

18.2.9.3. Многопроцессорность

Если вы используете этот модуль в рамках многопроцессорного приложения (например, используя модули multiprocessing или concurrent.futures), имейте в виду, что внутренний генератор случайных чисел OpenSSL не обрабатывает корректно разветвлённые процессы. Приложения должны изменить состояние PRNG родительского процесса, если они используют какие-либо SSL-функции с os.fork(). Любой успешный вызов RAND_add(), RAND_bytes() или RAND_pseudo_bytes() достаточно.

18.2.10. Поддержка LibreSSL

LibreSSL — это вилка OpenSSL 1.0.1. Модуль ssl имеет ограниченную поддержку LibreSSL. Некоторые функции недоступны, когда модуль ssl скомпилирован с LibreSSL.

  • LibreSSL >= 2.6.1 больше не поддерживает NPN. Методы SSLContext.set_npn_protocols() и SSLSocket.selected_npn_protocol() недоступны.
  • SSLContext.set_default_verify_paths() игнорирует переменные среды SSL_CERT_FILE и SSL_CERT_PATH, хотя get_default_verify_paths() по-прежнему их отображает.

См. также

Class socket.socket

Документация по базовому классу socket

SSL/TLS Strong Encryption: An Introduction

Введение из документации Apache HTTP Server

RFC 1422: Privacy Enhancement for Internet Electronic Mail: Part II: Certificate-Based Key Management

Стив Кент

RFC 4086: Randomness Requirements for Security

Донольд Е., Джеффри Шиллер

RFC 5280: Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile

Д. Купер

RFC 5246: The Transport Layer Security (TLS) Protocol Version 1.2

Т. Диеркс и др.

RFC 6066: Transport Layer Security (TLS) Extensions

Д. Истлейк

IANA TLS: Transport Layer Security (TLS) Parameters

IANA

RFC 7525: Recommendations for Secure Use of Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS)

IETF

Mozilla’s Server Side TLS recommendations

Mozilla

© 2001–2020 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.6/library/ssl.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API