Перейти к содержимому

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

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


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

This is an optional module. If it is missing from your copy of CPython, look for documentation from your distributor (that is, whoever provided Python to you). If you are the distributor, see Requirements for optional modules.

Примечание

Некоторое поведение может зависеть от платформы, поскольку вызовы производятся к сетевым 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:

python
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:

python
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:

python
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, вы можете снова включить их, используя:

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

Примечание

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

python
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 или клиентами, запрашивающими аутентификацию на основе сертификатов. Например:

python
>>> 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, если ГПСЧ не был инициализирован достаточным количеством энтропии или если операция не поддерживается текущим методом RAND. RAND_status() можно использовать для проверки состояния ГПСЧ, а RAND_add() – для его инициализации.

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

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

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

ssl.RAND_status()

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

ssl.RAND_add(bytes, entropy, /)

Mix the given bytes into the SSL pseudo-random number generator. The parameter entropy (a float) is a lower bound on the entropy contained in string (so you can always use 0.0). See RFC 1750 for more information on sources of entropy.

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

Certificate handlingРабота с сертификатами

ssl.cert_time_to_seconds(cert_time)

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

Пример:

python
>>> 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” dates must use GMT (RFC 5280).

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

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

По адресу addr SSL-защищённого сервера, заданному парой (hostname, port-number), извлекает сертификат сервера и возвращает его в виде строки в формате 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()

Returns a named tuple with paths to OpenSSL’s default cafile and capath. The paths are the same as used by SSLContext.set_default_verify_paths(). The return value is a named tuple 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, если сертификат является доверенным для всех целей.

Пример:

python
>>> 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-сессий. Это улучшает прямую секретность, но требует больше вычислительных ресурсов. Этот параметр применим только к серверным сокетам.

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

ssl.OP_SINGLE_ECDH_USE

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

Добавлено в версии 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 встроенную поддержку для пропуска проверки общего имени субъекта (common name), и SSLContext.hostname_checks_common_name доступен для записи.

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

ssl.HAS_ECDH

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

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

ssl.HAS_SNI

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

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

ssl.HAS_NPN

Указывает, имеет ли библиотека OpenSSL встроенную поддержку Согласование следующего протокола, описанного в Согласование протокола прикладного уровня. При истинном значении с помощью метода 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, загруженной интерпретатором:

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

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

ssl.OPENSSL_VERSION_INFO

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

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

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

ssl.OPENSSL_VERSION_NUMBER

Сырой номер версии библиотеки OpenSSL в виде одного целого числа:

python
>>> 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 TLS Alert Registry содержит этот список и ссылки на 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 socketsSSL сокеты

class ssl.SSLSocket(socket.socket)

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

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

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

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

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

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

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

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

Изменено в версии 3.15: Python теперь использует SSL_sendfile внутри, когда это возможно. Функция отправляет файл более эффективно, поскольку выполняет шифрование TLS в ядре, чтобы избежать дополнительных переключений контекста.

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

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

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

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

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

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

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

SSLSocket.write(data)

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

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

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

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

Устарело с версии 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 alert.

SSLSocket.getpeercert(binary_form=False)

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

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

Поля subject и issuer представляют собой кортежи, содержащие последовательность относительных отличительных имен (RDN) в структуре данных сертификата для соответствующих полей, и каждый RDN представляет собой последовательность пар имя-значение. Вот пример из реального мира:

python
{'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, если соединение не установлено или рукопожатие не завершено.

The cb_type parameter allow selection of the desired channel binding type. Valid channel binding types are listed in the CHANNEL_BINDING_TYPES list. Currently only the ‘tls-unique’ channel binding, defined by RFC 5929, is supported. ValueError will be raised if an unsupported channel binding type is requested.

Добавлено в версии 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-форму ("xn--pythn-mua.org"), а не U-форму ("pythön.org").

SSLSocket.session

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

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

SSLSocket.session_reused

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

SSL contextsSSL-контексты

Добавлено в версии 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_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-сертификатом и одним обычным сертификатом:

python
>>> 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, см. в обсуждении Certificates.

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

Если аргумент 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. Дополнительную информацию о том, как организовать сертификаты в этом файле, см. в обсуждении Certificates.

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

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

Изменено в версии 3.4: Новый опциональный аргумент cadata.

SSLContext.get_ca_certs(binary_form=False)

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

Примечание

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

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

SSLContext.get_ciphers()

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

Пример:

python
>>> 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 TLS. Например:

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

Загружает набор сертификатов по умолчанию «центра сертификации» (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'], упорядоченный по предпочтению. Выбор протокола произойдет во время рукопожатия в соответствии с согласованием протокола прикладного уровня (ALPN). После успешного рукопожатия метод 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-label ("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-соединение будет завершено с отправкой клиенту фатального предупреждения 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() на сокете. Для сокетов на стороне сервера, если у сокета нет удалённого peer, он считается слушающим сокетом, и серверная 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-сессиям, созданным или управляемым этим контекстом. Возвращается словарь, который сопоставляет названия каждого элемента информации с их числовыми значениями. Например, вот общее количество попаданий и промахов в кеше сессий с момента создания контекста:

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

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

Пример:

python
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, когда проверка имени хоста включена и 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:

text
>>> 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. Аутентификация после рукопожатия по умолчанию отключена, и сервер может запрашивать сертификат клиента только во время начального рукопожатия. При включении сервер может запросить сертификат клиента в любое время после рукопожатия.

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

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

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

SSLContext.protocol

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

SSLContext.hostname_checks_common_name

Определяет, выполняет ли check_hostname проверку общего имени субъекта сертификата при отсутствии расширения 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, можно устанавливать, комбинируя их с помощью логического ИЛИ. По умолчанию OpenSSL не требует и не проверяет списки отзыва сертификатов (CRL).

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

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

text
>>> 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 перечисление:

text
>>> ssl.create_default_context().verify_mode
<VerifyMode.CERT_REQUIRED: 2>
SSLContext.set_psk_client_callback(callback)

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

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

Параметр callback – это вызываемый объект с сигнатурой def callback(hint: str | None) -> tuple[str | None, bytes]. Параметр hint – необязательная подсказка об идентификаторе, отправляемая сервером. Возвращаемое значение – кортеж вида (client-identity, psk). client-identity – необязательная строка, которая может использоваться сервером для выбора соответствующего PSK для клиента. Строка должна быть не длиннее 256 октетов в кодировке UTF-8. PSK – это байтоподобный объект, представляющий предварительно согласованный ключ. Для отклонения соединения верните PSK нулевой длины.

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

Примечание

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

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

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

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

python
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 (предварительно согласованный ключ) на стороне сервера.

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

Параметр callback – это вызываемый объект с сигнатурой def callback(identity: str | None) -> bytes. Параметр identity – необязательный идентификатор, отправляемый клиентом, который может использоваться для выбора соответствующего PSK. Возвращаемое значение – байтоподобный объект, представляющий предварительно согласованный ключ. Для отклонения соединения верните PSK нулевой длины.

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

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

Примечание

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

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

python
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 использует файлы для хранения сертификатов. Они должны быть отформатированы как “PEM” (см. RFC 1422), что представляет собой форму кодирования base-64, заключенную между строкой заголовка и строкой нижнего колонтитула:

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

Certificate chainsЦепочки сертификатов

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

python
-----BEGIN CERTIFICATE-----
... (certificate for your server)...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
... (the certificate for the CA)...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
... (the root certificate for the CA's issuer)...
-----END CERTIFICATE-----

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

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

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

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

python
-----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, например, следующим образом:

python
% 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Примеры

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

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

python
try:
    import ssl
except ImportError:
    pass
else:
    ...  # выполнить действие, требующее поддержки SSL

Client-side operationРабота на стороне клиента

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

python
>>> context = ssl.create_default_context()

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

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

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

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

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

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

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

python
>>> cert = conn.getpeercert()

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

python
>>> 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-канал установлен и сертификат проверен, вы можете продолжить общение с сервером:

python
>>> 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() и начнёте ожидать подключения клиентов:

python
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-сокета для подключения:

python
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 и что-то с ними делать, пока не закончите работу с клиентом (или клиент не закончит с вами):

python
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() для ожидания готовности сокета:

    python
    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 BIO supportПоддержка Memory BIO

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

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

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

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

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

Объединение обработки протокола SSL и сетевого ввода-вывода обычно работает хорошо, но есть случаи, когда это не так. Примером являются асинхронные фреймворки ввода-вывода, которые хотят использовать другую модель мультиплексирования IO, отличную от модели «select/poll на файловом дескрипторе» (основанной на готовности), которая предполагается socket.socket и внутренними процедурами сокетного IO 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.

Changed in version 3.7: SSLObject instances must be created with wrap_bio(). In earlier versions, it was possible to create instances directly. This was never documented or officially supported.

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

class ssl.MemoryBIO

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

pending

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

eof

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

read(n=-1, /)

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

write(buf, /)

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

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

write_eof()

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

SSL sessionSSL-сессия

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

python
>>> 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 отключены по умолчанию.

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

Созданный выше SSL-контекст будет разрешать только соединения с сервером по 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, такие как ранние данные, отложенный запрос клиентского сертификата 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