Документация Python неофициальный перевод
Содержание страницы

ssl – обёртка TLS/SSL для сокетовssl – TLS/SSL wrapper for socket objects

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


Этот модуль предоставляет доступ к шифрованию безопасности транспортного уровня (часто называемому «Secure Sockets Layer») и средствам проверки подлинности одноранговых узлов для сетевых сокетов, как на стороне клиента, так и на стороне сервера. Для этого модуль использует библиотеку OpenSSL.

Это опциональный модуль. Если его нет в вашей копии CPython, обратитесь к документации от вашего дистрибьютора (то есть того, кто предоставил вам Python). Если вы дистрибьютор, обратитесь к требованиям к опциональным модулям.

Примечание

Некоторые особенности поведения могут зависеть от платформы, поскольку используются системные API сокетов. Установленная версия OpenSSL также может влиять на поведение. Например, TLSv1.3 доступен в OpenSSL версии 1.1.1.

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

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

Доступность: не WASI.

Этот модуль не работает или недоступен на WebAssembly. Подробнее см. платформы WebAssembly.

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

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

Для более сложных приложений класс 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.

Изменено в версии 3.10: PEP 644 реализован. Модуль ssl требует OpenSSL 1.1.1 или новее.

Использование устаревших констант и функций приводит к предупреждениям об устаревании.

Функции, константы и исключенияFunctions, constants, and exceptions

Создание сокетовSocket creation

Экземпляры SSLSocket должны создаваться с помощью метода SSLContext.wrap_socket(). Вспомогательная функция create_default_context() возвращает новый контекст с безопасными настройками по умолчанию.

Пример клиентского сокета с контекстом по умолчанию и двойным стеком IPv4/IPv6:

import socket
import ssl

hostname = 'www.python.org'
context = ssl.create_default_context()

with socket.create_connection((hostname, 443)) as sock:
    with context.wrap_socket(sock, server_hostname=hostname) as ssock:
        print(ssock.version())

Пример клиентского сокета с пользовательским контекстом и IPv4:

hostname = 'www.python.org'
# PROTOCOL_TLS_CLIENT требует правильной цепочки сертификатов и имени хоста
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
context.load_verify_locations('path/to/cabundle.pem')

with socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) as sock:
    with context.wrap_socket(sock, server_hostname=hostname) as ssock:
        print(ssock.version())

Пример серверного сокета, прослушивающего localhost IPv4:

context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.load_cert_chain('/path/to/certchain.pem', '/path/to/private.key')

with socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) as sock:
    sock.bind(('127.0.0.1', 8443))
    sock.listen(5)
    with context.wrap_socket(sock, server_side=True) as ssock:
        conn, addr = ssock.accept()
        ...

Создание контекстаContext creation

Вспомогательная функция помогает создавать объекты 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_CLIENT или PROTOCOL_TLS_SERVER, OP_NO_SSLv2 и OP_NO_SSLv3 с наборами шифров высокой стойкости без RC4 и без неаутентифицированных наборов шифров. Передача SERVER_AUTH в качестве назначения устанавливает verify_mode в CERT_REQUIRED и либо загружает сертификаты ЦС (если указан хотя бы один из cafile, capath или cadata), либо использует SSLContext.load_default_certs() для загрузки сертификатов ЦС по умолчанию.

Если keylog_filename поддерживается и установлена переменная окружения SSLKEYLOGFILE, create_default_context() включает запись ключей.

Настройки по умолчанию для этого контекста включают VERIFY_X509_PARTIAL_CHAIN и VERIFY_X509_STRICT. Они заставляют базовую реализацию OpenSSL вести себя как реализация, соответствующая RFC 5280, ценой небольшой несовместимости со старыми сертификатами X.509.

Примечание

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

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

Примечание

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

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

Примечание

Этот контекст по умолчанию включает VERIFY_X509_STRICT, что может отклонять сертификаты, выпущенные до RFC 5280, или некорректные сертификаты, которые базовая реализация OpenSSL в противном случае приняла бы. Хотя отключать это не рекомендуется, можно сделать это с помощью:

ctx = ssl.create_default_context()
ctx.verify_flags &= ~ssl.VERIFY_X509_STRICT

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

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

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

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

Изменено в версии 3.8: Добавлена поддержка логирования ключей в SSLKEYLOGFILE.

Изменено в версии 3.10: Контекст теперь использует протокол PROTOCOL_TLS_CLIENT или PROTOCOL_TLS_SERVER вместо общего PROTOCOL_TLS.

Изменено в версии 3.13: Контекст теперь использует VERIFY_X509_PARTIAL_CHAIN и VERIFY_X509_STRICT в своих флагах проверки по умолчанию.

Алгоритмы подписейSignature algorithms

ssl.get_sigalgs()

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

>>> ssl.get_sigalgs()
['ecdsa_secp256r1_sha256', 'ecdsa_secp384r1_sha384', ...]

Эти названия можно использовать при формировании строковых значений для передачи методам SSLContext.set_client_sigalgs() и SSLContext.set_server_sigalgs().

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

Исключения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.SSLCertVerificationError

Подкласс SSLError, возбуждаемый при неудачной проверке сертификата.

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

verify_code

Числовой код ошибки, обозначающий ошибку проверки.

verify_message

