ssl — оболочка TLS/SSL для объектов сокетов
Исходный код: Lib/ssl.py
Этот модуль предоставляет сетевым сокетам клиентской и серверной сторон доступ к средствам шифрования Transport Layer Security (часто известного как «Secure Sockets Layer») и аутентификации узлов. Этот модуль использует библиотеку OpenSSL. Она доступна во всех современных системах Unix, Windows, macOS и, вероятно, на дополнительных платформах при условии, что на платформе установлена OpenSSL.
Примечание
Некоторое поведение может зависеть от платформы, поскольку выполняются вызовы API сокетов операционной системы. Установленная версия OpenSSL также может вызывать различия в поведении. Например, TLSv1.3 появился в OpenSSL версии 1.1.1.
Предупреждение
Не используйте этот модуль, не прочитав раздел Рекомендации по безопасности. Иначе у вас может возникнуть ложное чувство защищённости, поскольку настройки модуля ssl по умолчанию не обязательно подходят для вашего приложения.
Доступность: недоступен в Emscripten и WASI.
Этот модуль не работает или недоступен на платформах WebAssembly wasm32-emscripten и wasm32-wasi. Подробнее см. в разделе Платформы WebAssembly.
В этом разделе документированы объекты и функции модуля 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.
Изменено в версии 3.10: Реализован PEP 644. Для модуля ssl требуется OpenSSL 1.1.1 или новее.
Использование устаревших констант и функций вызывает предупреждения об устаревании.
Функции, константы и исключения
Создание сокета
Экземпляры SSLSocket должны создаваться с помощью метода SSLContext.wrap_socket(). Вспомогательная функция create_default_context() возвращает новый контекст с безопасными настройками по умолчанию.
Пример клиентского сокета с контекстом по умолчанию и двойным стеком IPv4/IPv6:
import socket
import ssl
hostname = 'www.python.org'
context = ssl.create_default_context()
with socket.create_connection((hostname, 443)) as sock:
with context.wrap_socket(sock, server_hostname=hostname) as ssock:
print(ssock.version())
Пример клиентского сокета с пользовательским контекстом и IPv4:
hostname = 'www.python.org'
# PROTOCOL_TLS_CLIENT requires valid cert chain and hostname
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
context.load_verify_locations('path/to/cabundle.pem')
with socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) as sock:
with context.wrap_socket(sock, server_hostname=hostname) as ssock:
print(ssock.version())
Пример серверного сокета, прослушивающего localhost по IPv4:
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.load_cert_chain('/path/to/certchain.pem', '/path/to/private.key')
with socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) as sock:
sock.bind(('127.0.0.1', 8443))
sock.listen(5)
with context.wrap_socket(sock, server_side=True) as ssock:
conn, addr = ssock.accept()
...
Создание контекста
Вспомогательная функция помогает создавать объекты 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_CLIENTилиPROTOCOL_TLS_SERVER,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.Изменено в версии 3.10: Теперь контекст использует протокол
PROTOCOL_TLS_CLIENTилиPROTOCOL_TLS_SERVERвместо общего протоколаPROTOCOL_TLS.
Исключения
-
exception ssl.SSLError -
Вызывается для обозначения ошибки в базовой реализации SSL (в настоящее время предоставляемой библиотекой OpenSSL). Это указывает на проблему на вышележащем уровне шифрования и аутентификации, наложенном на базовое сетевое соединение. Это исключение является подклассом
OSError. Код и сообщение об ошибке экземпляровSSLErrorпредоставляет библиотека OpenSSL.Изменено в версии 3.3: Раньше
SSLErrorбыл подклассомsocket.error.-
library -
Строковое мнемоническое обозначение подмодуля OpenSSL, в котором произошла ошибка, например
SSL,PEMилиX509. Диапазон возможных значений зависит от версии OpenSSL.Добавлено в версии 3.3.
-
reason -
Строковое мнемоническое обозначение причины возникновения этой ошибки, например
CERTIFICATE_VERIFY_FAILED. Диапазон возможных значений зависит от версии OpenSSL.Добавлено в версии 3.3.
-
-
exception ssl.SSLZeroReturnError -
Подкласс
SSLError, вызываемый при попытке чтения или записи, если SSL-соединение было корректно закрыто. Обратите внимание, что это не означает, что базовый транспорт (то есть TCP) был закрыт.Добавлено в версии 3.3.
-
exception ssl.SSLWantReadError -
Подкласс
SSLError, вызываемый неблокирующим SSL-сокетом при попытке чтения или записи данных, если до выполнения запроса необходимо получить дополнительные данные через базовый транспорт TCP.Добавлено в версии 3.3.
-
exception ssl.SSLWantWriteError -
Подкласс
SSLError, вызываемый неблокирующим SSL-сокетом при попытке чтения или записи данных, если до выполнения запроса необходимо отправить дополнительные данные через базовый транспорт TCP.Добавлено в версии 3.3.
-
exception ssl.SSLSyscallError -
Подкласс
SSLError, вызываемый при возникновении системной ошибки во время выполнения операции над SSL-сокетом. К сожалению, простого способа получить исходный номер errno нет.Добавлено в версии 3.3.
-
exception ssl.SSLEOFError -
Подкласс
SSLError, вызываемый при внезапном разрыве SSL-соединения. Как правило, при возникновении этой ошибки не следует повторно использовать базовый транспорт.Добавлено в версии 3.3.
-
exception ssl.SSLCertVerificationError -
Подкласс
SSLError, вызываемый при сбое проверки сертификата.Добавлено в версии 3.7.
-
verify_code -
Числовой код ошибки, обозначающий ошибку проверки.
-
verify_message -
Текстовое описание ошибки проверки.
-
-
exception ssl.CertificateError -
Псевдоним для
SSLCertVerificationError.Изменено в версии 3.7: Теперь это исключение является псевдонимом для
SSLCertVerificationError.
Генерация случайных данных
-
ssl.RAND_bytes(num) -
Возвращает num криптографически стойких псевдослучайных байтов. Вызывает исключение
SSLError, если ГПСЧ не был инициализирован достаточным количеством данных или если текущий метод RAND не поддерживает эту операцию. С помощьюRAND_status()можно проверить состояние ГПСЧ, а с помощьюRAND_add()— инициализировать ГПСЧ.Почти во всех приложениях предпочтительнее использовать
os.urandom().Требования к криптографически стойкому генератору описаны в статье Википедии «Криптографически стойкий генератор псевдослучайных чисел (CSPRNG)».
Добавлено в версии 3.3.
-
ssl.RAND_status() -
Возвращает
True, если генератор псевдослучайных чисел SSL инициализирован «достаточным» количеством случайных данных, иFalseв противном случае. Для увеличения случайности генератора псевдослучайных чисел можно использоватьssl.RAND_egd()иssl.RAND_add().
-
ssl.RAND_add(bytes, entropy) -
Добавляет указанные bytes в генератор псевдослучайных чисел SSL. Параметр entropy (число с плавающей точкой) задаёт нижнюю границу энтропии, содержащейся в строке (поэтому всегда можно использовать
0.0). Подробнее об источниках энтропии см. в RFC 1750.Изменено в версии 3.5: Теперь принимается записываемый объект, подобный bytes.
Работа с сертификатами
-
ssl.cert_time_to_seconds(cert_time) -
Возвращает время в секундах с начала эпохи по строке
cert_time, представляющей дату «notBefore» или «notAfter» сертификата в формате"%b %d %H:%M:%S %Y %Z"strptime (локаль C).Пример:
>>> import ssl >>> timestamp = ssl.cert_time_to_seconds("Jan 5 09:34:43 2018 GMT") >>> timestamp 1515144883 >>> from datetime import datetime >>> print(datetime.utcfromtimestamp(timestamp)) 2018-01-05 09:34:43В датах «notBefore» и «notAfter» необходимо использовать время по Гринвичу (RFC 5280).
Изменено в версии 3.5: Входное время интерпретируется как время UTC, заданное часовым поясом «GMT» во входной строке. Раньше использовался местный часовой пояс. Возвращается целое число (входной формат не предусматривает долей секунды)
-
ssl.get_server_certificate(addr, ssl_version=PROTOCOL_TLS_CLIENT, ca_certs=None[, timeout]) -
Получает сертификат SSL-защищённого сервера по его адресу
addr, заданному парой (hostname, port-number), и возвращает его в виде строки в кодировке PEM. Если задан параметрssl_version, для попытки подключения к серверу используется указанная версия протокола SSL. Если указан параметр ca_certs, он должен быть именем файла со списком корневых сертификатов в том же формате, что и параметр cafile вSSLContext.load_verify_locations(). Выполняется попытка проверить сертификат сервера по этому набору корневых сертификатов; если проверка не пройдёт, вызов завершится ошибкой. Тайм-аут можно задать параметромtimeout.Изменено в версии 3.3: Теперь эта функция совместима с IPv6.
Изменено в версии 3.5: Версия SSL по умолчанию ssl_version изменена с
PROTOCOL_SSLv3наPROTOCOL_TLSдля максимальной совместимости с современными серверами.Изменено в версии 3.10: Добавлен параметр timeout.
-
ssl.DER_cert_to_PEM_cert(DER_cert_bytes) -
Преобразует сертификат в виде последовательности байтов в кодировке DER в строковое представление того же сертификата в кодировке PEM.
-
ssl.PEM_cert_to_DER_cert(PEM_cert_string) -
Преобразует сертификат в виде строки ASCII в кодировке PEM в последовательность байтов в кодировке DER для того же сертификата.
-
ssl.get_default_verify_paths() -
Возвращает именованный кортеж с путями к файлу cafile и каталогу capath по умолчанию для OpenSSL. Эти пути совпадают с используемыми методом
SSLContext.set_default_verify_paths(). Возвращаемое значение — это именованный кортежDefaultVerifyPaths:-
cafile— разрешённый путь к cafile илиNone, если файл не существует, -
capath— разрешённый путь к capath илиNone, если каталог не существует, -
openssl_cafile_env— ключ среды OpenSSL, указывающий на cafile, -
openssl_cafile— жёстко заданный путь к cafile, -
openssl_capath_env— ключ среды OpenSSL, указывающий на capath, -
openssl_capath— жёстко заданный путь к каталогу capath
Добавлено в версии 3.4.
-
-
ssl.enum_certificates(store_name) -
Получает сертификаты из системного хранилища сертификатов Windows. В качестве store_name можно указать
CA,ROOTилиMY. В Windows могут быть и другие хранилища сертификатов.Функция возвращает список кортежей (cert_bytes, encoding_type, trust). encoding_type задаёт кодировку cert_bytes. Это может быть
x509_asnдля данных X.509 ASN.1 илиpkcs_7_asnдля данных PKCS#7 ASN.1. trust задаёт назначение сертификата в виде набора OID или ровноTrue, если сертификату можно доверять для любых целей.Пример:
>>> ssl.enum_certificates("CA") [(b'data...', 'x509_asn', {'1.3.6.1.5.5.7.3.1', '1.3.6.1.5.5.7.3.2'}), (b'data...', 'x509_asn', True)]Доступность: Windows.
Добавлено в версии 3.4.
-
ssl.enum_crls(store_name) -
Получает списки отозванных сертификатов (CRL) из системного хранилища сертификатов Windows. В качестве store_name можно указать
CA,ROOTилиMY. В Windows могут быть и другие хранилища сертификатов.Функция возвращает список кортежей (cert_bytes, encoding_type, trust). encoding_type задаёт кодировку cert_bytes. Это может быть
x509_asnдля данных X.509 ASN.1 илиpkcs_7_asnдля данных PKCS#7 ASN.1.Доступность: Windows.
Добавлено в версии 3.4.
Константы
Теперь все константы представляют собой коллекции enum.IntEnum или enum.IntFlag.
Добавлено в версии 3.6.
-
ssl.CERT_NONE -
Возможное значение для
SSLContext.verify_mode. За исключениемPROTOCOL_TLS_CLIENT, это режим по умолчанию. На стороне клиента принимается практически любой сертификат. Ошибки проверки, например недоверенный или просроченный сертификат, игнорируются и не прерывают рукопожатие TLS/SSL.В режиме сервера сертификат у клиента не запрашивается, поэтому клиент не отправляет его для аутентификации с помощью клиентского сертификата.
См. обсуждение в разделе Рекомендации по безопасности ниже.
-
ssl.CERT_OPTIONAL -
Возможное значение для
SSLContext.verify_mode. В режиме клиентаCERT_OPTIONALимеет то же значение, что иCERT_REQUIRED. Вместо этого для сокетов на стороне клиента рекомендуется использоватьCERT_REQUIRED.В режиме сервера клиенту отправляется запрос на предоставление сертификата. Клиент может проигнорировать запрос или отправить сертификат для аутентификации клиента TLS. Если клиент решит отправить сертификат, он будет проверен. Любая ошибка проверки немедленно прерывает рукопожатие TLS.
Для использования этой настройки необходимо передать действительный набор сертификатов CA в
SSLContext.load_verify_locations().
-
ssl.CERT_REQUIRED -
Возможное значение для
SSLContext.verify_mode. В этом режиме от другой стороны соединения сокетов требуются сертификаты; если сертификат не предоставлен или его проверка завершится неудачей, будет вызвано исключениеSSLError. Этого режима недостаточно для проверки сертификата в режиме клиента, так как он не сопоставляет имена хостов. Для проверки подлинности сертификата также необходимо включитьcheck_hostname.PROTOCOL_TLS_CLIENTиспользуетCERT_REQUIREDи по умолчанию включаетcheck_hostname.Для серверного сокета этот режим обеспечивает обязательную аутентификацию клиента TLS с помощью сертификата. Клиенту отправляется запрос на предоставление сертификата, и клиент должен предоставить действительный сертификат, которому можно доверять.
Для использования этой настройки необходимо передать действительный набор сертификатов CA в
SSLContext.load_verify_locations().
-
class ssl.VerifyMode -
Коллекция
enum.IntEnumконстант CERT_*.Добавлено в версии 3.6.
-
ssl.VERIFY_DEFAULT -
Возможное значение для
SSLContext.verify_flags. В этом режиме списки отзыва сертификатов (CRL) не проверяются. По умолчанию OpenSSL не требует наличия CRL и не проверяет их.Добавлено в версии 3.4.
-
ssl.VERIFY_CRL_CHECK_LEAF -
Возможное значение для
SSLContext.verify_flags. В этом режиме проверяется только сертификат узла, но не промежуточные сертификаты CA. Для этого режима требуется действительный 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_ALLOW_PROXY_CERTS -
Возможное значение для
SSLContext.verify_flags, включающее проверку прокси-сертификатов.Добавлено в версии 3.10.
-
ssl.VERIFY_X509_TRUSTED_FIRST -
Возможное значение для
SSLContext.verify_flags. Оно указывает OpenSSL предпочитать доверенные сертификаты при построении цепочки доверия для проверки сертификата. Этот флаг включен по умолчанию.Добавлено в версии 3.4.4.
-
ssl.VERIFY_X509_PARTIAL_CHAIN -
Возможное значение для
SSLContext.verify_flags. Оно указывает OpenSSL считать промежуточные CA в хранилище доверенных сертификатов якорями доверия так же, как самоподписанные корневые сертификаты CA. Это позволяет доверять сертификатам, выданным промежуточным CA, не доверяя его родительскому корневому CA.Добавлено в версии 3.10.
-
class ssl.VerifyFlags -
Коллекция
enum.IntFlagконстант VERIFY_*.Добавлено в версии 3.6.
-
ssl.PROTOCOL_TLS -
Выбирает наивысшую версию протокола, поддерживаемую и клиентом, и сервером. Несмотря на название, этот параметр может выбрать протоколы как «SSL», так и «TLS».
Добавлено в версии 3.6.
Устарело с версии 3.10: Для безопасного обмена данными клиентам и серверам TLS требуются разные настройки по умолчанию. Универсальная константа протокола TLS устарела; вместо нее используйте
PROTOCOL_TLS_CLIENTиPROTOCOL_TLS_SERVER.
-
ssl.PROTOCOL_TLS_CLIENT -
Автоматически согласовывает наивысшую версию протокола, поддерживаемую и клиентом, и сервером, и настраивает контекст для соединений на стороне клиента. Этот протокол по умолчанию включает
CERT_REQUIREDиcheck_hostname.Добавлено в версии 3.6.
-
ssl.PROTOCOL_TLS_SERVER -
Автоматически согласовывает наивысшую версию протокола, поддерживаемую и клиентом, и сервером, и настраивает контекст для соединений на стороне сервера.
Добавлено в версии 3.6.
-
ssl.PROTOCOL_SSLv23 -
Псевдоним для
PROTOCOL_TLS.Устарело с версии 3.6: Вместо этого используйте
PROTOCOL_TLS.
-
ssl.PROTOCOL_SSLv3 -
Выбирает SSL версии 3 в качестве протокола шифрования канала.
Этот протокол недоступен, если OpenSSL скомпилирован с параметром
no-ssl3.Предупреждение
SSL версии 3 небезопасен. Настоятельно не рекомендуется его использовать.
Устарело с версии 3.6: OpenSSL объявил устаревшими все протоколы для конкретных версий. Вместо этого используйте протокол по умолчанию
PROTOCOL_TLS_SERVERилиPROTOCOL_TLS_CLIENTс параметрамиSSLContext.minimum_versionиSSLContext.maximum_version.
-
ssl.PROTOCOL_TLSv1 -
Выбирает TLS версии 1.0 в качестве протокола шифрования канала.
Устарело с версии 3.6: OpenSSL объявил устаревшими все протоколы для конкретных версий.
-
ssl.PROTOCOL_TLSv1_1 -
Выбирает TLS версии 1.1 в качестве протокола шифрования канала. Доступно только в OpenSSL версии 1.0.1 и выше.
Добавлено в версии 3.4.
Устарело с версии 3.6: OpenSSL объявил устаревшими все протоколы для конкретных версий.
-
ssl.PROTOCOL_TLSv1_2 -
Выбирает TLS версии 1.2 в качестве протокола шифрования канала. Доступно только в OpenSSL версии 1.0.1 и выше.
Добавлено в версии 3.4.
Устарело с версии 3.6: OpenSSL объявил устаревшими все протоколы для конкретных версий.
-
ssl.OP_ALL -
Включает обходные решения для различных ошибок в других реализациях SSL. Этот параметр установлен по умолчанию. Он не обязательно задает те же флаги, что и константа
SSL_OP_ALLв OpenSSL.Добавлено в версии 3.2.
-
ssl.OP_NO_SSLv2 -
Запрещает соединение SSLv2. Этот параметр применим только вместе с
PROTOCOL_TLS. Он не позволяет узлам соединения выбрать SSLv2 в качестве версии протокола.Добавлено в версии 3.2.
Устарело с версии 3.6: SSLv2 устарел
-
ssl.OP_NO_SSLv3 -
Запрещает соединение SSLv3. Этот параметр применим только вместе с
PROTOCOL_TLS. Он не позволяет узлам соединения выбрать SSLv3 в качестве версии протокола.Добавлено в версии 3.2.
Устарело с версии 3.6: SSLv3 устарел
-
ssl.OP_NO_TLSv1 -
Запрещает соединение TLSv1. Этот параметр применим только вместе с
PROTOCOL_TLS. Он не позволяет узлам соединения выбрать TLSv1 в качестве версии протокола.Добавлено в версии 3.2.
Устарело с версии 3.7: Этот параметр устарел начиная с OpenSSL 1.1.0; вместо него используйте новые параметры
SSLContext.minimum_versionиSSLContext.maximum_version.
-
ssl.OP_NO_TLSv1_1 -
Запрещает соединение TLSv1.1. Этот параметр применим только вместе с
PROTOCOL_TLS. Он не позволяет узлам соединения выбрать TLSv1.1 в качестве версии протокола. Доступно только в OpenSSL версии 1.0.1 и выше.Добавлено в версии 3.4.
Устарело с версии 3.7: Этот параметр устарел начиная с OpenSSL 1.1.0.
-
ssl.OP_NO_TLSv1_2 -
Запрещает соединение TLSv1.2. Этот параметр применим только вместе с
PROTOCOL_TLS. Он не позволяет узлам соединения выбрать TLSv1.2 в качестве версии протокола. Доступно только в OpenSSL версии 1.0.1 и выше.Добавлено в версии 3.4.
Устарело с версии 3.7: Этот параметр устарел начиная с OpenSSL 1.1.0.
-
ssl.OP_NO_TLSv1_3 -
Запрещает соединение TLSv1.3. Этот параметр применим только вместе с
PROTOCOL_TLS. Он не позволяет узлам соединения выбрать TLSv1.3 в качестве версии протокола. TLS 1.3 доступен в OpenSSL 1.1.1 и более поздних версиях. Если Python скомпилирован с более старой версией OpenSSL, значение флага по умолчанию равно 0.Добавлено в версии 3.6.3.
Устарело с версии 3.7: Этот параметр устарел начиная с OpenSSL 1.1.0. Он был добавлен в версии 2.7.15 и 3.6.3 для обратной совместимости с OpenSSL 1.0.2.
-
ssl.OP_NO_RENEGOTIATION -
Отключает повторное согласование для TLSv1.2 и более ранних версий. Не отправляет сообщения HelloRequest и игнорирует запросы на повторное согласование через ClientHello.
Этот параметр доступен только в OpenSSL 1.1.0h и более поздних версиях.
Добавлено в версии 3.7.
-
ssl.OP_CIPHER_SERVER_PREFERENCE -
Использует порядок шифров, предпочтительный для сервера, а не для клиента. Этот параметр не влияет на клиентские сокеты и серверные сокеты SSLv2.
Добавлено в версии 3.3.
-
ssl.OP_SINGLE_DH_USE -
Запрещает повторное использование одного и того же ключа DH в разных сеансах SSL. Это повышает прямую секретность, но требует больших вычислительных ресурсов. Этот параметр применяется только к серверным сокетам.
Добавлено в версии 3.3.
-
ssl.OP_SINGLE_ECDH_USE -
Запрещает повторное использование одного и того же ключа ECDH в разных сеансах SSL. Это повышает прямую секретность, но требует больших вычислительных ресурсов. Этот параметр применяется только к серверным сокетам.
Добавлено в версии 3.3.
-
ssl.OP_ENABLE_MIDDLEBOX_COMPAT -
Отправляет фиктивные сообщения Change Cipher Spec (CCS) во время рукопожатия TLS 1.3, чтобы соединение TLS 1.3 было больше похоже на соединение TLS 1.2.
Этот параметр доступен только в OpenSSL 1.1.1 и более поздних версиях.
Добавлено в версии 3.8.
-
ssl.OP_NO_COMPRESSION -
Отключает сжатие в канале SSL. Это полезно, если протокол приложения поддерживает собственную схему сжатия.
Добавлено в версии 3.3.
-
class ssl.Options -
Коллекция
enum.IntFlagконстант OP_*.
-
ssl.OP_NO_TICKET -
Запрещает клиенту запрашивать билет сеанса.
Добавлено в версии 3.6.
-
ssl.OP_IGNORE_UNEXPECTED_EOF -
Игнорирует неожиданное завершение TLS-соединений.
Этот параметр доступен только в OpenSSL 3.0.0 и более поздних версиях.
Добавлено в версии 3.10.
-
ssl.OP_ENABLE_KTLS -
Включает использование TLS в ядре. Чтобы воспользоваться этой функцией, OpenSSL должен быть скомпилирован с ее поддержкой, а согласованные наборы шифров и расширения должны поддерживаться ею (список поддерживаемых элементов может различаться в зависимости от платформы и версии ядра).
Обратите внимание, что при включенном TLS в ядре некоторые криптографические операции выполняются непосредственно ядром, а не через доступные провайдеры OpenSSL. Это может быть нежелательно, например, если приложение требует выполнять все криптографические операции с помощью провайдера FIPS.
Этот параметр доступен только в OpenSSL 3.0.0 и более поздних версиях.
Добавлено в версии 3.12.
-
ssl.OP_LEGACY_SERVER_CONNECT -
Разрешает небезопасное повторное согласование между OpenSSL и только неподготовленными серверами.
Добавлено в версии 3.12.
-
ssl.HAS_ALPN -
Указывает, имеет ли библиотека OpenSSL встроенную поддержку расширения TLS согласование протокола на уровне приложения, описанного в RFC 7301.
Добавлено в версии 3.5.
-
ssl.HAS_NEVER_CHECK_COMMON_NAME -
Указывает, имеет ли библиотека OpenSSL встроенную поддержку отключения проверки общего имени субъекта и доступна ли для записи настройка
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 встроенную поддержку согласования следующего протокола, описанного в разделе согласование протокола на уровне приложения. Если значение истинно, для объявления поддерживаемых протоколов можно использовать метод
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 и других документов. Реестр предупреждений TLS IANA содержит этот список и ссылки на RFC, в которых определено значение предупреждений.
Используется как возвращаемое значение функции обратного вызова в
SSLContext.set_servername_callback().Добавлено в версии 3.4.
-
class ssl.AlertDescription -
Коллекция
enum.IntEnumконстант ALERT_DESCRIPTION_*.Добавлено в версии 3.6.
-
Purpose.SERVER_AUTH -
Параметр для
create_default_context()иSSLContext.load_default_certs(). Это значение указывает, что контекст может использоваться для аутентификации веб-серверов (следовательно, он будет применяться для создания сокетов на стороне клиента).Добавлено в версии 3.4.
-
Purpose.CLIENT_AUTH -
Параметр для
create_default_context()иSSLContext.load_default_certs(). Это значение указывает, что контекст может использоваться для аутентификации веб-клиентов (следовательно, он будет использоваться для создания сокетов на стороне сервера).Добавлено в версии 3.4.
-
class ssl.SSLErrorNumber -
Коллекция
enum.IntEnumконстант SSL_ERROR_*.Добавлено в версии 3.6.
-
class ssl.TLSVersion -
Коллекция
enum.IntEnumверсий SSL и TLS дляSSLContext.maximum_versionиSSLContext.minimum_version.Добавлено в версии 3.7.
-
TLSVersion.MINIMUM_SUPPORTED
-
TLSVersion.MAXIMUM_SUPPORTED -
Минимальная или максимальная поддерживаемая версия SSL или TLS. Это магические константы. Их значения не отражают самую низкую и самую высокую доступные версии TLS/SSL.
-
TLSVersion.SSLv3
-
TLSVersion.TLSv1
-
TLSVersion.TLSv1_1
-
TLSVersion.TLSv1_2
-
TLSVersion.TLSv1_3 -
От SSL 3.0 до TLS 1.3.
Устарело с версии 3.10: Все элементы
TLSVersion, кромеTLSVersion.TLSv1_2иTLSVersion.TLSv1_3, устарели.
SSL-сокеты
-
class ssl.SSLSocket(socket.socket) -
SSL-сокеты предоставляют следующие методы объекта Socket Objects:
accept()bind()close()connect()detach()fileno()-
getpeername(),getsockname() -
getsockopt(),setsockopt() -
gettimeout(),settimeout(),setblocking() listen()makefile()-
recv(),recv_into()(однако передавать ненулевой аргументflagsнельзя) -
send(),sendall()(с тем же ограничением) -
sendfile()(однакоos.sendfileиспользуется только для незашифрованных сокетов, в противном случае используетсяsend()) shutdown()
Однако, поскольку протокол SSL (и TLS) использует собственное кадрирование поверх TCP, абстракция SSL-сокетов в некоторых отношениях может отличаться от спецификации обычных сокетов на уровне ОС. См. в частности примечания о неблокирующих сокетах.
Экземпляры
SSLSocketнеобходимо создавать с помощью методаSSLContext.wrap_socket().Изменено в версии 3.5: Добавлен метод
sendfile().Изменено в версии 3.5:
shutdown()больше не сбрасывает время ожидания сокета при каждом получении или отправке байтов. Теперь время ожидания сокета представляет собой максимальную общую продолжительность завершения работы.Устарело с версии 3.6: Создание экземпляра
SSLSocketнапрямую устарело; используйтеSSLContext.wrap_socket(), чтобы обернуть сокет.Изменено в версии 3.7: Экземпляры
SSLSocketнеобходимо создавать с помощьюwrap_socket(). В предыдущих версиях экземпляры можно было создавать напрямую. Это никогда не было задокументировано или официально поддержано.Изменено в версии 3.10: Теперь Python использует внутри
SSL_read_exиSSL_write_ex. Функции поддерживают чтение и запись данных размером более 2 ГБ. Запись данных нулевой длины больше не завершается ошибкой нарушения протокола.
У SSL-сокетов также есть следующие дополнительные методы и атрибуты:
-
SSLSocket.read(len=1024, buffer=None) -
Считывает до len байтов данных из SSL-сокета и возвращает результат в виде экземпляра
bytes. Если указан параметр buffer, данные считываются в буфер, а возвращается количество считанных байтов.Вызывает
SSLWantReadErrorилиSSLWantWriteError, если сокет неблокирующий и операция чтения должна была бы блокироваться.Поскольку повторное согласование может произойти в любой момент, вызов
read()также может вызвать операции записи.Изменено в версии 3.5: Время ожидания сокета больше не сбрасывается при каждом получении или отправке байтов. Теперь оно представляет собой максимальную общую продолжительность чтения до len байтов.
Устарело с версии 3.6: Используйте
recv()вместоread().
-
SSLSocket.write(buf) -
Записывает buf в SSL-сокет и возвращает количество записанных байтов. Аргумент buf должен быть объектом, поддерживающим интерфейс буфера.
Вызывает
SSLWantReadErrorилиSSLWantWriteError, если сокет неблокирующий и операция записи должна была бы блокироваться.Поскольку повторное согласование может произойти в любой момент, вызов
write()также может вызвать операции чтения.Изменено в версии 3.5: Время ожидания сокета больше не сбрасывается при каждом получении или отправке байтов. Теперь оно представляет собой максимальную общую продолжительность записи buf.
Устарело с версии 3.6: Используйте
send()вместоwrite().
Примечание
Методы read() и write() — низкоуровневые методы, которые читают и записывают незашифрованные данные на уровне приложения и расшифровывают/зашифровывают их в данные на уровне передачи. Для работы этих методов требуется активное SSL-соединение: рукопожатие должно быть завершено, а SSLSocket.unwrap() не должен быть вызван.
Обычно вместо этих методов следует использовать методы API сокетов, например recv() и send().
-
SSLSocket.do_handshake() -
Выполняет установочное SSL-рукопожатие.
Изменено в версии 3.4: Метод рукопожатия также выполняет
match_hostname(), если атрибутcheck_hostnameобъектаcontext, связанного с сокетом, имеет значение true.Изменено в версии 3.5: Время ожидания сокета больше не сбрасывается при каждом получении или отправке байтов. Теперь оно представляет собой максимальную общую продолжительность рукопожатия.
Изменено в версии 3.7: OpenSSL сопоставляет имя хоста или IP-адрес во время рукопожатия. Функция
match_hostname()больше не используется. Если OpenSSL отклоняет имя хоста или IP-адрес, рукопожатие досрочно прерывается, а другой стороне отправляется TLS-сообщение-предупреждение.
-
SSLSocket.getpeercert(binary_form=False) -
Если у другой стороны соединения нет сертификата, возвращает
None. Если SSL-рукопожатие ещё не выполнено, вызываетValueError.Если параметр
binary_formимеет значениеFalseи от другой стороны получен сертификат, этот метод возвращает экземплярdict. Если сертификат не прошёл проверку, словарь пуст. Если сертификат прошёл проверку, возвращается словарь с несколькими ключами, среди которыхsubject(субъект, которому выдан сертификат) иissuer(субъект, выдавший сертификат). Если сертификат содержит расширение Subject Alternative Name (см. RFC 3280), в словаре также будет ключsubjectAltName.Поля
subjectиissuer— кортежи, содержащие последовательности относительных различительных имён (RDN), указанные в структуре данных сертификата для соответствующих полей; каждый RDN представляет собой последовательность пар «имя-значение». Вот пример из реальной жизни:{'issuer': ((('countryName', 'IL'),), (('organizationName', 'StartCom Ltd.'),), (('organizationalUnitName', 'Secure Digital Certificate Signing'),), (('commonName', 'StartCom Class 2 Primary Intermediate Server CA'),)), 'notAfter': 'Nov 22 08:15:19 2013 GMT', 'notBefore': 'Nov 21 03:09:52 2011 GMT', 'serialNumber': '95F0', 'subject': ((('description', '571208-SLe257oHY9fVQ07Z'),), (('countryName', 'US'),), (('stateOrProvinceName', 'California'),), (('localityName', 'San Francisco'),), (('organizationName', 'Electronic Frontier Foundation, Inc.'),), (('commonName', '*.eff.org'),), (('emailAddress', 'hostmaster@eff.org'),)), 'subjectAltName': (('DNS', '*.eff.org'), ('DNS', 'eff.org')), 'version': 3}Если параметр
binary_formимеет значениеTrueи сертификат предоставлен, этот метод возвращает DER-кодированную форму всего сертификата в виде последовательности байтов илиNone, если другая сторона не предоставила сертификат. Предоставление сертификата другой стороной зависит от роли SSL-сокета:- для клиентского SSL-сокета сервер всегда предоставляет сертификат независимо от того, требовалась ли проверка;
- для серверного SSL-сокета клиент предоставляет сертификат только по запросу сервера; поэтому
getpeercert()вернётNone, если использовалосьCERT_NONE(а неCERT_OPTIONALилиCERT_REQUIRED).
См. также
SSLContext.check_hostname.Изменено в версии 3.2: Возвращаемый словарь содержит дополнительные элементы, такие как
issuerиnotBefore.Изменено в версии 3.4: Если рукопожатие не выполнено, вызывается
ValueError. Возвращаемый словарь содержит дополнительные элементы расширений X509v3, такие какcrlDistributionPoints,caIssuersи URIOCSP.Изменено в версии 3.9: В строках с IPv6-адресами больше нет завершающего символа новой строки.
-
SSLSocket.cipher() -
Возвращает кортеж из трёх значений: название используемого шифра, версию протокола SSL, определяющую его использование, и количество используемых секретных битов. Если соединение не установлено, возвращает
None.
-
Возвращает список шифров, доступных как клиенту, так и серверу. Каждый элемент возвращаемого списка — кортеж из трёх значений: название шифра, версия протокола SSL, определяющая его использование, и количество секретных битов, используемых шифром.
shared_ciphers()возвращаетNone, если соединение не установлено или сокет является клиентским.Добавлено в версии 3.5.
-
SSLSocket.compression() -
Возвращает строку с названием используемого алгоритма сжатия или
None, если соединение не сжато.Если протокол более высокого уровня поддерживает собственный механизм сжатия, можно использовать
OP_NO_COMPRESSION, чтобы отключить сжатие на уровне SSL.Добавлено в версии 3.3.
-
SSLSocket.get_channel_binding(cb_type='tls-unique') -
Возвращает данные привязки канала для текущего соединения в виде объекта bytes. Возвращает
None, если соединение не установлено или рукопожатие не завершено.Параметр cb_type позволяет выбрать нужный тип привязки канала. Допустимые типы привязки канала перечислены в списке
CHANNEL_BINDING_TYPES. В настоящее время поддерживается только привязка канала «tls-unique», определённая в RFC 5929. Если запрошен неподдерживаемый тип привязки канала, будет вызвано исключениеValueError.Добавлено в версии 3.3.
-
SSLSocket.selected_alpn_protocol() -
Возвращает протокол, выбранный во время TLS-рукопожатия. Если
SSLContext.set_alpn_protocols()не вызывался, другая сторона не поддерживает ALPN, этот сокет не поддерживает ни один из предложенных клиентом протоколов или рукопожатие ещё не произошло, возвращаетсяNone.Добавлено в версии 3.5.
-
SSLSocket.selected_npn_protocol() -
Возвращает протокол более высокого уровня, выбранный во время TLS/SSL-рукопожатия. Если
SSLContext.set_npn_protocols()не вызывался, другая сторона не поддерживает NPN или рукопожатие ещё не произошло, возвращаетсяNone.Добавлено в версии 3.3.
Устарело с версии 3.10: NPN вытеснен ALPN
-
SSLSocket.unwrap() -
Выполняет завершающее SSL-рукопожатие, которое удаляет уровень TLS из базового сокета, и возвращает объект базового сокета. Это можно использовать для перехода от зашифрованного обмена данными по соединению к незашифрованному. Для дальнейшего обмена данными с другой стороной соединения всегда следует использовать возвращённый сокет, а не исходный.
-
SSLSocket.verify_client_post_handshake() -
Запрашивает пострукопожатную аутентификацию (PHA) у клиента TLS 1.3. Инициировать PHA можно только для соединения TLS 1.3 с сокета на стороне сервера, после начального TLS-рукопожатия и при включённой PHA на обеих сторонах; см.
SSLContext.post_handshake_auth.Метод не выполняет обмен сертификатами немедленно. Сторона сервера отправляет CertificateRequest при следующей операции записи и ожидает, что клиент ответит сертификатом при следующей операции чтения.
Если какое-либо предварительное условие не выполнено (например, используется не TLS 1.3 или PHA не включена), вызывается исключение
SSLError.Примечание
Доступно только при использовании OpenSSL 1.1.1 и включённой поддержке TLS 1.3. Если поддержка TLS 1.3 отсутствует, метод вызывает
NotImplementedError.Добавлено в версии 3.8.
-
SSLSocket.version() -
Возвращает в виде строки фактическую версию протокола SSL, согласованную для соединения, или
None, если защищённое соединение не установлено. На момент написания возможные возвращаемые значения включают"SSLv2","SSLv3","TLSv1","TLSv1.1"и"TLSv1.2". В более новых версиях OpenSSL могут быть определены дополнительные возвращаемые значения.Добавлено в версии 3.5.
-
SSLSocket.pending() -
Возвращает количество уже расшифрованных байтов, ожидающих чтения из соединения.
-
SSLSocket.context -
Объект
SSLContext, с которым связан этот SSL-сокет.Добавлено в версии 3.2.
-
SSLSocket.server_side -
Логическое значение:
Trueдля сокетов на стороне сервера иFalseдля сокетов на стороне клиента.Добавлено в версии 3.2.
-
SSLSocket.server_hostname -
Имя хоста сервера: тип
strилиNoneдля серверного сокета либо если имя хоста не было указано в конструкторе.Добавлено в версии 3.2.
Изменено в версии 3.7: Теперь атрибут всегда содержит текст в кодировке ASCII. Если
server_hostname— интернационализированное доменное имя (IDN), в этом атрибуте теперь хранится форма A-label ("xn--pythn-mua.org"), а не форма U-label ("pythön.org").
-
SSLSocket.session -
Объект
SSLSessionдля этого SSL-соединения. Сеанс доступен для клиентских и серверных сокетов после выполнения TLS-рукопожатия. Для клиентских сокетов сеанс можно установить до вызоваdo_handshake(), чтобы повторно использовать сеанс.Добавлено в версии 3.6.
-
SSLSocket.session_reused -
Добавлено в версии 3.6.
Контексты SSL
Добавлено в версии 3.2.
Контекст SSL хранит различные данные, срок жизни которых превышает срок жизни отдельных SSL-соединений, например параметры конфигурации SSL, сертификаты и закрытые ключи. Он также управляет кэшем SSL-сеансов для сокетов на стороне сервера, чтобы ускорить повторные подключения тех же клиентов.
-
class ssl.SSLContext(protocol=None) -
Создаёт новый контекст SSL. Можно передать параметр protocol, который должен быть одной из констант
PROTOCOL_*, определённых в этом модуле. Параметр указывает, какую версию протокола SSL использовать. Как правило, сервер выбирает определённую версию протокола, а клиент должен подстроиться под выбор сервера. Большинство версий несовместимы друг с другом. Если параметр не указан, используется значение по умолчаниюPROTOCOL_TLS; оно обеспечивает наибольшую совместимость с другими версиями.В таблице показано, к каким версиям на сервере (по горизонтали) может подключиться клиент (по вертикали):
клиент / сервер
SSLv2
SSLv3
TLS [3]
TLSv1
TLSv1.1
TLSv1.2
SSLv2
да
нет
нет [1]
нет
нет
нет
SSLv3
нет
да
нет [2]
нет
нет
нет
TLS (SSLv23) [3]
нет [1]
нет [2]
да
да
да
да
TLSv1
нет
нет
да
да
нет
нет
TLSv1.1
нет
нет
да
нет
да
нет
TLSv1.2
нет
нет
да
нет
нет
да
Сноски
См. также
create_default_context()позволяет модулюsslвыбирать параметры безопасности для заданной цели.Изменено в версии 3.6: Контекст создаётся с безопасными значениями по умолчанию. По умолчанию устанавливаются параметры
OP_NO_COMPRESSION,OP_CIPHER_SERVER_PREFERENCE,OP_SINGLE_DH_USE,OP_SINGLE_ECDH_USE,OP_NO_SSLv2иOP_NO_SSLv3(за исключениемPROTOCOL_SSLv3). Изначальный список наборов шифров содержит только шифрыHIGH, без шифровNULLиMD5.Устарело с версии 3.10: Использование
SSLContextбез аргумента protocol устарело. В будущем для класса контекста потребуется протоколPROTOCOL_TLS_CLIENTилиPROTOCOL_TLS_SERVER.Изменено в версии 3.10: Теперь наборы шифров по умолчанию включают только безопасные шифры AES и ChaCha20 с прямой секретностью и уровнем безопасности 2. Ключи RSA и DH длиной менее 2048 бит и ключи ECC длиной менее 224 бит запрещены.
PROTOCOL_TLS,PROTOCOL_TLS_CLIENTиPROTOCOL_TLS_SERVERиспользуют TLS 1.2 в качестве минимальной версии TLS.Примечание
SSLContextдопускает лишь ограниченные изменения после того, как контекст был использован соединением. Добавлять новые сертификаты во внутреннее хранилище доверенных сертификатов разрешено, но изменение шифров, настроек проверки или сертификатов mTLS может привести к неожиданному поведению.Примечание
SSLContextпредназначен для совместного использования несколькими соединениями. Поэтому он потокобезопасен, если его не перенастраивать после использования соединением.
Объекты SSLContext имеют следующие методы и атрибуты:
-
SSLContext.cert_store_stats() -
Получает статистику о количестве загруженных сертификатов X.509, числе сертификатов X.509, помеченных как сертификаты CA, и списках отзыва сертификатов в виде словаря.
Пример для контекста с одним сертификатом CA и одним другим сертификатом:
>>> context.cert_store_stats() {'crl': 0, 'x509_ca': 1, 'x509': 2}Добавлено в версии 3.4.
-
SSLContext.load_cert_chain(certfile, keyfile=None, password=None) -
Загружает закрытый ключ и соответствующий ему сертификат. Строка certfile должна содержать путь к единственному файлу в формате PEM, в котором находятся сертификат и любое количество сертификатов CA, необходимых для подтверждения подлинности сертификата. Строка keyfile, если она указана, должна содержать путь к файлу с закрытым ключом. В противном случае закрытый ключ также будет взят из certfile. Дополнительную информацию о хранении сертификата в файле certfile см. в разделе Сертификаты.
Аргумент password может быть функцией, вызываемой для получения пароля, необходимого для расшифровки закрытого ключа. Она будет вызвана, только если закрытый ключ зашифрован и требуется пароль. Функция вызывается без аргументов и должна возвращать строку, bytes или bytearray. Если возвращаемое значение является строкой, перед использованием для расшифровки ключа оно будет закодировано в UTF-8. Также непосредственно в качестве аргумента password можно передать значение типа string, bytes или bytearray. Оно игнорируется, если закрытый ключ не зашифрован и пароль не нужен.
Если аргумент password не указан, а пароль необходим, для интерактивного запроса пароля будет использоваться встроенный механизм OpenSSL.
Если закрытый ключ не соответствует сертификату, возбуждается исключение
SSLError.Изменено в версии 3.3: Добавлен новый необязательный аргумент password.
-
SSLContext.load_default_certs(purpose=Purpose.SERVER_AUTH) -
Загружает набор сертификатов удостоверяющих центров (CA) по умолчанию из стандартных расположений. В Windows сертификаты CA загружаются из системных хранилищ
CAиROOT. Во всех системах вызываетсяSSLContext.set_default_verify_paths(). В будущем метод может загружать сертификаты CA и из других расположений.Флаг purpose задаёт тип загружаемых сертификатов CA. Настройка по умолчанию
Purpose.SERVER_AUTHзагружает сертификаты, помеченные как доверенные для аутентификации веб-сервера TLS (сокеты на стороне клиента).Purpose.CLIENT_AUTHзагружает сертификаты CA для проверки сертификатов клиента на стороне сервера.Добавлено в версии 3.4.
-
SSLContext.load_verify_locations(cafile=None, capath=None, cadata=None) -
Загружает набор сертификатов удостоверяющих центров (CA), используемых для проверки сертификатов других сторон, если
verify_modeимеет значение, отличное отCERT_NONE. Необходимо указать хотя бы один из параметров: cafile или capath.Этот метод также может загружать списки отзыва сертификатов (CRL) в формате PEM или DER. Чтобы использовать CRL, необходимо правильно настроить
SSLContext.verify_flags.Строка cafile, если она указана, представляет собой путь к файлу с объединёнными сертификатами CA в формате PEM. Дополнительную информацию о размещении сертификатов в этом файле см. в разделе Сертификаты.
Строка capath, если она указана, представляет собой путь к каталогу с несколькими сертификатами CA в формате PEM, расположенными в соответствии со специальной структурой каталогов OpenSSL.
Объект cadata, если он указан, представляет собой либо строку ASCII с одним или несколькими сертификатами в формате PEM, либо объект, подобный bytes, содержащий сертификаты в формате DER. Как и в случае с capath, дополнительные строки вокруг сертификатов в формате PEM игнорируются, но должен присутствовать хотя бы один сертификат.
Изменено в версии 3.4: Добавлен новый необязательный аргумент cadata.
-
SSLContext.get_ca_certs(binary_form=False) -
Получает список загруженных сертификатов удостоверяющих центров (CA). Если параметр
binary_formимеет значениеFalse, каждый элемент списка представляет собой словарь, аналогичный результату вызоваSSLSocket.getpeercert(). В противном случае метод возвращает список сертификатов в формате DER. Возвращаемый список не содержит сертификаты из capath, если только сертификат не был запрошен и загружен SSL-соединением.Примечание
Сертификаты из каталога capath не загружаются, пока не будут использованы хотя бы один раз.
Добавлено в версии 3.4.
-
SSLContext.get_ciphers() -
Получает список включённых шифров. Список упорядочен по приоритету шифров. См.
SSLContext.set_ciphers().Пример:
>>> ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23) >>> ctx.set_ciphers('ECDHE+AESGCM:!ECDSA') >>> ctx.get_ciphers() [{'aead': True, 'alg_bits': 256, 'auth': 'auth-rsa', 'description': 'ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=RSA ' 'Enc=AESGCM(256) Mac=AEAD', 'digest': None, 'id': 50380848, 'kea': 'kx-ecdhe', 'name': 'ECDHE-RSA-AES256-GCM-SHA384', 'protocol': 'TLSv1.2', 'strength_bits': 256, 'symmetric': 'aes-256-gcm'}, {'aead': True, 'alg_bits': 128, 'auth': 'auth-rsa', 'description': 'ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=RSA ' 'Enc=AESGCM(128) Mac=AEAD', 'digest': None, 'id': 50380847, 'kea': 'kx-ecdhe', 'name': 'ECDHE-RSA-AES128-GCM-SHA256', 'protocol': 'TLSv1.2', 'strength_bits': 128, 'symmetric': 'aes-128-gcm'}]Добавлено в версии 3.6.
-
SSLContext.set_default_verify_paths() -
Загружает набор сертификатов удостоверяющих центров (CA) по умолчанию из пути файловой системы, заданного при сборке библиотеки OpenSSL. К сожалению, нельзя легко определить, успешно ли отработал этот метод: если сертификаты не найдены, ошибка не возвращается. Однако, когда библиотека OpenSSL поставляется в составе операционной системы, она, скорее всего, настроена правильно.
-
SSLContext.set_ciphers(ciphers) -
Задаёт доступные шифры для сокетов, созданных с этим контекстом. Значение должно быть строкой в формате списка шифров OpenSSL. Если ни один шифр не может быть выбран (поскольку параметры компиляции или другая конфигурация запрещают использование всех заданных шифров), будет возбуждено исключение
SSLError.Примечание
После установления соединения метод
SSLSocket.cipher()SSL-сокетов возвращает выбранный в данный момент шифр.Наборы шифров TLS 1.3 нельзя отключить с помощью
set_ciphers().
-
SSLContext.set_alpn_protocols(protocols) -
Указывает протоколы, которые сокет должен объявить во время рукопожатия SSL/TLS. Это должен быть список строк ASCII, например
['http/1.1', 'spdy/2'], упорядоченный по предпочтительности. Выбор протокола выполняется во время рукопожатия в соответствии с RFC 7301. После успешного рукопожатия методSSLSocket.selected_alpn_protocol()возвращает согласованный протокол.Если
HAS_ALPNимеет значениеFalse, этот метод возбуждает исключениеNotImplementedError.Добавлено в версии 3.5.
-
SSLContext.set_npn_protocols(protocols) -
Указывает протоколы, которые сокет должен объявить во время рукопожатия SSL/TLS. Это должен быть список строк, например
['http/1.1', 'spdy/2'], упорядоченный по предпочтительности. Выбор протокола выполняется во время рукопожатия в соответствии с согласованием протокола прикладного уровня. После успешного рукопожатия методSSLSocket.selected_npn_protocol()возвращает согласованный протокол.Если
HAS_NPNимеет значениеFalse, этот метод возбуждает исключениеNotImplementedError.Добавлено в версии 3.3.
Устарело с версии 3.10: NPN вытеснен ALPN
-
SSLContext.sni_callback -
Регистрирует функцию обратного вызова, которая будет вызвана после получения сервером SSL/TLS сообщения рукопожатия TLS Client Hello, если клиент TLS указывает расширение SNI (индикацию имени сервера). Механизм индикации имени сервера определён в RFC 6066, раздел 3 — Server Name Indication.
Для каждого
SSLContextможно задать только один обработчик. Если для sni_callback задано значениеNone, обработчик отключается. Повторный вызов этой функции отключает ранее зарегистрированный обработчик.Функция обратного вызова вызывается с тремя аргументами: первый — это
ssl.SSLSocket, второй — строка с именем сервера, с которым намерен связаться клиент (илиNone, если в TLS Client Hello имя сервера отсутствует), а третий аргумент — исходныйSSLContext. Аргумент с именем сервера является текстом. Для интернационализированного доменного имени имя сервера представляет собой IDN A-label ("xn--pythn-mua.org").Типичное применение этого обработчика — изменение атрибута
SSLSocket.contextобъектаssl.SSLSocketна новый объект типаSSLContext, представляющий цепочку сертификатов, соответствующую имени сервера.Из-за ранней стадии согласования TLS-соединения доступны только ограниченный набор методов и атрибутов, например
SSLSocket.selected_alpn_protocol()иSSLSocket.context. Для работы методовSSLSocket.getpeercert(),SSLSocket.cipher()иSSLSocket.compression()необходимо, чтобы TLS-соединение продвинулось дальше этапа TLS Client Hello. Поэтому они не возвращают осмысленных значений и их нельзя безопасно вызывать.Функция sni_callback должна возвращать
None, чтобы разрешить продолжение согласования TLS. Если необходимо прервать TLS-соединение, можно вернуть константуALERT_DESCRIPTION_*. Любые другие возвращаемые значения приведут к фатальной ошибке TLS с кодомALERT_DESCRIPTION_INTERNAL_ERROR.Если функция sni_callback возбуждает исключение, TLS-соединение будет завершено с фатальным сообщением-оповещением TLS
ALERT_DESCRIPTION_HANDSHAKE_FAILURE.Если при сборке библиотеки OpenSSL была определена константа OPENSSL_NO_TLSEXT, этот метод возбуждает исключение
NotImplementedError.Добавлено в версии 3.7.
-
SSLContext.set_servername_callback(server_name_callback) -
Это устаревший API, сохранённый для обратной совместимости. По возможности следует использовать
sni_callback. Указанный server_name_callback похож на sni_callback, однако, если имя хоста сервера является доменным именем в кодировке IDN, server_name_callback получает декодированную U-label ("pythön.org").Если при декодировании имени сервера возникает ошибка, TLS-соединение завершится фатальным сообщением-оповещением TLS
ALERT_DESCRIPTION_INTERNAL_ERROR, отправленным клиенту.Добавлено в версии 3.4.
-
SSLContext.load_dh_params(dhfile) -
Загружает параметры генерации ключей для обмена ключами Диффи — Хеллмана (DH). Использование обмена ключами DH повышает прямую секретность за счёт вычислительных ресурсов (как на сервере, так и на клиенте). Параметр dhfile должен содержать путь к файлу с параметрами DH в формате PEM.
Эта настройка не применяется к клиентским сокетам. Для дополнительного повышения безопасности также можно использовать параметр
OP_SINGLE_DH_USE.Добавлено в версии 3.3.
-
SSLContext.set_ecdh_curve(curve_name) -
Задаёт имя кривой для обмена ключами на основе эллиптических кривых Диффи — Хеллмана (ECDH). ECDH значительно быстрее обычного DH и при этом, вероятно, столь же безопасен. Параметр curve_name должен быть строкой с названием известной эллиптической кривой, например
prime256v1— широко поддерживаемой кривой.Эта настройка не применяется к клиентским сокетам. Для дополнительного повышения безопасности также можно использовать параметр
OP_SINGLE_ECDH_USE.Этот метод недоступен, если
HAS_ECDHимеет значениеFalse.Добавлено в версии 3.3.
См. также
- SSL/TLS и совершенная прямая секретность
-
Винсент Берна.
-
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_side имеет значение true, указание server_hostname вызовет исключение
ValueError.Параметр
do_handshake_on_connectуказывает, следует ли выполнять SSL-рукопожатие автоматически после выполненияsocket.connect()или приложение вызовет его явно, используя методSSLSocket.do_handshake(). Явный вызовSSLSocket.do_handshake()позволяет программе управлять блокирующим поведением операций ввода-вывода сокета, участвующих в рукопожатии.Параметр
suppress_ragged_eofsзадаёт, как методSSLSocket.recv()должен сообщать о неожиданном EOF на другом конце соединения. Если указаноTrue(значение по умолчанию), в ответ на ошибки неожиданного EOF, вызванные базовым сокетом, возвращается обычный EOF (пустой объект bytes); если указаноFalse, исключения передаются вызывающему коду.session — см.
session.Чтобы обернуть
SSLSocketв другойSSLSocket, используйтеSSLContext.wrap_bio().Изменено в версии 3.5: Теперь параметр server_hostname можно передавать всегда, даже если OpenSSL не поддерживает SNI.
Изменено в версии 3.6: Добавлен аргумент session.
Изменено в версии 3.7: Метод возвращает экземпляр
SSLContext.sslsocket_class, а не экземпляр фиксированного типаSSLSocket.
-
SSLContext.sslsocket_class -
Тип возвращаемого значения
SSLContext.wrap_socket(); по умолчаниюSSLSocket. Атрибут можно переопределить для экземпляра класса, чтобы возвращать пользовательский подкласс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 -
Следует ли проверять соответствие имени узла сертификата узла-собеседника в
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.
-
SSLContext.keylog_filename -
Записывает ключи TLS в файл журнала ключей при каждом создании или получении ключевого материала. Файл журнала ключей предназначен только для отладки. Формат файла определён NSS и используется многими анализаторами трафика, например Wireshark. Файл журнала открывается только для добавления данных. Запись синхронизирована между потоками, но не между процессами.
Добавлено в версии 3.8.
-
SSLContext.maximum_version -
Элемент перечисления
TLSVersion, представляющий наивысшую поддерживаемую версию TLS. По умолчанию установлено значениеTLSVersion.MAXIMUM_SUPPORTED. Для протоколов, отличных отPROTOCOL_TLS,PROTOCOL_TLS_CLIENTиPROTOCOL_TLS_SERVER, атрибут доступен только для чтения.Атрибуты
maximum_version,minimum_versionиSSLContext.optionsвлияют на поддерживаемые контекстом версии SSL и TLS. Реализация не предотвращает недопустимые сочетания. Например, контекст сOP_NO_TLSv1_2вoptionsиmaximum_version, установленным вTLSVersion.TLSv1_2, не сможет установить соединение TLS 1.2.Добавлено в версии 3.7.
-
SSLContext.minimum_version -
Аналогичен
SSLContext.maximum_version, но задаёт минимальную поддерживаемую версию илиTLSVersion.MINIMUM_SUPPORTED.Добавлено в версии 3.7.
-
SSLContext.num_tickets -
Управляет количеством билетов сеанса TLS 1.3 для контекста
PROTOCOL_TLS_SERVER. Эта настройка не влияет на соединения TLS 1.0–1.2.Добавлено в версии 3.8.
-
SSLContext.options -
Целое число, представляющее набор параметров SSL, включённых для этого контекста. Значение по умолчанию —
OP_ALL, но можно указать и другие параметры, напримерOP_NO_SSLv2, объединив их побитовой операцией ИЛИ.Изменено в версии 3.6:
SSLContext.optionsвозвращает флагиOptions:>>> ssl.create_default_context().options <Options.OP_ALL|OP_NO_SSLv3|OP_NO_SSLv2|OP_NO_COMPRESSION: 2197947391>
Устарело начиная с версии 3.7: Все параметры
OP_NO_SSL*иOP_NO_TLS*устарели начиная с Python 3.7. Вместо них используйтеSSLContext.minimum_versionиSSLContext.maximum_version.
-
SSLContext.post_handshake_auth -
Включает аутентификацию клиента TLS 1.3 после рукопожатия. По умолчанию такая аутентификация отключена, и сервер может запросить сертификат клиента TLS только во время начального рукопожатия. Если аутентификация включена, сервер может запросить сертификат клиента TLS в любое время после рукопожатия.
Если параметр включён для клиентских сокетов, клиент сообщает серверу о поддержке аутентификации после рукопожатия.
Если параметр включён для серверных сокетов, необходимо также установить
SSLContext.verify_modeвCERT_OPTIONALилиCERT_REQUIRED. Фактический обмен сертификатами клиента откладывается до вызоваSSLSocket.verify_client_post_handshake()и выполнения некоторых операций ввода-вывода.Добавлено в версии 3.8.
-
SSLContext.protocol -
Версия протокола, выбранная при создании контекста. Этот атрибут доступен только для чтения.
-
SSLContext.hostname_checks_common_name -
Следует ли при проверке
check_hostnameпроверять общее имя субъекта сертификата, если в нём отсутствует расширение альтернативного имени субъекта (по умолчанию: true).Добавлено в версии 3.7.
Изменено в версии 3.10: В OpenSSL до версии 1.1.1l этот флаг не действовал. В Python 3.8.9, 3.9.3 и 3.10 добавлены обходные решения для предыдущих версий.
-
SSLContext.security_level -
Целое число, представляющее уровень безопасности контекста. Этот атрибут доступен только для чтения.
Добавлено в версии 3.10.
-
SSLContext.verify_flags -
Флаги операций проверки сертификатов. Флаги, например
VERIFY_CRL_CHECK_LEAF, можно объединять побитовой операцией ИЛИ. По умолчанию OpenSSL не требует списки отозванных сертификатов (CRL) и не проверяет их.Добавлено в версии 3.4.
Изменено в версии 3.6:
SSLContext.verify_flagsвозвращает флагиVerifyFlags:>>> ssl.create_default_context().verify_flags <VerifyFlags.VERIFY_X509_TRUSTED_FIRST: 32768>
-
SSLContext.verify_mode -
Следует ли пытаться проверять сертификаты других узлов и как действовать в случае неудачной проверки. Этот атрибут должен иметь одно из значений:
CERT_NONE,CERT_OPTIONALилиCERT_REQUIRED.Изменено в версии 3.6:
SSLContext.verify_modeвозвращает перечислениеVerifyMode:>>> ssl.create_default_context().verify_mode <VerifyMode.CERT_REQUIRED: 2>
Сертификаты
Сертификаты, как правило, являются частью системы с открытым и закрытым ключами. В такой системе каждому субъекту (которым может быть компьютер, человек или организация) назначается уникальный двухчастный ключ шифрования. Одна часть ключа является общедоступной и называется открытым ключом; другая часть хранится в секрете и называется закрытым ключом. Эти части связаны: если зашифровать сообщение одной из них, расшифровать его можно другой, и только другой.
Сертификат содержит сведения о двух субъектах. В нём указаны имя субъекта и его открытый ключ. Также в нём содержится утверждение второго субъекта, издателя, о том, что субъект является тем, за кого себя выдаёт, и что это действительно его открытый ключ. Утверждение издателя подписывается его закрытым ключом, известным только ему. Однако любой может проверить утверждение издателя, получив его открытый ключ, расшифровав с его помощью утверждение и сравнив его с остальными сведениями сертификата. Сертификат также содержит сведения о периоде, в течение которого он действителен. Они представлены двумя полями — «notBefore» и «notAfter».
При использовании сертификатов в Python клиент или сервер может доказать свою личность с помощью сертификата. От другой стороны сетевого соединения также можно потребовать предоставить сертификат; этот сертификат можно проверить в соответствии с требованиями клиента или сервера, запросившего такую проверку. При неудачной проверке попытка подключения может вызвать исключение. Проверка выполняется автоматически базовой инфраструктурой OpenSSL; приложению не нужно заниматься её механизмами. Однако приложению обычно необходимо предоставить наборы сертификатов, чтобы этот процесс мог выполняться.
Python использует файлы для хранения сертификатов. Они должны быть в формате «PEM» (см. RFC 1422) — это представление в кодировке base64, заключённое между строкой заголовка и строкой окончания:
-----BEGIN CERTIFICATE----- ... (certificate in base64 PEM encoding) ... -----END CERTIFICATE-----
Цепочки сертификатов
Файлы Python с сертификатами могут содержать последовательность сертификатов, иногда называемую цепочкой сертификатов. Цепочка должна начинаться с сертификата субъекта, который является клиентом или сервером, затем следовать сертификат издателя этого сертификата, затем сертификат издателя того сертификата и так далее, пока не встретится сертификат с самоподписью, то есть сертификат, у которого совпадают субъект и издатель; такой сертификат иногда называют корневым сертификатом. Сертификаты следует просто объединить в файле сертификатов. Например, предположим, что у нас есть цепочка из трёх сертификатов: от сертификата нашего сервера к сертификату центра сертификации, подписавшего сертификат сервера, а затем к корневому сертификату организации, выдавшей сертификат центру сертификации:
-----BEGIN CERTIFICATE----- ... (certificate for your server)... -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- ... (the certificate for the CA)... -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- ... (the root certificate for the CA's issuer)... -----END CERTIFICATE-----
Сертификаты центров сертификации
Если требуется проверять сертификат другой стороны соединения, необходимо предоставить файл «сертификатов ЦС», содержащий цепочки сертификатов для каждого издателя, которому вы готовы доверять. И этот файл просто содержит объединённые цепочки. Для проверки Python использует первую найденную в файле цепочку, которая подходит. Файл сертификатов платформы можно использовать, вызвав SSLContext.load_default_certs(); это выполняется автоматически с помощью create_default_context().
Объединённый ключ и сертификат
Часто закрытый ключ хранится в том же файле, что и сертификат; в этом случае достаточно передать только параметр certfile в SSLContext.load_cert_chain(). Если закрытый ключ хранится вместе с сертификатом, он должен находиться перед первым сертификатом в цепочке:
-----BEGIN RSA PRIVATE KEY----- ... (private key in base64 encoding) ... -----END RSA PRIVATE KEY----- -----BEGIN CERTIFICATE----- ... (certificate in base64 PEM encoding) ... -----END CERTIFICATE-----
Самоподписанные сертификаты
Если вы собираетесь создать сервер, предоставляющий службы соединения с 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:
... # do something that requires SSL support
Работа на стороне клиента
В этом примере создаётся SSL-контекст с рекомендуемыми параметрами безопасности для клиентских сокетов, включая автоматическую проверку сертификатов:
>>> context = ssl.create_default_context()
Если вы предпочитаете настраивать параметры безопасности самостоятельно, можно создать контекст с нуля (однако будьте осторожны: настройки могут оказаться неверными):
>>> context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
>>> context.load_verify_locations("/etc/ssl/certs/ca-bundle.crt")
(в этом фрагменте предполагается, что операционная система хранит набор всех сертификатов ЦС в /etc/ssl/certs/ca-bundle.crt; если это не так, возникнет ошибка и расположение придётся изменить)
Протокол PROTOCOL_TLS_CLIENT настраивает контекст для проверки сертификатов и имён узлов. Для verify_mode устанавливается значение CERT_REQUIRED, а для check_hostname — True. Все остальные протоколы создают SSL-контексты с небезопасными настройками по умолчанию.
Когда вы используете контекст для подключения к серверу, CERT_REQUIRED и check_hostname проверяют сертификат сервера: проверяется, что сертификат сервера подписан одним из сертификатов ЦС, что подпись корректна, а также другие свойства, например срок действия и соответствие имени узла:
>>> 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.example.com', 10023))
bindsocket.listen(5)
Когда клиент подключится, вызовите для сокета accept(), чтобы получить новый сокет с другой стороны, и используйте метод контекста SSLContext.wrap_socket(), чтобы создать серверный SSL-сокет для соединения:
while True:
newsocket, fromaddr = bindsocket.accept()
connstream = context.wrap_socket(newsocket, server_side=True)
try:
deal_with_client(connstream)
finally:
connstream.shutdown(socket.SHUT_RDWR)
connstream.close()
Затем считывайте данные из connstream и выполняйте с ними необходимые действия, пока работа с клиентом не завершится (или пока клиент не завершит работу с вами):
def deal_with_client(connstream):
data = connstream.recv(1024)
# empty data means the client is finished with us
while data:
if not do_something(connstream, data):
# we'll assume do_something returns False
# when we're finished with client
break
data = connstream.recv(1024)
# finished with client
После этого вернитесь к ожиданию новых клиентских подключений (конечно, реальный сервер, вероятно, обрабатывал бы каждое клиентское соединение в отдельном потоке или переводил сокеты в неблокирующий режим и использовал цикл событий).
Примечания о неблокирующих сокетах
SSL-сокеты в неблокирующем режиме ведут себя немного иначе, чем обычные сокеты. Поэтому при работе с неблокирующими сокетами необходимо учитывать несколько особенностей:
-
Большинство методов
SSLSocketпри блокировке операции ввода-вывода вызовут исключениеSSLWantWriteErrorилиSSLWantReadErrorвместоBlockingIOError. ИсключениеSSLWantReadErrorбудет вызвано, если потребуется операция чтения из базового сокета, аSSLWantWriteError— если потребуется операция записи в базовый сокет. Обратите внимание: попытка записи в SSL-сокет может потребовать предварительного чтения из базового сокета, а попытка чтения из SSL-сокета может потребовать предварительной записи в базовый сокет.Изменено в версии 3.5: В более ранних версиях Python метод
SSLSocket.send()возвращал ноль вместо вызова исключенияSSLWantWriteErrorилиSSLWantReadError. - Вызов
select()сообщает, что сокет на уровне ОС готов к чтению (или записи), но это не означает, что на верхнем уровне SSL достаточно данных. Например, могла поступить только часть SSL-кадра. Поэтому будьте готовы обработать ошибкиSSLSocket.recv()иSSLSocket.send()и повторить попытку после следующего вызоваselect(). -
И наоборот, поскольку у уровня SSL есть собственное кадрирование, в SSL-сокете могут оставаться доступные для чтения данные, о которых
select()не знает. Поэтому сначала следует вызватьSSLSocket.recv(), чтобы считать все потенциально доступные данные, и только затем, если это всё ещё необходимо, блокировать выполнение вызовомselect().(Разумеется, аналогичные условия применяются при использовании других примитивов, таких как
poll()или примитивы из модуляselectors.) -
Само SSL-рукопожатие будет неблокирующим: метод
SSLSocket.do_handshake()нужно повторять, пока он не завершится успешно. Ниже приведён пример использованияselect()для ожидания готовности сокета:while True: try: sock.do_handshake() break except ssl.SSLWantReadError: select.select([sock], [], []) except ssl.SSLWantWriteError: select.select([], [sock], [])
См. также
Модуль asyncio поддерживает неблокирующие SSL-сокеты и предоставляет высокоуровневый API потоков. Он опрашивает события с помощью модуля selectors и обрабатывает исключения SSLWantWriteError, SSLWantReadError и BlockingIOError. Он также выполняет SSL-рукопожатие асинхронно.
Поддержка Memory BIO
Добавлено в версии 3.5.
С момента появления модуля SSL в Python 2.6 класс SSLSocket предоставляет две связанные, но отдельные группы возможностей:
- Обработка протокола SSL
- Сетевой ввод-вывод
API сетевого ввода-вывода идентичен API класса socket.socket, от которого также наследуется SSLSocket. Благодаря этому SSL-сокет можно использовать вместо обычного сокета без каких-либо дополнительных изменений, что позволяет легко добавить поддержку SSL в существующее приложение.
Совместное использование обработки протокола SSL и сетевого ввода-вывода обычно работает хорошо, но в некоторых случаях возникают проблемы. Например, асинхронные фреймворки ввода-вывода могут использовать другую модель мультиплексирования ввода-вывода, а не модель «select/poll для файлового дескриптора» (на основе готовности), предполагаемую классом socket.socket и внутренними процедурами OpenSSL для ввода-вывода через сокеты. Это особенно актуально для таких платформ, как Windows, где эта модель неэффективна. Для таких случаев предусмотрен вариант класса SSLSocket с ограниченным набором возможностей, называемый SSLObject.
-
class ssl.SSLObject -
Вариант класса
SSLSocketс ограниченным набором возможностей, представляющий экземпляр протокола SSL и не содержащий методов сетевого ввода-вывода. Обычно этот класс используют авторы фреймворков, которые хотят реализовать асинхронный ввод-вывод для SSL с помощью буферов в памяти.Этот класс реализует интерфейс поверх низкоуровневого объекта SSL, реализованного OpenSSL. Этот объект хранит состояние SSL-соединения, но сам не выполняет сетевой ввод-вывод. Ввод-вывод необходимо выполнять через отдельные объекты «BIO» — уровень абстракции ввода-вывода OpenSSL.
У этого класса нет публичного конструктора. Экземпляр
SSLObjectнеобходимо создать с помощью методаwrap_bio(). Этот метод создаст экземплярSSLObjectи свяжет его с парой BIO. Входящий BIO используется для передачи данных из Python экземпляру протокола SSL, а исходящий BIO — для передачи данных в обратном направлении.Доступны следующие методы:
contextserver_sideserver_hostnamesessionsession_reusedread()write()getpeercert()selected_alpn_protocol()selected_npn_protocol()cipher()shared_ciphers()compression()pending()do_handshake()verify_client_post_handshake()unwrap()get_channel_binding()version()
По сравнению с
SSLSocket, этому объекту недоступны следующие возможности:- Любой вид сетевого ввода-вывода;
recv()иsend()выполняют чтение и запись только в базовые буферыMemoryBIO. - Механизм do_handshake_on_connect отсутствует. Для начала рукопожатия всегда нужно вручную вызывать
do_handshake(). - Обработка suppress_ragged_eofs отсутствует. Все нарушения протокола, связанные с условием конца файла, сообщаются с помощью исключения
SSLEOFError. - В отличие от SSL-сокета, вызов метода
unwrap()ничего не возвращает: для SSL-сокета этот метод возвращает базовый сокет. - В качестве первого параметра обратный вызов server_name_callback, переданный в
SSLContext.set_servername_callback(), получит экземплярSSLObject, а не экземплярSSLSocket.
Некоторые примечания об использовании
SSLObject:- Весь ввод-вывод для
SSLObjectвыполняется в неблокирующем режиме. Это означает, например, чтоread()вызовет исключениеSSLWantReadError, если ему потребуется больше данных, чем доступно во входящем BIO.
Изменено в версии 3.7: Экземпляры
SSLObjectнеобходимо создавать с помощьюwrap_bio(). В более ранних версиях экземпляры можно было создавать напрямую. Эта возможность никогда не документировалась и официально не поддерживалась.
Объект SSLObject взаимодействует с внешним миром с помощью буферов в памяти. Класс MemoryBIO предоставляет буфер в памяти, который можно использовать для этой цели. Он является оболочкой для объекта OpenSSL memory BIO (базовый ввод-вывод):
-
class ssl.MemoryBIO -
Буфер в памяти, который можно использовать для передачи данных между Python и экземпляром протокола SSL.
-
pending -
Возвращает количество байтов, находящихся в данный момент в буфере памяти.
-
eof -
Логическое значение, указывающее, находится ли BIO в памяти в данный момент в позиции конца файла.
-
read(n=-1) -
Читает из буфера памяти не более n байтов. Если n не задано или отрицательно, возвращаются все байты.
-
write(buf) -
Записывает байты из buf в BIO в памяти. Аргумент buf должен быть объектом, поддерживающим протокол буфера.
Возвращаемое значение — количество записанных байтов, всегда равное длине buf.
-
Сеанс SSL
Добавлено в версии 3.6.
-
class ssl.SSLSession -
Объект сеанса, используемый методом
session.-
id
-
time
-
timeout
-
ticket_lifetime_hint
-
has_ticket
-
Вопросы безопасности
Рекомендуемые значения по умолчанию
Для использования на стороне клиента, если у вас нет особых требований к политике безопасности, настоятельно рекомендуется использовать функцию create_default_context() для создания SSL-контекста. Она загрузит доверенные сертификаты центров сертификации системы, включит проверку сертификатов и имени хоста, а также попытается выбрать достаточно безопасные настройки протокола и шифров.
Например, вот как с помощью класса smtplib.SMTP создать доверенное защищённое соединение с SMTP-сервером:
>>> import ssl, smtplib
>>> smtp = smtplib.SMTP("mail.python.org", port=587)
>>> context = ssl.create_default_context()
>>> smtp.starttls(context=context)
(220, b'2.0.0 Ready to start TLS')
Если для соединения требуется сертификат клиента, его можно добавить с помощью SSLContext.load_cert_chain().
В отличие от этого, если вы самостоятельно создадите SSL-контекст, вызвав конструктор SSLContext, проверка сертификатов и имени хоста по умолчанию включена не будет. Если вы решите поступить именно так, прочитайте приведённые ниже рекомендации, чтобы обеспечить надлежащий уровень безопасности.
Настройка вручную
Проверка сертификатов
При непосредственном вызове конструктора SSLContext по умолчанию используется CERT_NONE. Поскольку этот режим не проверяет подлинность другой стороны, он может быть небезопасным, особенно в режиме клиента, когда обычно требуется удостовериться в подлинности сервера, с которым устанавливается соединение. Поэтому в режиме клиента настоятельно рекомендуется использовать CERT_REQUIRED. Однако этого недостаточно: нужно также проверить, что сертификат сервера, который можно получить вызовом SSLSocket.getpeercert(), соответствует нужной службе. Во многих протоколах и приложениях службу можно идентифицировать по имени хоста. Эта стандартная проверка выполняется автоматически, если включён параметр 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.minimum_version = ssl.TLSVersion.TLSv1_3 >>> client_context.maximum_version = ssl.TLSVersion.TLSv1_3
Созданный выше SSL-контекст будет разрешать подключения к серверу только по TLSv1.3 и более поздним версиям (если они поддерживаются вашей системой). PROTOCOL_TLS_CLIENT по умолчанию включает проверку сертификатов и имени хоста. В контекст необходимо загрузить сертификаты.
Выбор шифров
Если у вас повышенные требования к безопасности, можно точно настроить набор шифров, используемых при согласовании SSL-сеанса, с помощью метода SSLContext.set_ciphers(). Начиная с Python 3.2.3 модуль ssl по умолчанию отключает некоторые слабые шифры, однако вы можете дополнительно ограничить их выбор. Обязательно ознакомьтесь с документацией OpenSSL о формате списка шифров. Чтобы проверить, какие шифры включены заданным списком, используйте SSLContext.get_ciphers() или команду openssl ciphers в вашей системе.
Многопроцессорная обработка
Если вы используете этот модуль в многопроцессном приложении (например, с модулями multiprocessing или concurrent.futures), имейте в виду, что встроенный генератор случайных чисел OpenSSL некорректно обрабатывает порождённые процессы. Если приложение использует функции SSL с os.fork(), оно должно изменить состояние ГПСЧ родительского процесса. Для этого достаточно любого успешного вызова RAND_add() или RAND_bytes().
TLS 1.3
Добавлено в версии 3.7.
Протокол TLS 1.3 работает немного иначе, чем предыдущие версии TLS/SSL. Некоторые новые возможности TLS 1.3 пока недоступны.
- В TLS 1.3 используется отдельный набор наборов шифров. По умолчанию включены все наборы шифров AES-GCM и ChaCha20. Метод
SSLContext.set_ciphers()пока не позволяет включать или отключать шифры TLS 1.3, но методSSLContext.get_ciphers()возвращает их. - Билеты сеанса больше не отправляются в рамках начального рукопожатия и обрабатываются иначе.
SSLSocket.sessionиSSLSessionнесовместимы с TLS 1.3. - Сертификаты на стороне клиента также больше не проверяются во время начального рукопожатия. Сервер может запросить сертификат в любой момент. Клиенты обрабатывают запросы сертификатов во время отправки или получения данных приложения от сервера.
- Такие возможности TLS 1.3, как ранняя передача данных, отложенный запрос сертификата клиента TLS, настройка алгоритмов подписи и повторное согласование ключей, пока не поддерживаются.
См. также
-
Classsocket.socket -
Документация по базовому классу
socket - Надёжное шифрование SSL/TLS: введение
-
Введение из документации Apache HTTP Server
- RFC 1422: Повышение конфиденциальности электронной почты в Интернете. Часть II: Управление ключами на основе сертификатов
-
Стив Кент
- RFC 4086: Требования к случайности для обеспечения безопасности
-
Дональд Э., Джеффри И. Шиллер
- RFC 5280: Профиль сертификатов и списков отзыва сертификатов (CRL) инфраструктуры открытых ключей Internet X.509
-
Д. Купер
- RFC 5246: Протокол защиты транспортного уровня (TLS), версия 1.2
-
Т. Диркс и др.
- RFC 6066: Расширения протокола защиты транспортного уровня (TLS)
-
Д. Истлейк
- IANA TLS: параметры протокола защиты транспортного уровня (TLS)
-
IANA
- RFC 7525: Рекомендации по безопасному использованию протокола защиты транспортного уровня (TLS) и протокола защиты транспортного уровня для дейтаграмм (DTLS)
-
IETF
- Рекомендации Mozilla по TLS на стороне сервера
-
Mozilla
© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.12/library/ssl.html