ssl — TLS/SSL обёртка для сокетных объектов

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


Модуль обеспечивает доступ к средствам шифрования и одноранговой аутентификации для сетевых сокетов, как на стороне клиента, так и на стороне сервера. Модуль использует библиотеку OpenSSL. Он доступен на всех современных Unix-системах, Windows, Mac OS X и, вероятно, дополнительных платформах, пока OpenSSL установлен на этой платформе.

Примечание

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

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

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

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

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

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

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

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

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

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

Так как Python 3.2 и 2.7.9, рекомендуется использовать SSLContext.wrap_socket() SSLContext сущность для обертывания сокеты в качестве SSLSocket объектов. Помощник create_default_context() возвращает новый контекст с безопасными настройками по умолчанию. Старая функция wrap_socket() устарела, поскольку она неэффективна и не поддерживает указание имени сервера (SNI) и сопоставление имени хоста.

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

import socket
import ssl

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

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

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

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

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

Сервер сокет пример прослушивания IPv4 localhost:

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

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

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

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

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

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

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

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

Примечание

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

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

Примечание

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

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

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

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

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

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

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

Исключения

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

При попытке выполнить операцию на SSL- SSLError возникла подкласс сокет. К сожалению, нет простого способа проверить исходный номер ошибки.

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

exception ssl.SSLEOFError

При резком завершении SSL-соединения возникает подкласс SSLError. Как правило, при возникновении этой ошибки не следует пытаться повторно использовать базовый транспорт.

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

exception ssl.SSLCertVerificationError

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

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

verify_code

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

verify_message

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

exception ssl.CertificateError

Это алиас для SSLCertVerificationError.

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

Случайное поколение

ssl.RAND_bytes(num)

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

Практически для всех применений os.urandom() является предпочтительным.

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

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

ssl.RAND_pseudo_bytes(num)

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

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

Практически для всех применений os.urandom() является предпочтительным.

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

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

ssl.RAND_status()

Возвращает True, если SSL псевдослучайное число генератор было затравлено с «достаточной» случайностью, и False иначе. Можно использовать ssl.RAND_egd() и ssl.RAND_add() для увеличения случайности генератор псевдослучайных чисел.

ssl.RAND_egd(path)

Если вы где-то запускаете демон сбора энтропии (EGD), и path является именем пути открытого для него соединения сокет, это будет считывать 256 байт случайности из сокет, и добавлять его в генератор псевдослучайных чисел SSL, чтобы повысить безопасность генерируемых секретных ключей. Это обычно необходимо только в системах без лучших источников случайности.

Источники демонов сбора энтропии см. в http://egd.sourceforge.net/ или http://prngd.sourceforge.net/.

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

ssl.RAND_add(bytes, entropy)

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

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

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

ssl.match_hostname(cert, hostname)

Убедитесь, что cert (в декодированном формате, как возвращенный SSLSocket.getpeercert()) соответствует заданному hostname. Применяются правила проверки подлинности HTTPS-серверов, описанные в разделах RFC 2818, RFC 5280 и RFC 6125. Помимо HTTPS, эта функция должна быть пригодна для проверки идентичности серверов в различных протоколах на основе SSL, таких как FTPS, IMAPS, POPS и других.

CertificateError поднимается при отказе. При успехе функция ничего не возвращает:

>>> cert = {'subject': ((('commonName', 'example.com'),),)}
>>> ssl.match_hostname(cert, "example.com")
>>> ssl.match_hostname(cert, "example.org")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/py3k/Lib/ssl.py", line 130, in match_hostname
ssl.CertificateError: hostname 'example.org' doesn't match 'example.com'

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

Изменено в версии 3.3.3: Теперь функция следует за RFC 6125, раздел 6.4.3, и не соответствует ни нескольким подстановочным знакам (например, *.*.com или *a*.example.org), ни подстановочному знаку внутри фрагмента интернационализированных доменных имен (IDN). IDN A-метки, такие как www*.xn--pthon-kva.org, по-прежнему поддерживаются, но x*.python.org больше не соответствуют xn--tda.python.org.

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

Изменено в версии 3.7: Функция больше не используемый для соединений TLS. Сопоставление имен хостов теперь выполняется OpenSSL.