Человекочитаемая строка с описанием ошибки проверки.

exception ssl.CertificateError

Псевдоним для SSLCertVerificationError.

Изменено в версии 3.7: Это исключение теперь является псевдонимом для SSLCertVerificationError.

Генерация случайных чиселRandom generation

ssl.RAND_bytes(num, /)

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

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

Прочитайте статью в Википедии Криптостойкий генератор псевдослучайных чисел (CSPRNG), чтобы узнать требования к криптостойкому генератору.

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

ssl.RAND_status()

Возвращает True, если генератор псевдослучайных чисел SSL был инициализирован достаточным количеством случайности, и False в противном случае. Используйте ssl.RAND_add() для увеличения случайности генератора псевдослучайных чисел.

ssl.RAND_add(bytes, entropy, /)

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

Изменено в версии 3.5: Теперь принимается записываемый байтоподобный объект.

Обработка сертификатовCertificate handling

ssl.cert_time_to_seconds(cert_time)

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

Вот пример:

>>> import ssl
>>> import datetime as dt
>>> timestamp = ssl.cert_time_to_seconds("Jan  5 09:34:43 2018 GMT")
>>> timestamp
1515144883
>>> print(dt.datetime.fromtimestamp(timestamp, dt.UTC))
2018-01-05 09:34:43+00:00

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

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

ssl.get_server_certificate(addr, ssl_version=PROTOCOL_TLS_CLIENT, ca_certs=None[, timeout])

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

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

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

Изменено в версии 3.10: Добавлен параметр timeout.

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

Добавлено в версии 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 для данных X.509 ASN.1 или pkcs_7_asn для данных PKCS#7 ASN.1. Параметр trust определяет назначение сертификата в виде набора OID или точно 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)]

Добавлено в версии 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 для данных X.509 ASN.1 или pkcs_7_asn для данных PKCS#7 ASN.1.

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

КонстантыConstants

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

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

ssl.CERT_NONE

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

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

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

ssl.CERT_OPTIONAL

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

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

Использование этого параметра требует передачи допустимого набора сертификатов ЦС в SSLContext.load_verify_locations().

ssl.CERT_REQUIRED

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

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

Использование этого параметра требует передачи допустимого набора сертификатов ЦС в SSLContext.load_verify_locations().

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. В этом режиме проверяется только сертификат однорангового узла, но ни один из промежуточных сертификатов ЦС. Режим требует действительного CRL, подписанного эмитентом сертификата однорангового узла (его прямым вышестоящим ЦС). Если подходящий CRL не был загружен с помощью SSLContext.load_verify_locations, проверка не удастся.

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

ssl.VERIFY_CRL_CHECK_CHAIN

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

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

ssl.VERIFY_X509_STRICT

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

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

ssl.VERIFY_ALLOW_PROXY_CERTS

Возможное значение для SSLContext.verify_flags для включения проверки прокси-сертификатов.

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

ssl.VERIFY_X509_TRUSTED_FIRST

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

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

ssl.VERIFY_X509_PARTIAL_CHAIN

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

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

class ssl.VerifyFlags

enum.IntFlag набор констант VERIFY_*.

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

ssl.PROTOCOL_TLS

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

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

Устарело с версии 3.10: TLS-клиенты и серверы требуют разных настроек по умолчанию для безопасной связи. Общая константа протокола TLS устарела в пользу PROTOCOL_TLS_CLIENT и PROTOCOL_TLS_SERVER.

ssl.PROTOCOL_TLS_CLIENT

Автоматически согласовывает самую высокую версию протокола, поддерживаемую как клиентом, так и сервером, и настраивает контекст для соединений на стороне клиента. Данный протокол по умолчанию включает CERT_REQUIRED и check_hostname.

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

ssl.PROTOCOL_TLS_SERVER

Автоматически согласовывает самую высокую версию протокола, поддерживаемую как клиентом, так и сервером, и настраивает контекст для соединений на стороне сервера.

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

ssl.PROTOCOL_SSLv23

Псевдоним для PROTOCOL_TLS.

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

ssl.PROTOCOL_SSLv3

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

Этот протокол недоступен, если OpenSSL скомпилирован с опцией no-ssl3.

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

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

Устарело с версии 3.6: OpenSSL объявил устаревшими все версионно-зависимые протоколы. Используйте протокол по умолчанию PROTOCOL_TLS_SERVER или PROTOCOL_TLS_CLIENT с SSLContext.minimum_version и SSLContext.maximum_version вместо.

ssl.PROTOCOL_TLSv1

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

Устарело с версии 3.6: OpenSSL объявил устаревшими все версионно-зависимые протоколы.

ssl.PROTOCOL_TLSv1_1

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

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

Устарело с версии 3.6: OpenSSL объявил устаревшими все версионно-зависимые протоколы.

ssl.PROTOCOL_TLSv1_2

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

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

Устарело с версии 3.6: OpenSSL объявил устаревшими все версионно-зависимые протоколы.

ssl.OP_ALL

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

Добавлено в версии 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.

Устарело с версии 3.7: Этот параметр устарел начиная с OpenSSL 1.1.0, используйте новые SSLContext.minimum_version и SSLContext.maximum_version вместо них.

ssl.OP_NO_TLSv1_1

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

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

Устарело с версии 3.7: Этот параметр устарел начиная с OpenSSL 1.1.0.