Разрешить подстановочные знаки, если это крайний левый и единственный символ в этом сегменте. Частичные подстановочные знаки, такие как www*.example.com, больше не поддерживаются.

Не рекомендуется, начиная с версии 3.7.

ssl.cert_time_to_seconds(cert_time)

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

Вот пример:

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

В датах «notBefore» или «notAfter» должен использоваться GMT (RFC 5280).

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

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

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

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

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

ssl.DER_cert_to_PEM_cert(DER_cert_bytes)

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

ssl.PEM_cert_to_DER_cert(PEM_cert_string)

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

ssl.get_default_verify_paths()

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

  • cafile - разрешенный путь к кафе или None, если файл не существует,
  • capath - разрешенный путь к capath или None, если каталог не существует,
  • OpenSSL_cafile_env - ключ среды OpenSSL, указывающий на кафе,
  • OpenSSL_cafile - жесткий закодированный путь к кафе,
  • OpenSSL_capath_env - ключ среды OpenSSL, указывающий на capath,
  • OpenSSL_capath - жесткий закодированный путь к каталогу capath

Доступность: LibreSSL ignores the environment vars OpenSSL_cafile_env и OpenSSL_capath_env.

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

ssl.enum_certificates(store_name)

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

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

Пример:

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

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

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

ssl.enum_crls(store_name)

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

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

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

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

ssl.wrap_socket(sock, keyfile=None, certfile=None, server_side=False, cert_reqs=CERT_NONE, ssl_version=PROTOCOL_TLS, ca_certs=None, do_handshake_on_connect=True, suppress_ragged_eofs=True, ciphers=None)

Принимает сущность sock socket.socket и возвращает сущность ssl.SSLSocket, подтип socket.socket, который переносит базовый сокет в SSL-контекст. sock должно быть SOCK_STREAM сокет; другие типы сокет не поддерживаются.

Внутри функции создается SSLContext с протоколом ssl_version и SSLContext.options, имеющим значение cert_reqs. Если установлены параметры keyfile, certfile, ca_certs или ciphers, то значения передаются в SSLContext.load_cert_chain(), SSLContext.load_verify_locations() и SSLContext.set_ciphers().

Аргументы server_side, do_handshake_on_connect и suppress_ragged_eofs имеют то же значение, что и SSLContext.wrap_socket().

Не рекомендуется, начиная с версии 3.7: Так как Python 3.2 и 2.7.9, рекомендуется использовать SSLContext.wrap_socket() вместо wrap_socket(). Функция верхнего уровня ограничена и создает небезопасный клиентский сокет без указания имени сервера или сопоставления имени хоста.

Константы

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

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

ssl.CERT_NONE

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

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

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

ssl.CERT_OPTIONAL

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

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

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

ssl.CERT_REQUIRED

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

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

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

class ssl.VerifyMode

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

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

ssl.VERIFY_DEFAULT

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

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

ssl.VERIFY_CRL_CHECK_LEAF

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

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

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

class ssl.VerifyFlags

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

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

ssl.PROTOCOL_TLS

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

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

ssl.PROTOCOL_TLS_CLIENT

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

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

ssl.PROTOCOL_TLS_SERVER

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

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

ssl.PROTOCOL_SSLv23

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

Не рекомендуется, начиная с версии 3.6: Вместо этого используйте PROTOCOL_TLS.

ssl.PROTOCOL_SSLv2

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

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

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

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

Не рекомендуется, начиная с версии 3.6: OpenSSL удалил поддержку SSLv2.

ssl.PROTOCOL_SSLv3

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

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

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

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

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

ssl.PROTOCOL_TLSv1

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

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

ssl.PROTOCOL_TLSv1_1

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

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

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

ssl.PROTOCOL_TLSv1_2

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

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

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

ssl.OP_ALL

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

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

ssl.OP_NO_RENEGOTIATION

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

Этот параметр доступен только для 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

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

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

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

ssl.OP_NO_COMPRESSION

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

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

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

class ssl.Options

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

ssl.OP_NO_TICKET

Запретить клиентской стороне запрашивать мандат сеанса.

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

ssl.HAS_ALPN

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

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

ssl.HAS_NEVER_CHECK_COMMON_NAME

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

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

ssl.HAS_ECDH

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

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

ssl.HAS_SNI

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

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

ssl.HAS_NPN

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

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

ssl.HAS_SSLv2

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

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

ssl.HAS_SSLv3

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

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

ssl.HAS_TLSv1

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

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

ssl.HAS_TLSv1_1

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

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

ssl.HAS_TLSv1_2

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

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

ssl.HAS_TLSv1_3

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

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

ssl.CHANNEL_BINDING_TYPES

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

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

ssl.OPENSSL_VERSION

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

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

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

ssl.OPENSSL_VERSION_INFO

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

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

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

ssl.OPENSSL_VERSION_NUMBER

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

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

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

ssl.ALERT_DESCRIPTION_HANDSHAKE_FAILURE
ssl.ALERT_DESCRIPTION_INTERNAL_ERROR
ALERT_DESCRIPTION_*

Описания оповещений от RFC 5246 и других. В реестре предупреждений IANA TLS содержится этот список и ссылки на 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.

Сокеты SSL

class ssl.SSLSocket(socket.socket)

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

Однако, так как протокол SSL (и TLS) имеет свой собственный фрейминг поверх TCP, SSL сокеты абстракция может в определённых отношениях расходиться со спецификацией нормального, OS-уровня сокеты. Особенно видишь notes on non-blocking sockets.

Сущности SSLSocket должны быть созданы с помощью метода SSLContext.wrap_socket().

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

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

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

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

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

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

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

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

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

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

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

SSLSocket.write(buf)

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

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

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

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

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

Примечание

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

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

SSLSocket.do_handshake()

Выполните квитирование установки SSL.

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

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

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

SSLSocket.getpeercert(binary_form=False)

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

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

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

{'issuer': ((('countryName', 'IL'),),
            (('organizationName', 'StartCom Ltd.'),),
            (('organizationalUnitName',
              'Secure Digital Certificate Signing'),),
            (('commonName',
              'StartCom Class 2 Primary Intermediate Server CA'),)),
 'notAfter': 'Nov 22 08:15:19 2013 GMT',
 'notBefore': 'Nov 21 03:09:52 2011 GMT',
 'serialNumber': '95F0',
 'subject': ((('description', '571208-SLe257oHY9fVQ07Z'),),
             (('countryName', 'US'),),
             (('stateOrProvinceName', 'California'),),
             (('localityName', 'San Francisco'),),
             (('organizationName', 'Electronic Frontier Foundation, Inc.'),),
             (('commonName', '*.eff.org'),),
             (('emailAddress', 'hostmaster@eff.org'),)),
 'subjectAltName': (('DNS', '*.eff.org'), ('DNS', 'eff.org')),
 'version': 3}

Примечание

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

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

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

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

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

Изменено в версии 3.8.1: IPv6 адрес больше не строки иметь завершающую новую строку.

SSLSocket.cipher()

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

SSLSocket.shared_ciphers()

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

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

SSLSocket.compression()

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

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

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

SSLSocket.get_channel_binding(cb_type="tls-unique")

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

Параметр cb_type позволяет выбрать требуемый тип биндинг канала. Допустимые типы биндинг каналов перечислены в списке CHANNEL_BINDING_TYPES. В настоящее время поддерживается только биндинг канала «tls-unique», определенный RFC 5929. ValueError генерируется, если запрашивается неподдерживаемый тип биндинг канала.

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

SSLSocket.selected_alpn_protocol()

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

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

SSLSocket.selected_npn_protocol()

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

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

SSLSocket.unwrap()

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

SSLSocket.verify_client_post_handshake()

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

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

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

Примечание

Доступно только с включенными 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- сокет. Если SSL- сокет был создан с использованием устаревшей функции wrap_socket() (а не SSLContext.wrap_socket()), это пользовательский объект контекст, созданный для этого SSL- сокет.

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

SSLSocket.server_side

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

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

SSLSocket.server_hostname

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

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

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

SSLSocket.session

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

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

SSLSocket.session_reused

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

Контексты SSL

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

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

class ssl.SSLContext(protocol=PROTOCOL_TLS)