ssl.OP_NO_TLSv1_2

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

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

Устарело с версии 3.7: Этот параметр устарел начиная с OpenSSL 1.1.0.

ssl.OP_NO_TLSv1_3

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

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

Устарело с версии 3.7: Этот параметр устарел начиная с OpenSSL 1.1.0. Он был добавлен в версии 2.7.15 и 3.6.3 для обратной совместимости с OpenSSL 1.0.2.

ssl.OP_NO_RENEGOTIATION

Отключает любое пересогласование в TLSv1.2 и более ранних версиях. Не отправляет сообщения HelloRequest и игнорирует запросы на пересогласование через ClientHello.

Этот параметр доступен только в OpenSSL 1.1.0h и выше.

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

ssl.OP_CIPHER_SERVER_PREFERENCE

Использовать порядок шифров, заданный на сервере, а не на клиенте. Этот параметр не влияет на клиентские сокеты и сокеты сервера SSLv2.

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

ssl.OP_SINGLE_DH_USE

Предотвращает повторное использование одного и того же DH-ключа для разных SSL-сеансов. Это улучшает прямую секретность (forward secrecy), но требует больше вычислительных ресурсов. Этот параметр применяется только к серверным сокетам.

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

ssl.OP_SINGLE_ECDH_USE

Предотвращает повторное использование одного и того же ECDH-ключа для разных SSL-сеансов. Это улучшает прямую секретность (forward secrecy), но требует больше вычислительных ресурсов. Этот параметр применяется только к серверным сокетам.

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

ssl.OP_ENABLE_MIDDLEBOX_COMPAT

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

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

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

ssl.OP_NO_COMPRESSION

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

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

class ssl.Options

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

ssl.OP_NO_TICKET

Предотвращает запрос сессионного билета со стороны клиента.

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

ssl.OP_IGNORE_UNEXPECTED_EOF

Игнорирует неожиданное завершение TLS-соединений.

Эта опция доступна только в OpenSSL 3.0.0 и новее.

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

ssl.OP_ENABLE_KTLS

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

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

Эта опция доступна только в OpenSSL 3.0.0 и новее.

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

ssl.OP_LEGACY_SERVER_CONNECT

Разрешает устаревшее небезопасное пересогласование между OpenSSL и незапатченными серверами только.

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

ssl.HAS_ALPN

Указывает, имеет ли библиотека OpenSSL встроенную поддержку расширения TLS Согласование протокола прикладного уровня, как описано в RFC 7301.

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

ssl.HAS_NEVER_CHECK_COMMON_NAME

Указывает, имеет ли библиотека OpenSSL встроенную поддержку отключения проверки общего имени субъекта и SSLContext.hostname_checks_common_name является доступным для записи.

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

ssl.HAS_ECDH

Указывает, имеет ли библиотека OpenSSL встроенную поддержку обмена ключами Диффи-Хеллмана на основе эллиптических кривых. Это должно быть истиной (true), если только эта возможность не была явно отключена распространителем.

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

ssl.HAS_SNI

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

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

ssl.HAS_NPN

Указывает, имеет ли библиотека OpenSSL встроенную поддержку Согласования следующего протокола, как описано в Согласовании протокола прикладного уровня. Если истина (true), вы можете использовать метод SSLContext.set_npn_protocols() для объявления поддерживаемых протоколов.

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

ssl.HAS_SSLv2

Указывает, имеет ли библиотека OpenSSL встроенную поддержку протокола SSL 2.0.

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

ssl.HAS_SSLv3

Указывает, имеет ли библиотека OpenSSL встроенную поддержку протокола SSL 3.0.

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

ssl.HAS_TLSv1

Указывает, имеет ли библиотека OpenSSL встроенную поддержку протокола TLS 1.0.

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

ssl.HAS_TLSv1_1

Указывает, имеет ли библиотека OpenSSL встроенную поддержку протокола TLS 1.1.

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

ssl.HAS_TLSv1_2

Указывает, имеет ли библиотека OpenSSL встроенную поддержку протокола TLS 1.2.

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

ssl.HAS_TLSv1_3

Определяет, поддерживает ли библиотека OpenSSL протокол TLS 1.3 на встроенном уровне.

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

ssl.HAS_PSK

Определяет, поддерживает ли библиотека OpenSSL TLS-PSK встроенными средствами.

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

ssl.HAS_PSK_TLS13

Поддерживает ли библиотека OpenSSL встроенную поддержку внешних PSK в TLS 1.3, как описано в RFC 9258.

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

ssl.HAS_PHA

Определяет, поддерживает ли библиотека OpenSSL TLS-PHA встроенными средствами.

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

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.

class ssl.TLSVersion

enum.IntEnum набор версий SSL и TLS для SSLContext.maximum_version и SSLContext.minimum_version.

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

TLSVersion.MINIMUM_SUPPORTED
TLSVersion.MAXIMUM_SUPPORTED

Минимальная или максимальная поддерживаемая версия SSL или TLS. Это магические константы. Их значения не соответствуют наименьшей и наибольшей доступным версиям TLS/SSL.

TLSVersion.SSLv3
TLSVersion.TLSv1
TLSVersion.TLSv1_1
TLSVersion.TLSv1_2
TLSVersion.TLSv1_3

от SSL 3.0 до TLS 1.3.

Устарело с версии 3.10: Все члены TLSVersion, кроме TLSVersion.TLSv1_2 и TLSVersion.TLSv1_3, устарели.

SSL-сокетыSSL sockets

class ssl.SSLSocket(socket.socket)

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

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

Экземпляры SSLSocket должны создаваться с помощью метода SSLContext.wrap_socket().

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

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

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

Изменено в версии 3.7: Экземпляры SSLSocket должны создаваться с помощью wrap_socket(). В более ранних версиях можно было создавать экземпляры напрямую. Это никогда не документировалось и официально не поддерживалось.

Изменено в версии 3.10: Python теперь использует SSL_read_ex и SSL_write_ex внутренне. Функции поддерживают чтение и запись данных размером более 2 ГБ. Запись данных нулевой длины больше не вызывает ошибку нарушения протокола.

Changed in version 3.15: Python now uses SSL_sendfile internally when possible. The function sends a file more efficiently because it performs TLS encryption in the kernel to avoid additional context switches.

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

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

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

Возбуждает SSLWantReadError или SSLWantWriteError, если сокет является неблокирующим и чтение заблокируется.

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

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

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

SSLSocket.write(data)

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

Возбуждает SSLWantReadError или SSLWantWriteError, если сокет является неблокирующим и запись заблокируется.

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

Изменено в версии 3.5: Тайм-аут сокета больше не сбрасывается каждый раз при получении или отправке байт. Теперь тайм-аут сокета – это максимальная общая продолжительность записи data.

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

Примечание

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

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

SSLSocket.do_handshake(block=False)

Выполняет рукопожатие для настройки SSL.

Если block равен true, а тайм-аут, полученный с помощью gettimeout(), равен нулю, сокет переводится в блокирующий режим до выполнения рукопожатия.

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

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

Изменено в версии 3.7: Имя хоста или IP-адрес теперь сопоставляется OpenSSL во время рукопожатия. Функция match_hostname() больше не используется. Если OpenSSL отклоняет имя хоста или IP-адрес, рукопожатие прерывается досрочно, и одноранговому узлу отправляется сообщение TLS-оповещения.

SSLSocket.getpeercert(binary_form=False)

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

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

Поля 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}

Если параметр binary_form равен True и сертификат был предоставлен, этот метод возвращает DER-кодированную форму всего сертификата в виде последовательности байтов или None, если одноранговый узел не предоставил сертификат. Предоставляет ли одноранговый узел сертификат, зависит от роли SSL-сокета:

  • для клиентского SSL-сокета сервер всегда предоставляет сертификат, независимо от того, требовалась ли проверка;

  • для серверного SSL-сокета клиент предоставляет сертификат только по запросу сервера; поэтому getpeercert() вернет None, если использовался CERT_NONE (а не CERT_OPTIONAL или CERT_REQUIRED).

См. также SSLContext.check_hostname.

Изменено в версии 3.2: Возвращаемый словарь включает дополнительные элементы, такие как issuer и notBefore.

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

Изменено в версии 3.9: Строки IPv6-адресов больше не содержат завершающего перевода строки.

SSLSocket.get_verified_chain()

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

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

SSLSocket.get_unverified_chain()

Возвращает необработанную цепочку сертификатов, предоставленную другим концом SSL-канала, в виде списка байтов в DER-кодировке.

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

SSLSocket.cipher()

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

SSLSocket.shared_ciphers()

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

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

SSLSocket.group()

Возвращает группу, используемую для согласования ключей на этом соединении. Если соединение не установлено, возвращает None.

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

SSLSocket.client_sigalg()

Возвращает алгоритм подписи, используемый для аутентификации клиента на основе сертификата на этом соединении, или None, если соединение не было установлено или аутентификация клиента не выполнялась.

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

SSLSocket.server_sigalg()

Возвращает алгоритм подписи, используемый сервером для завершения рукопожатия TLS на этом соединении, или None, если соединение не установлено или набор шифров не имеет подписи.

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

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.

Устарело с версии 3.10: NPN заменён на ALPN

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.

Примечание

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

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

SSLSocket.version()

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

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

SSLSocket.pending()

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

SSLSocket.context

Объект SSLContext, к которому привязан этот SSL-сокет.

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

SSLSocket.server_side

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

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

SSLSocket.server_hostname

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

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

Изменено в версии 3.7: Атрибут теперь всегда является текстом ASCII. Если server_hostname является интернационализированным доменным именем (IDN), этот атрибут теперь хранит форму A-label ("xn--pythn-mua.org"), а не форму U-label ("pythön.org").

SSLSocket.session

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

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

SSLSocket.session_reused

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

Контексты SSLSSL contexts

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

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

class ssl.SSLContext(protocol=None)

Создаёт новый контекст SSL. Можно передать протокол, который должен быть одной из констант PROTOCOL_*, определённых в этом модуле. Параметр указывает, какую версию протокола 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

нет

нет

да

нет

нет

да

Сноски

См. также

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

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

Устарело с версии 3.10: Вызов SSLContext без аргумента protocol устарел. В будущем класс контекста будет требовать протокол PROTOCOL_TLS_CLIENT или PROTOCOL_TLS_SERVER.