Создать новый SSL-контекст. Можно передать protocol, которая должна быть одной из PROTOCOL_* констант, определенных в этом модуле. Параметр указывает, какую версию протокола SSL использовать. Обычно сервер выбирает конкретную версию протокола, и клиент должен адаптироваться к выбору сервера. Большинство версий не совместимы с другими версиями. Если не указано, по умолчанию используется значение PROTOCOL_TLS; обеспечивает наибольшую совместимость с другими версиями.

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

клиент / сервер SSLv2 SSLv3 TLS [3] TLSv1 TLSv1.1 TLSv1.2
SSLv2 yes no no [1] no no no
SSLv3 no yes no [2] no no no
TLS (SSLv23) [3] no [1] no [2] yes yes yes yes
TLSv1 no no yes yes no no
TLSv1.1 no no yes no yes no
TLSv1.2 no no yes no no yes

Сноски

[1](1, 2) SSLContext по умолчанию отключает SSLv2 с OP_NO_SSLv2.
[2](1, 2) SSLContext по умолчанию отключает SSLv3 с OP_NO_SSLv3.
[3](1, 2) TLS 1.3 протокол будет доступен с PROTOCOL_TLS в OpenSSL > = 1.1.1. Выделенная константа PROTOCOL отсутствует только для TLS 1.3.

См.также

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

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

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

SSLContext.cert_store_stats()

Получение статистики об объемах загруженных сертификатов X.509, количестве сертификатов X.509, помеченных как сертификаты ЦС, и списках отзыва сертификатов как словарь.

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

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

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

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

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

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

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

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

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

SSLContext.load_default_certs(purpose=Purpose.SERVER_AUTH)

Загрузить набор сертификатов центра сертификации (ЦС) по умолчанию из местоположений по умолчанию. В 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)

Загрузить набор сертификатов центра сертификации (ЦС), используемый для проверки сертификатов других одноранговых узлов, если verify_mode отличается от CERT_NONE. Необходимо указать хотя бы один из cafile или capath.

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

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

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

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

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

SSLContext.get_ca_certs(binary_form=False)

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

Примечание

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

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

SSLContext.get_ciphers()

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

Пример:

>>> ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
>>> ctx.set_ciphers('ECDHE+AESGCM:!ECDSA')
>>> ctx.get_ciphers()  # OpenSSL 1.0.x
[{'alg_bits': 256,
  'description': 'ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH     Au=RSA  '
                 'Enc=AESGCM(256) Mac=AEAD',
  'id': 50380848,
  'name': 'ECDHE-RSA-AES256-GCM-SHA384',
  'protocol': 'TLSv1/SSLv3',
  'strength_bits': 256},
 {'alg_bits': 128,
  'description': 'ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH     Au=RSA  '
                 'Enc=AESGCM(128) Mac=AEAD',
  'id': 50380847,
  'name': 'ECDHE-RSA-AES128-GCM-SHA256',
  'protocol': 'TLSv1/SSLv3',
  'strength_bits': 128}]

В OpenSSL 1.1 и более новой версии шифр словарь содержит дополнительные поля:

>>> ctx.get_ciphers()  # OpenSSL 1.1+
[{'aead': True,
  'alg_bits': 256,
  'auth': 'auth-rsa',
  'description': 'ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH     Au=RSA  '
                 'Enc=AESGCM(256) Mac=AEAD',
  'digest': None,
  'id': 50380848,
  'kea': 'kx-ecdhe',
  'name': 'ECDHE-RSA-AES256-GCM-SHA384',
  'protocol': 'TLSv1.2',
  'strength_bits': 256,
  'symmetric': 'aes-256-gcm'},
 {'aead': True,
  'alg_bits': 128,
  'auth': 'auth-rsa',
  'description': 'ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH     Au=RSA  '
                 'Enc=AESGCM(128) Mac=AEAD',
  'digest': None,
  'id': 50380847,
  'kea': 'kx-ecdhe',
  'name': 'ECDHE-RSA-AES128-GCM-SHA256',
  'protocol': 'TLSv1.2',
  'strength_bits': 128,
  'symmetric': 'aes-128-gcm'}]

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

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