Изменено в версии 3.10: Наборы шифров по умолчанию теперь включают только безопасные шифры AES и ChaCha20 с прямой секретностью и уровнем безопасности 2. Ключи RSA и DH с длиной менее 2048 бит и ключи ECC с длиной менее 224 бит запрещены. PROTOCOL_TLS, PROTOCOL_TLS_CLIENT и PROTOCOL_TLS_SERVER используют TLS 1.2 как минимальную версию TLS.

Примечание

SSLContext поддерживает только ограниченную модификацию после того, как был использован соединением. Добавление новых сертификатов во внутреннее хранилище доверенных сертификатов разрешено, но изменение шифров, параметров проверки или сертификатов mTLS может привести к неожиданному поведению.

Примечание

SSLContext предназначен для совместного использования несколькими соединениями. Таким образом, он потокобезопасен, если не перенастраивается после того, как был использован соединением.

Объекты 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 может быть функцией, вызываемой для получения пароля для расшифровки закрытого ключа. Она будет вызвана только в том случае, если закрытый ключ зашифрован и требуется пароль. Она будет вызвана без аргументов, и должна возвращать строку, bytes или bytearray. Если возвращаемое значение – строка, она будет закодирована в UTF-8 перед использованием для расшифровки ключа. В качестве альтернативы, строка, bytes или bytearray могут быть переданы напрямую в качестве аргумента 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)

Возвращает список загруженных сертификатов “certification authority” (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()
[{'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'}]

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

SSLContext.get_groups(*, include_aliases=False)

Возвращает список групп, реализованных для согласования ключей, с учётом текущих значений minimum_version и maximum_version. Например:

>>> ctx = ssl.create_default_context()
>>> ctx.minimum_version = ssl.TLSVersion.TLSv1_3
>>> ctx.maximum_version = ssl.TLSVersion.TLSv1_3
>>> ctx.get_groups()
['secp256r1', 'secp384r1', 'secp521r1', 'x25519', 'x448', ...]

По умолчанию этот метод возвращает только предпочтительные имена IANA для доступных групп. Однако если параметр include_aliases установлен в True, метод также вернёт все связанные псевдонимы, такие как имена кривых ECDH, поддерживаемые в старых версиях OpenSSL.

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

SSLContext.set_default_verify_paths()

Загружает набор сертификатов по умолчанию “certification authority” (CA) из пути файловой системы, заданного при сборке библиотеки OpenSSL. К сожалению, нет простого способа узнать, успешно ли выполняется этот метод: ошибка не возвращается, если сертификаты не найдены. Однако, если библиотека OpenSSL поставляется как часть операционной системы, она, скорее всего, настроена правильно.

SSLContext.set_ciphers(ciphers, /)

Устанавливает разрешённые шифры для сокетов, создаваемых с этим контекстом при подключении с использованием TLS 1.2 и более ранних версий. Аргумент ciphers должен быть строкой в формате списка шифров OpenSSL. Чтобы задать разрешённые шифры TLS 1.3, используйте SSLContext.set_ciphersuites().

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

Примечание

После подключения метод SSLSocket.cipher() SSL-сокетов вернёт сведения о согласованном шифре.

SSLContext.set_ciphersuites(ciphersuites, /)

Устанавливает разрешённые шифры для сокетов, создаваемых с этим контекстом при подключении с использованием TLS 1.3. Аргумент ciphersuites должен быть строкой, разделённой двоеточиями, с именами шифров TLS 1.3. Если ни один шифр не может быть выбран (например, из-за параметров сборки или другой конфигурации, запрещающей использование всех указанных шифров), будет вызвано исключение SSLError.

Примечание

После подключения метод SSLSocket.cipher() SSL-сокетов вернёт сведения о согласованном шифре.

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

SSLContext.set_groups(groups, /)

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

Примечание

После подключения метод SSLSocket.group() SSL-сокетов вернёт группу, используемую для согласования ключей на этом соединении.

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

SSLContext.set_client_sigalgs(sigalgs, /)

Устанавливает алгоритмы подписи, разрешённые для аутентификации клиента на основе сертификата. Это должна быть строка в формате списка сигнатурных алгоритмов клиента OpenSSL.

Примечание

После подключения метод SSLSocket.client_sigalg() SSL-сокетов вернёт алгоритм подписи, используемый для аутентификации клиента на основе сертификата на этом соединении.

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

SSLContext.set_server_sigalgs(sigalgs, /)

Устанавливает алгоритмы подписи, разрешённые для завершения сервером TLS-рукопожатия. Это должна быть строка в формате списка сигнатурных алгоритмов OpenSSL.

Примечание

При подключении метод SSLSocket.server_sigalg() SSL-сокетов возвращает алгоритм подписи, который сервер использовал для завершения TLS-рукопожатия на этом соединении.

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

SSLContext.set_alpn_protocols(alpn_protocols)

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

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

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

SSLContext.set_npn_protocols(npn_protocols)

Определяет, какие протоколы сокет должен объявлять во время рукопожатия SSL/TLS. Это должен быть список строк, например ['http/1.1', 'spdy/2'], упорядоченный по предпочтению. Выбор протокола происходит во время рукопожатия и выполняется в соответствии с Согласованием протокола прикладного уровня (Application Layer Protocol Negotiation). После успешного рукопожатия метод SSLSocket.selected_npn_protocol() вернёт согласованный протокол.

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

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

Устарело с версии 3.10: NPN заменён на ALPN

SSLContext.sni_callback

Регистрирует функцию обратного вызова, которая будет вызвана после получения сервером SSL/TLS сообщения TLS Client Hello, когда клиент TLS указывает индикацию имени сервера. Механизм индикации имени сервера описан в RFC 6066 раздел 3 – Server Name Indication.

Для каждого SSLContext можно установить только один колбэк. Если sni_callback установлено в None, колбэк отключается. Повторный вызов этой функции отключит ранее зарегистрированный колбэк.

Функция обратного вызова будет вызвана с тремя аргументами: первый – ssl.SSLSocket, второй – строка, представляющая имя сервера, с которым клиент намерен установить соединение (или None, если TLS Client Hello не содержит имя сервера), и третий аргумент – исходный SSLContext. Аргумент имени сервера является текстовым. Для интернационализированных доменных имён имя сервера представляет собой IDN A-метку ("xn--pythn-mua.org").

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

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

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

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

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

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

SSLContext.set_servername_callback(server_name_callback)

Это устаревший API, сохранённый для обратной совместимости. По возможности следует использовать sni_callback. Заданный server_name_callback похож на sni_callback, за исключением того, что когда имя хоста сервера является интернационализированным доменным именем в кодировке IDN, server_name_callback получает декодированную U-метку ("pythön.org").

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

Добавлено в версии 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.

SSLContext.wrap_socket(sock, server_side=False, do_handshake_on_connect=True, suppress_ragged_eofs=True, server_hostname=None, session=None)

Оборачивает существующий сокет Python sock и возвращает экземпляр SSLContext.sslsocket_class (по умолчанию SSLSocket). Возвращаемый SSL-сокет привязан к контексту, его настройкам и сертификатам. sock должен быть сокетом SOCK_STREAM; другие типы сокетов не поддерживаются.

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

Для клиентских сокетов построение контекста выполняется лениво; если базовый сокет ещё не подключён, построение контекста будет выполнено после вызова connect() на сокете. Для серверных сокетов, если у сокета нет удалённого узла, считается, что это слушающий сокет, и SSL-обёртка на стороне сервера автоматически выполняется для клиентских подключений, принятых через метод accept(). Метод может возбудить исключение SSLError.

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

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

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

session, см. session.

Чтобы обернуть SSLSocket в другой SSLSocket, используйте SSLContext.wrap_bio().

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

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

Изменено в версии 3.7: Метод возвращает экземпляр SSLContext.sslsocket_class вместо жёстко заданного SSLSocket.

SSLContext.sslsocket_class

Возвращаемый тип SSLContext.wrap_socket(), по умолчанию SSLSocket. Этому атрибуту можно присвоить значение на экземплярах SSLContext, чтобы возвращать пользовательский подкласс SSLSocket.

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

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

Оборачивает объекты BIO incoming и outgoing и возвращает экземпляр SSLContext.sslobject_class (по умолчанию SSLObject). Процедуры SSL будут читать входные данные из входящего BIO и записывать данные в исходящий BIO.

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

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

Изменено в версии 3.7: Метод возвращает экземпляр SSLContext.sslobject_class вместо жёстко заданного SSLObject.

SSLContext.sslobject_class

Возвращаемый тип SSLContext.wrap_bio(), по умолчанию SSLObject. Атрибут можно переопределить на экземпляре класса, чтобы возвращать пользовательский подкласс SSLObject.

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

SSLContext.session_stats()

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

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

Определяет, нужно ли проверять hostname в сертификате однорангового узла в SSLSocket.do_handshake(). Атрибут verify_mode контекста должен быть установлен в CERT_OPTIONAL или CERT_REQUIRED, а для проверки hostname необходимо передать server_hostname в wrap_socket(). Включение проверки hostname автоматически меняет verify_mode с CERT_NONE на CERT_REQUIRED. Его нельзя вернуть обратно на CERT_NONE, пока проверка hostname включена. Протокол PROTOCOL_TLS_CLIENT включает проверку hostname по умолчанию. Для остальных протоколов проверку hostname нужно включать явно.

Пример:

import socket, ssl

context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
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.

Изменено в версии 3.7: verify_mode теперь автоматически меняется на CERT_REQUIRED, когда включена проверка hostname, а verify_mode равен CERT_NONE. Раньше та же операция завершилась бы с ошибкой ValueError.

SSLContext.keylog_filename

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

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

SSLContext.maximum_version

Элемент перечисления TLSVersion, представляющий самую высокую поддерживаемую версию TLS. Значение по умолчанию – TLSVersion.MAXIMUM_SUPPORTED. Атрибут доступен только для чтения для протоколов, отличных от PROTOCOL_TLS, PROTOCOL_TLS_CLIENT и PROTOCOL_TLS_SERVER.

Атрибуты maximum_version, minimum_version и SSLContext.options влияют на поддерживаемые версии SSL и TLS контекста. Реализация не предотвращает недопустимые комбинации. Например, контекст с OP_NO_TLSv1_2 в options и maximum_version, установленным в TLSVersion.TLSv1_2, не сможет установить соединение TLS 1.2.

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

SSLContext.minimum_version

Аналогично SSLContext.maximum_version, но задаёт самую низкую поддерживаемую версию или TLSVersion.MINIMUM_SUPPORTED.

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

SSLContext.num_tickets

Управляет количеством сессионных билетов TLS 1.3 для контекста PROTOCOL_TLS_SERVER. Настройка не влияет на соединения TLS 1.0–1.2.

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

SSLContext.options

Целое число, представляющее набор опций SSL, включённых в этом контексте. Значение по умолчанию – OP_ALL, но можно указать другие опции, например OP_NO_SSLv2, комбинируя их с помощью OR.

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

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

Устарело с версии 3.7: Все опции OP_NO_SSL* и OP_NO_TLS* устарели начиная с Python 3.7. Используйте вместо них SSLContext.minimum_version и SSLContext.maximum_version.

SSLContext.post_handshake_auth

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

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

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

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

SSLContext.protocol

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

SSLContext.hostname_checks_common_name

Определяет, будет ли check_hostname проверять общее имя (common name) субъекта сертификата при отсутствии расширения subject alternative name (по умолчанию: true).

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

Изменено в версии 3.10: Этот флаг не действовал в OpenSSL версий ниже 1.1.1l. Python 3.8.9, 3.9.3 и 3.10 содержат обходные пути для предыдущих версий.

SSLContext.security_level

Целое число, представляющее уровень безопасности для контекста. Этот атрибут доступен только для чтения.

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

SSLContext.verify_flags

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

Добавлено в версии 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>
SSLContext.set_psk_client_callback(callback)

Включает аутентификацию TLS-PSK (предварительный общий ключ) на стороне клиента.

В целом аутентификация на основе сертификатов предпочтительнее этого метода.

The parameter callback is a callable object with the signature: def callback(hint: str | None) -> tuple[str | None, bytes]. The hint parameter is an optional identity hint sent by the server. The return value is a tuple in the form (client-identity, psk). Client-identity is an optional string which may be used by the server to select a corresponding PSK for the client. The string must be less than or equal to 256 octets when UTF-8 encoded. PSK is a bytes-like object representing the pre-shared key. Return a zero length PSK to reject the connection.

Установка callback в None удаляет существующий колбэк.

Примечание

При использовании TLS 1.3:

  • параметр hint всегда равен None.

  • client-identity должна быть непустой строкой.

Пример использования:

context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
context.maximum_version = ssl.TLSVersion.TLSv1_2
context.set_ciphers('PSK')

# Простая лямбда:
psk = bytes.fromhex('c0ffee')
context.set_psk_client_callback(lambda hint: (None, psk))

# Таблица с использованием подсказки от сервера:
psk_table = { 'ServerId_1': bytes.fromhex('c0ffee'),
              'ServerId_2': bytes.fromhex('facade')
}
def callback(hint):
    return 'ClientId_1', psk_table.get(hint, b'')
context.set_psk_client_callback(callback)

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

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

SSLContext.set_psk_server_callback(callback, identity_hint=None)

Включает аутентификацию TLS-PSK (предварительный общий ключ) на стороне сервера.

В целом аутентификация на основе сертификатов предпочтительнее этого метода.

The parameter callback is a callable object with the signature: def callback(identity: str | None) -> bytes. The identity parameter is an optional identity sent by the client which can be used to select a corresponding PSK. The return value is a bytes-like object representing the pre-shared key. Return a zero length PSK to reject the connection.

Установка callback в None удаляет существующий колбэк.

Параметр identity_hint – необязательная строка подсказки идентификатора, отправляемая клиенту. Строка должна быть не длиннее 256 октетов при кодировке UTF-8.

Примечание

При использовании TLS 1.3 параметр identity_hint не отправляется клиенту.

Пример использования:

context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.maximum_version = ssl.TLSVersion.TLSv1_2
context.set_ciphers('PSK')

# Простая лямбда:
psk = bytes.fromhex('c0ffee')
context.set_psk_server_callback(lambda identity: psk)

# Таблица с использованием идентификатора клиента:
psk_table = { 'ClientId_1': bytes.fromhex('c0ffee'),
              'ClientId_2': bytes.fromhex('facade')
}
def callback(identity):
    return psk_table.get(identity, b'')
context.set_psk_server_callback(callback, 'ServerId_1')

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

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

Сертификаты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-----

Цепочки сертификатов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-----

Сертификаты УЦCA certificates

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

Объединённый ключ и сертификатCombined key and certificate

Часто закрытый ключ хранится в том же файле, что и сертификат; в этом случае достаточно передать только параметр certfile для SSLContext.load_cert_chain(). Если закрытый ключ хранится вместе с сертификатом, он должен располагаться перед первым сертификатом в цепочке сертификатов:

-----BEGIN RSA PRIVATE KEY-----
... (private key in base64 encoding) ...
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
... (certificate in base64 PEM encoding) ...
-----END CERTIFICATE-----

Самоподписанные сертификаты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
%

Недостаток самоподписанного сертификата в том, что он является собственным корневым сертификатом, и никто другой не будет иметь его в своём кэше известных (и доверенных) корневых сертификатов.

ПримерыExamples

Проверка поддержки SSLTesting for SSL support

Чтобы проверить наличие поддержки SSL в установке Python, в пользовательском коде следует использовать следующую идиому:

try:
    import ssl
except ImportError:
    pass
else:
    ...  # сделать что-то, что требует поддержки SSL

Операции на стороне клиентаClient-side operation

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

>>> context = ssl.create_default_context()

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

>>> context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
>>> context.load_verify_locations("/etc/ssl/certs/ca-bundle.crt")

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

Протокол PROTOCOL_TLS_CLIENT настраивает контекст для проверки сертификатов и проверки имени хоста. verify_mode установлен в CERT_REQUIRED, а check_hostname установлен в True. Все остальные протоколы создают контексты SSL с небезопасными настройками по умолчанию.

При использовании контекста для подключения к серверу CERT_REQUIRED и check_hostname проверяют сертификат сервера: они гарантируют, что сертификат сервера был подписан одним из сертификатов ЦС, проверяют корректность подписи, а также проверяют другие свойства, такие как срок действия и идентификация имени хоста:

>>> 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'']

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