SSLContext.set_default_verify_paths()

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

SSLContext.set_ciphers(ciphers)

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

Примечание

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

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

SSLContext.set_alpn_protocols(protocols)

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

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

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

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

SSLContext.set_npn_protocols(protocols)

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

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

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

SSLContext.sni_callback

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

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

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

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

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

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

В случае возникновения исключения из функции sni_callback соединение TLS завершится неустранимым ALERT_DESCRIPTION_HANDSHAKE_FAILURE предупреждающего сообщения TLS.

Этот метод вызывает 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 неустранимым предупреждением TLS для клиента.

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

SSLContext.load_dh_params(dhfile)

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

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

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

SSLContext.set_ecdh_curve(curve_name)

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

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

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

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

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

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

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

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

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

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

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

session, смотри session.

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

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

Изменено в версии 3.7: Метод возвращает на сущность SSLContext.sslsocket_class вместо жестко закодированных SSLSocket.

SSLContext.sslsocket_class

Тип возвращает SSLContext.wrap_socket() по умолчанию - SSLSocket. атрибут может быть отвергнут на сущность класса чтобы к возвращает пользовательский подкласс SSLSocket.

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

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

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

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

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

Изменено в версии 3.7: Метод возвращает на сущность SSLContext.sslobject_class вместо жестко закодированных SSLObject.

SSLContext.sslobject_class

Тип возвращает SSLContext.wrap_bio() по умолчанию - SSLObject. атрибут может быть отвергнут на сущность класса чтобы к возвращает пользовательский подкласс SSLObject.

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

SSLContext.session_stats()

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

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

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

Пример:

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.

Примечание

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

SSLContext.keylog_filename

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

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

Примечание

Для работы этих функций требуется OpenSSL 1.1.1 или более новая версия.

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.

Примечание

Этот атрибут недоступен, если SSL-модуль не скомпилирован с OpenSSL 1.1.0g или более поздней версии.

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

SSLContext.minimum_version

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

Примечание

Этот атрибут недоступен, если SSL-модуль не скомпилирован с OpenSSL 1.1.0g или более поздней версии.

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

SSLContext.num_tickets

Управление количеством билетов сеанса TLS 1.3 TLS_PROTOCOL_SERVER контекст. Этот параметр не влияет на TLS 1.0 до 1.2 подключениям.

Примечание

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

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

SSLContext.options

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

Примечание

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

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

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

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

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

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

Примечание

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

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

SSLContext.protocol

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

SSLContext.hostname_checks_common_name

Возвращается ли check_hostname для проверки общего имени субъекта сертификата при отсутствии расширения альтернативного имени субъекта (по умолчанию true).

Примечание

Записывается только с OpenSSL 1.1.0 или более поздней версии.

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

SSLContext.verify_flags

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

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

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

>>> ssl.create_default_context().verify_flags  # doctest: +SKIP
<VerifyFlags.VERIFY_X509_TRUSTED_FIRST: 32768>
SSLContext.verify_mode

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

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

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

Сертификаты

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

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

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

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

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

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

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

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

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

Комбинированный ключ и сертификат

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

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

Самоподписанные сертификаты

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

% OpenSSL req -new -x509 -days 365 -nodes -out cert.pem -keyout cert.pem
Generating a 1024 bit RSA private key
.......++++++
.............................++++++
writing new private key to 'cert.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:MyState
Locality Name (eg, city) []:Some City
Organization Name (eg, company) [Internet Widgits Pty Ltd]:My Organization, Inc.
Organizational Unit Name (eg, section) []:My Group
Common Name (eg, YOUR name) []:myserver.mygroup.myorganization.com
Email Address []:ops@myserver.mygroup.myorganization.com
%

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

Примеры

Тестирование поддержки SSL

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

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

Клиентская операция

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

>>> context = ssl.create_default_context()

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

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

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

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

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

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

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

>>> cert = conn.getpeercert()

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

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

Теперь канал SSL установлен и сертификат проверен, можно перейти к разговору с сервером:

>>> conn.sendall(b"HEAD / HTTP/1.0\r\nHost: linuxfr.org\r\n\r\n")
>>> pprint.pprint(conn.recv(1024).split(b"\r\n"))
[b'HTTP/1.1 200 OK',
 b'Date: Sat, 18 Oct 2014 18:27:20 GMT',
 b'Server: nginx',
 b'Content-Type: text/html; charset=utf-8',
 b'X-Frame-Options: SAMEORIGIN',
 b'Content-Length: 45679',
 b'Accept-Ranges: bytes',
 b'Via: 1.1 varnish',
 b'Age: 2188',
 b'X-Served-By: cache-lcy1134-LCY',
 b'X-Cache: HIT',
 b'X-Cache-Hits: 11',
 b'Vary: Cookie',
 b'Strict-Transport-Security: max-age=63072000; includeSubDomains',
 b'Connection: close',
 b'',
 b'']

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

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

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

import socket, ssl

context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
context.load_cert_chain(certfile="mycertfile", keyfile="mykeyfile")

bindsocket = socket.socket()
bindsocket.bind(('myaddr.mydomain.com', 10023))
bindsocket.listen(5)

Когда клиент подключается, вы вызываете accept() на сокет, чтобы получить новый сокет с другого конца, и используете метод SSLContext.wrap_socket() контекст, чтобы создать SSL- сокет на стороне сервера для подключения:

while True:
    newsocket, fromaddr = bindsocket.accept()
    connstream = context.wrap_socket(newsocket, server_side=True)
    try:
        deal_with_client(connstream)
    finally:
        connstream.shutdown(socket.SHUT_RDWR)
        connstream.close()

Затем вы будете считывать данные из connstream и делать что-то с ним, пока вы закончите с клиентом (или клиент закончит с вами):

def deal_with_client(connstream):
    data = connstream.recv(1024)
    # пустые данные означают, что клиент закончил с нами
    while data:
        if not do_something(connstream, data):
            # Мы будем считать do_something возвращает False,
            # когда закончим с клиентом
            break
        data = connstream.recv(1024)
    # закончим с клиентом

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

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

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

  • Большинство методов SSLSocket приводит к SSLWantWriteError или SSLWantReadError вместо BlockingIOError, если операция I/O блокирует. SSLWantReadError будет возникать, если необходима операция чтения на базовом сокет и SSLWantWriteError для операции записи на базовом сокет. Следует отметить, что попытки write к сокет SSL могут потребовать сначала reading от базового сокет, а попытки read от сокет SSL могут потребовать предварительного write к базовому сокет.

    Изменено в версии 3.5: В более ранних Python вариантах метод SSLSocket.send() возвращенный нулевым вместо повышения SSLWantWriteError или SSLWantReadError.

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

  • И наоборот, поскольку уровень SSL имеет свою собственную структуру кадров, сокет SSL все еще может иметь данные, доступные для чтения, не зная об этом select(). Поэтому сначала следует вызвать SSLSocket.recv(), чтобы слить любые потенциально доступные данные, а затем заблокировать select() вызов только при необходимости.

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

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

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

См.также

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

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

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

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

  • обработка протокола SSL
  • Network IO.

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

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

class ssl.SSLObject

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

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

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

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

При сравнении с SSLSocket у этого объекта отсутствуют следующие возможности:

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

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

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

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

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

class ssl.MemoryBIO

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

pending

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

eof

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

read(n=-1)

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

write(buf)

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

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

write_eof()

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

SSL сессия

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

class ssl.SSLSession

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

id
time
timeout
ticket_lifetime_hint
has_ticket

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

Лучшие умолчания

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

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

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

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

Ручные параметры настройки

Подтверждение сертификатов

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

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

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

Версии протокола

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

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

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

Выбор шифра

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

Многопроцессорный

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

TLS 1.3

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

Python имеет предварительную и экспериментальную поддержку TLS 1.3 с OpenSSL 1.1.1. Новый протокол ведет себя несколько иначе, чем предыдущая версия TLS/SSL. Некоторые новые функции TLS 1.3 пока недоступны.

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

Поддержка LibreSSL

LibreSSL является форком OpenSSL 1.0.1. SSL-модуль имеет ограниченную поддержку LibreSSL. Некоторые функции недоступны при компиляции SSL-модуля с помощью LibreSSL.