Операции на стороне сервераServer-side operation

Для работы на стороне сервера обычно нужно иметь сертификат сервера и закрытый ключ, каждый в отдельном файле. Сначала создаётся контекст, содержащий ключ и сертификат, чтобы клиенты могли проверить подлинность. Затем открывается сокет, привязывается к порту, вызывается 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.example.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)
    # закончили с клиентом

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

Примечания о неблокирующих сокетахNotes on non-blocking sockets

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 асинхронно.

Поддержка Memory BIOMemory BIO support

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

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

  • Обработка протокола SSL

  • Сетевой ввод-вывод

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

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

class ssl.SSLObject

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

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

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

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

По сравнению с 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.

Изменено в версии 3.7: экземпляры SSLObject должны создаваться с помощью wrap_bio(). В более ранних версиях можно было создавать экземпляры напрямую. Это никогда не было документировано или официально поддерживалось.

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

class ssl.MemoryBIO

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

pending

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

eof

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

read(n=-1, /)

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

write(buf, /)

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

Возвращаемое значение – количество записанных байтов, которое всегда равно длине buf.

write_eof()

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

SSL-сеанс SSL session

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

class ssl.SSLSession

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

id
time
timeout
ticket_lifetime_hint
has_ticket

Соображения безопасностиSecurity considerations

Рекомендуемые настройки по умолчаниюBest defaults

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

Например, вот как можно использовать класс 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 самостоятельно, в нём по умолчанию не будут включены ни проверка сертификатов, ни проверка имени хоста. В этом случае следует прочитать приведённые ниже абзацы, чтобы достичь хорошего уровня безопасности.

Ручная настройкаManual settings

Проверка сертификатовVerifying certificates

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

Изменено в версии 3.7: Сопоставление имён хостов теперь выполняется библиотекой OpenSSL. Python больше не использует match_hostname().

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

Версии протоколовProtocol versions

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

>>> client_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
>>> client_context.minimum_version = ssl.TLSVersion.TLSv1_2
>>> client_context.maximum_version = ssl.TLSVersion.TLSv1_3

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

Выбор шифровCipher selection

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

Многопроцессная работаMulti-processing

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

TLS 1.3

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

Протокол TLS 1.3 ведёт себя несколько иначе, чем предыдущие версии TLS/SSL. Некоторые новые возможности TLS 1.3 пока недоступны.

  • TLS 1.3 использует непересекающийся набор шифров. Все наборы шифров AES-GCM и ChaCha20 включены по умолчанию. Чтобы ограничить, какие шифры TLS 1.3 разрешены, следует вызывать метод SSLContext.set_ciphersuites() вместо SSLContext.set_ciphers(), который влияет только на шифры в старых версиях TLS. Метод SSLContext.get_ciphers() возвращает информацию о шифрах как для TLS 1.3, так и для более ранних версий, а метод SSLSocket.cipher() возвращает информацию о согласованном шифре как для TLS 1.3, так и для более ранних версий после установки соединения.

  • Сессионные билеты больше не отправляются в составе исходного рукопожатия и обрабатываются иначе. SSLSocket.session и SSLSession несовместимы с TLS 1.3.

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

  • Функции TLS 1.3, такие как early data, отложенный запрос сертификата клиента TLS и смена ключей, пока не поддерживаются.

См. также

Класс socket.socket

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

SSL/TLS: надёжное шифрование. Введение

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

RFC 1422: Улучшение конфиденциальности для электронной почты в Интернете: Часть II: Управление ключами на основе сертификатов

Steve Kent

RFC 4086: Требования к случайности для обеспечения безопасности

Donald E. Eastlake, Jeffrey I. Schiller, Steve Crocker

RFC 5280: Профиль инфраструктуры открытых ключей X.509 Интернета: сертификаты и списки отзыва сертификатов (CRL)

David Cooper et al.

RFC 5246: Протокол безопасности транспортного уровня (TLS) версии 1.2

Tim Dierks and Eric Rescorla.

RFC 6066: Расширения безопасности транспортного уровня (TLS)

Donald E. Eastlake

IANA TLS: Параметры безопасности транспортного уровня (TLS)

IANA

RFC 7525: Рекомендации по безопасному использованию безопасности транспортного уровня (TLS) и безопасности дейтаграммного транспортного уровня (DTLS)

IETF

Рекомендации Mozilla по TLS на стороне сервера

Mozilla