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().Прочитайте статью Википедии Cryptographically secure pseudorandom number generator (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: Теперь принимается изменяемый объект-подобный байтам.
Обработка сертификатов
-
ssl.cert_time_to_seconds(cert_time) -
Возвращает время в секундах с эпохи, заданное строкой
cert_time, представляющей дату «notBefore» или «notAfter» из сертификата в формате"%b %d %H:%M:%S %Y %Z"strptime (локаль C).Вот пример:
>>> import ssl >>> timestamp = ssl.cert_time_to_seconds("Jan 5 09:34:43 2018 GMT") >>> timestamp 1515144883 >>> from datetime import datetime >>> print(datetime.utcfromtimestamp(timestamp)) 2018-01-05 09:34:43Даты «notBefore» и «notAfter» должны использовать GMT (RFC 5280).
Изменено в версии 3.5: Интерпретирует входное время как время в UTC, как указано в строке ввода с помощью часового пояса «GMT». Раньше использовался локальный часовой пояс. Возвращает целое число (нет дробной части секунды в формате входных данных)
-
ssl.get_server_certificate(addr, ssl_version=PROTOCOL_TLS_CLIENT, ca_certs=None[, timeout]) -
Принимая адрес
addrзащищенного SSL-сервера, как пару (имя_хоста, номер_порта), извлекает сертификат сервера и возвращает его как строку в формате PEM. Еслиssl_versionуказан, используется эта версия протокола SSL для подключения к серверу. Если ca_certs указан, это файл, содержащий список корневых сертификатов, в том же формате, что и параметр cafile вSSLContext.load_verify_locations(). Вызов попытается проверить сертификат сервера по набору корневых сертификатов и завершится ошибкой, если проверка не пройдёт. Таймаут может быть задан параметромtimeout.Изменено в версии 3.3: Эта функция теперь совместима с IPv6.
Изменено в версии 3.5: Значение по умолчанию для ssl_version изменено с
PROTOCOL_SSLv3наPROTOCOL_TLSдля максимальной совместимости с современными серверами.Изменено в версии 3.10: Добавлен параметр timeout.
-
ssl.DER_cert_to_PEM_cert(DER_cert_bytes) -
Принимая сертификат в виде DER-кодированного блока байтов, возвращает строку PEM, содержащую этот же сертификат.
-
ssl.PEM_cert_to_DER_cert(PEM_cert_string) -
Принимая сертификат в виде ASCII-строки PEM, возвращает DER-кодированную последовательность байтов для этого же сертификата.
-
ssl.get_default_verify_paths() -
Возвращает кортеж с именами путей к файлу cafile и каталогу capath по умолчанию OpenSSL. Пути такие же, как используемые в
SSLContext.set_default_verify_paths(). Результат — именованный кортежDefaultVerifyPaths:-
cafile— разрешенный путь к cafile илиNoneесли файл не существует, -
capath— разрешенный путь к capath илиNoneесли каталог не существует, -
openssl_cafile_env— ключ среды OpenSSL, указывающий на cafile, -
openssl_cafile— жёстко закодированный путь к cafile, -
openssl_capath_env— ключ среды OpenSSL, указывающий на capath, -
openssl_capath— жёстко закодированный путь к каталогу capath
Добавлен в версии 3.4.
-
-
ssl.enum_certificates(store_name) -
Извлекает сертификаты из хранилища системных сертификатов Windows. store_name может быть одним из
CA,ROOTилиMY. Windows может предоставлять и дополнительные хранилища сертификатов.Функция возвращает список кортежей (cert_bytes, encoding_type, trust). encoding_type указывает кодировку cert_bytes. Это либо
x509_asnдля данных X.509 ASN.1, либоpkcs_7_asnдля данных PKCS#7 ASN.1. Trust указывает назначение сертификата как набора OIDS или точноTrue, если сертификат надёжен для всех целей.Пример:
>>> ssl.enum_certificates("CA") [(b'data...', 'x509_asn', {'1.3.6.1.5.5.7.3.1', '1.3.6.1.5.5.7.3.2'}), (b'data...', 'x509_asn', True)]Доступность: Windows.
Добавлен в версии 3.4.
-
ssl.enum_crls(store_name) -
Извлекает CRL из хранилища системных сертификатов Windows. store_name может быть одним из
CA,ROOTилиMY. Windows может предоставлять и дополнительные хранилища сертификатов.Функция возвращает список кортежей (cert_bytes, encoding_type, trust). encoding_type указывает кодировку cert_bytes. Это либо
x509_asnдля данных 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 -
Коллекция констант CERT_* типа
enum.IntEnum.Добавлен в версии 3.6.
-
ssl.VERIFY_DEFAULT -
Возможные значения для
SSLContext.verify_flags. В этом режиме списки отзыва сертификатов (CRL) не проверяются. По умолчанию OpenSSL не требует и не проверяет CRL.Добавлен в версии 3.4.
-
ssl.VERIFY_CRL_CHECK_LEAF -
Возможные значения для
SSLContext.verify_flags. В этом режиме проверяется только сертификат peer, но не промежуточные сертификаты CA. Режим требует действительный CRL, подписанный издателем сертификата peer (его непосредственным предком CA). Если соответствующий CRL не загружен с помощьюSSLContext.load_verify_locations, проверка завершится неудачно.Добавлен в версии 3.4.
-
ssl.VERIFY_CRL_CHECK_CHAIN -
Возможные значения для
SSLContext.verify_flags. В этом режиме проверяются CRL всех сертификатов в цепочке сертификатов peer.Добавлен в версии 3.4.
-
ssl.VERIFY_X509_STRICT -
Возможные значения для
SSLContext.verify_flags, чтобы отключить обходные пути для поврежденных X.509 сертификатов.Добавлен в версии 3.4.
-
ssl.VERIFY_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 -
Коллекция констант VERIFY_* типа
enum.IntFlag.Добавлен в версии 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. Эта опция установлена по умолчанию. Она не обязательно устанавливает те же флаги, что и константа OpenSSL
SSL_OP_ALL.Добавлен в версии 3.2.
-
ssl.OP_NO_SSLv2 -
Запрещает подключение SSLv2. Эта опция применима только в сочетании с
PROTOCOL_TLS. Она предотвращает выбор SSLv2 как протокола версии клиентами.Добавлен в версии 3.2.
Устарело начиная с версии 3.6: SSLv2 устарел
-
ssl.OP_NO_SSLv3 -
Запрещает подключение SSLv3. Эта опция применима только в сочетании с
PROTOCOL_TLS. Она предотвращает выбор SSLv3 как протокола версии клиентами.Добавлен в версии 3.2.
Устарело начиная с версии 3.6: SSLv3 устарел
-
ssl.OP_NO_TLSv1 -
Запрещает подключение TLSv1. Эта опция применима только в сочетании с
PROTOCOL_TLS. Она предотвращает выбор TLSv1 как протокола версии клиентами.Добавлен в версии 3.2.
Устарело начиная с версии 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 -
Коллекция констант 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 Application-Layer Protocol Negotiation, описанного в 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 встроенная поддержка расширения Server Name Indication (определенного в RFC 6066).
Добавлен в версии 3.2.
-
ssl.HAS_NPN -
Есть ли в библиотеке OpenSSL встроенная поддержка Next Protocol Negotiation, как описано в Application Layer Protocol Negotiation. Если это значение истинно, вы можете использовать метод
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 Alert Registry IANA содержится этот список и ссылки на RFC, где определено их значение.
Используется как возвращаемое значение функции обратного вызова в
SSLContext.set_servername_callback().Добавлен в версии 3.4.
-
class ssl.AlertDescription -
Коллекция констант ALERT_DESCRIPTION_* типа
enum.IntEnum.Добавлен в версии 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 -
Коллекция констант SSL_ERROR_* типа
enum.IntEnum.Добавлен в версии 3.6.
-
class ssl.TLSVersion -
Коллекция констант 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 Soкеты
-
class ssl.SSLSocket(socket.socket) -
SSL сокеты предоставляют следующие методы объектов сокета:
accept()bind()close()connect()detach()fileno()-
getpeername(),getsockname() -
getsockopt(),setsockopt() -
gettimeout(),settimeout(),setblocking() listen()makefile()-
recv(),recv_into()(но передача ненулевогоflagsаргумента запрещена) -
send(),sendall()(с тем же ограничением) -
sendfile()(ноos.sendfileбудет использоваться только для текстовых сокетов, в противном случаеsend()будет использоваться) shutdown()
Однако, поскольку протокол SSL (и TLS) имеет собственное форматирование поверх TCP, абстракция SSL-сокетов может в определенных аспектах отличаться от спецификации обычных сокетов на уровне ОС. Обратите особое внимание на замечания о неблокирующих сокетах.
Экземпляры
SSLSocketдолжны создаваться с помощью методаSSLContext.wrap_socket().Изменено в версии 3.5: Метод
sendfile()был добавлен.Изменено в версии 3.5:
shutdown()больше не сбрасывает таймаут сокета каждый раз, когда принимаются или отправляются байты. Таймаут сокета теперь является максимальной общей продолжительностью завершения.Устарело начиная с версии 3.6: Не рекомендуется создавать экземпляр
SSLSocketнапрямую, используйтеSSLContext.wrap_socket()для обертывания сокета.Изменено в версии 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: Имя хоста или IP-адрес сравниваются OpenSSL во время рукопожатия. Функция
match_hostname()больше не используется. Если OpenSSL отказывается от имени хоста или IP-адреса, рукопожатие прерывается и отправляется сообщение TLS alert peer.
-
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иOCSPURI.Изменено в версии 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-метки ("xn--pythn-mua.org"), а не форму U-метки ("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 может быть функцией, которую нужно вызвать для получения пароля для расшифровки закрытого ключа. Она будет вызвана только в том случае, если закрытый ключ зашифрован и необходим пароль. Она будет вызвана без аргументов и должна вернуть строку, байты или массив байтов. Если возвращаемое значение является строкой, оно будет закодировано в UTF-8 перед использованием для расшифровки ключа. В качестве альтернативы можно напрямую передать строку, байты или массив байтов как аргумент password. Он будет проигнорирован, если закрытый ключ не зашифрован и пароль не требуется.
Если аргумент password не указан и пароль требуется, будет использована встроенная механизм запроса пароля OpenSSL для интерактивного запроса пароля у пользователя.
Если закрытый ключ не соответствует сертификату, будет поднято исключение
SSLError.Изменено в версии 3.3: Новый необязательный аргумент password.
-
SSLContext.load_default_certs(purpose=Purpose.SERVER_AUTH) -
Загрузка набора стандартных сертификатов «центра сертификации» (ЦС) из стандартных расположений. В Windows загружаются сертификаты ЦС из системных хранилищ
CAиROOT. На всех системах вызываетсяSSLContext.set_default_verify_paths(). В будущем метод может загружать сертификаты ЦС и из других расположений.Флаг purpose указывает, какие сертификаты ЦС загрузить. Стандартные настройки
Purpose.SERVER_AUTHзагружают сертификаты, помеченные и доверенные для аутентификации веб-сервера TLS (клиентские сокеты).Purpose.CLIENT_AUTHзагружает сертификаты ЦС для проверки сертификатов клиента на стороне сервера.Добавлена в версии 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, если присутствует, — это путь к файлу, содержащему конкатенированные сертификаты ЦС в формате PEM. Дополнительную информацию о том, как расположить сертификаты в этом файле, см. в разделе Сертификаты.
Строка capath, если присутствует, — это путь к каталогу, содержащему несколько сертификатов ЦС в формате 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() [{'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() -
Загрузка набора стандартных сертификатов «центра сертификации» (ЦС) из пути к файловой системе, определённого при построении библиотеки 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()вернёт согласованный протокол.Этот метод вызовет
NotImplementedError, еслиHAS_ALPNравноFalse.Добавлена в версии 3.5.
-
SSLContext.set_npn_protocols(protocols) -
Указывает, какие протоколы должен объявлять сокет во время рукопожатия SSL/TLS. Это должен быть список строк, например
['http/1.1', 'spdy/2'], упорядоченный по предпочтению. Выбор протокола произойдёт во время рукопожатия и будет происходить согласно Application Layer Protocol Negotiation. После успешного рукопожатия методSSLSocket.selected_npn_protocol()вернёт согласованный протокол.Этот метод вызовет
NotImplementedError, еслиHAS_NPNравноFalse.Добавлена в версии 3.3.
Устарело начиная с версии 3.10: NPN устарел, его заменил ALPN
-
SSLContext.sni_callback -
Зарегистрируйте функцию обратного вызова, которая будет вызвана после получения сообщения рукопожатия TLS Client Hello сервером SSL/TLS, когда клиент TLS указывает указание имени сервера. Механизм указания имени сервера описан в RFC 6066 разделе 3 — Указание имени сервера.
Только один обратный вызов может быть установлен для каждого
SSLContext. Если sni_callback установлен наNone, то обратный вызов отключён. Следующее вызов этой функции отключит ранее зарегистрированный обратный вызов.Функция обратного вызова будет вызвана с тремя аргументами: первым будет
ssl.SSLSocket, вторым — строка, представляющая имя сервера, с которым клиент намерен взаимодействовать (илиNone, если сообщение TLS Client Hello не содержит имени сервера), и третьим — исходныйSSLContext. Аргумент имени сервера — текст. Для доменных имён с национальными символами имя сервера — метка IDN A ("xn--pythn-mua.org").Типичное использование этого обратного вызова — изменение атрибута
ssl.SSLSocket’sSSLSocket.contextна новый объект типа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.Этот метод вызовет
NotImplementedError, если в бибилиотеке OpenSSL при её компиляции был определён OPENSSL_NO_TLSEXT.Добавлен в версии 3.7.
-
SSLContext.set_servername_callback(server_name_callback) -
Это устаревший API, сохранённый для обратной совместимости. Если возможно, используйте
sni_callbackвместо него. Указанный server_name_callback аналогичен sni_callback, за исключением того, что когда имя сервера закодировано в IDN (международное доменное имя), server_name_callback получает декодированную метку U ("pythön.org").Если при декодировании имени сервера произойдёт ошибка, соединение TLS завершится с сообщением об ошибке TLS
ALERT_DESCRIPTION_INTERNAL_ERRORдля клиента.Добавлен в версии 3.4.
-
SSLContext.load_dh_params(dhfile) -
Загружает параметры генерации ключей для обмена ключами Диффи-Хеллмана (DH). Использование обмена ключами DH улучшает конфиденциальность в будущем, но за счёт вычислительных ресурсов (как на сервере, так и на клиенте). Параметр dhfile должен указывать на файл с параметрами DH в формате PEM.
Это настройка не применяется к клиентским сокетам. Также можно использовать опцию
OP_SINGLE_DH_USEдля дальнейшего повышения безопасности.Добавлен в версии 3.3.
-
SSLContext.set_ecdh_curve(curve_name) -
Устанавливает имя кривой для обмена ключами Диффи-Хеллмана на основе эллиптических кривых (ECDH). ECDH значительно быстрее, чем обычный DH, и, вероятно, так же безопасен. Параметр curve_name должен быть строкой, описывающей известную эллиптическую кривую, например
prime256v1для широко поддерживаемой кривой.Это настройка не применяется к клиентским сокетам. Также можно использовать опцию
OP_SINGLE_ECDH_USEдля дальнейшего повышения безопасности.Этот метод недоступен, если
HAS_ECDHравноFalse.Добавлен в версии 3.3.
См. также
- 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_hostname, вызов метода с server_side равным True вызовет
ValueError.Параметр
do_handshake_on_connectуказывает, необходимо ли автоматически выполнить SSL-рукопожатие после выполненияsocket.connect(), или приложение должно вызвать его явно, вызвав методSSLSocket.do_handshake(). Явное вызовSSLSocket.do_handshake()даёт программе контроль над блокирующим поведением операций ввода-вывода сокета, связанного с рукопожатием.Параметр
suppress_ragged_eofsопределяет, как методSSLSocket.recv()должен сигнализировать о неожиданном завершении файла (EOF) с другой стороны соединения. Если заданоTrue(по умолчанию), он возвращает обычное EOF (пустой байтовый объект) в ответ на ошибки неожиданного EOF, поднятые подлежащим сокетом; еслиFalse, он передаст исключения вызывающей стороне.session, см.
session.Для обертывания
SSLSocketв другойSSLSocketиспользуйтеSSLContext.wrap_bio().Изменено в версии 3.5: Всегда разрешается передавать server_hostname, даже если OpenSSL не имеет SNI.
Изменено в версии 3.6: Добавлен аргумент session.
Изменено в версии 3.7: Метод возвращает экземпляр
SSLContext.sslsocket_classвместо жёстко заданногоSSLSocket.
-
SSLContext.sslsocket_class -
Тип возвращаемого значения
SSLContext.wrap_socket(), по умолчаниюSSLSocket. Атрибут может быть переопределён для экземпляра класса, чтобы возвращать пользовательский подкласс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 в файл keylog, когда генерируется или принимается материал ключей. Файл keylog предназначен только для отладки. Формат файла задаётся NSS и используется многими анализаторами трафика, такими как Wireshark. Файл журнала открывается в режиме добавления.
Записи синхронизируются между потоками, но не между процессами.
Добавлен в версии 3.8.
-
SSLContext.maximum_version -
TLSVersionперечисление, представляющее самую высокую поддерживаемую версию TLS. По умолчанию значениеTLSVersion.MAXIMUM_SUPPORTED. Атрибут является только для чтения для протоколов, отличных отPROTOCOL_TLS,PROTOCOL_TLS_CLIENTиPROTOCOL_TLS_SERVER.Атрибуты
maximum_version,minimum_versionиSSLContext.optionsвсе влияют на поддерживаемые версии SSL и TLS контекста. Реализация не предотвращает недопустимые комбинации. Например, контекст сOP_NO_TLSv1_2вoptionsиmaximum_version, установленным вTLSVersion.TLSv1_2, не сможет установить соединение TLS 1.2.Добавлен в версии 3.7.
-
SSLContext.minimum_version -
Аналогично
SSLContext.maximum_version, но это наименьшая поддерживаемая версия илиTLSVersion.MINIMUM_SUPPORTED.Добавлен в версии 3.7.
-
SSLContext.num_tickets -
Управляет количеством билетов сессий TLS 1.3 контекста
PROTOCOL_TLS_SERVER. Настройки не влияют на соединения TLS 1.0—1.2.Добавлен в версии 3.8.
-
SSLContext.options -
Целое число, представляющее набор опций SSL, включённых в этом контексте. По умолчанию значение
OP_ALL, но вы можете указать другие опции, такие какOP_NO_SSLv2, объединив их с операцией OR.Изменено в версии 3.6:
SSLContext.optionsвозвращает флагиOptions:>>> ssl.create_default_context().options <Options.OP_ALL|OP_NO_SSLv3|OP_NO_SSLv2|OP_NO_COMPRESSION: 2197947391>
Устарело начиная с версии 3.7: Все опции
OP_NO_SSL*иOP_NO_TLS*устарели начиная с Python 3.7. Вместо этого используйтеSSLContext.minimum_versionиSSLContext.maximum_version.
-
SSLContext.post_handshake_auth -
Включить пост-рукопожатие TLS 1.3 для проверки подлинности клиента. Проверка подлинности пост-рукопожатия по умолчанию отключена, и сервер может запросить сертификат клиента TLS только во время начального рукопожатия. При включении сервер может запросить сертификат клиента 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, объединив их с операцией OR. По умолчанию OpenSSL не требует и не проверяет списки отзыва сертификатов (CRL).Добавлен в версии 3.4.
Изменено в версии 3.6:
SSLContext.verify_flagsвозвращает флагиVerifyFlags:>>> ssl.create_default_context().verify_flags <VerifyFlags.VERIFY_X509_TRUSTED_FIRST: 32768>
-
SSLContext.verify_mode -
Выполнять ли проверку сертификатов других узлов и как реагировать при неудачной проверке. Это свойство должно быть одним из
CERT_NONE,CERT_OPTIONALилиCERT_REQUIRED.Изменено в версии 3.6:
SSLContext.verify_modeвозвращает перечислениеVerifyMode:>>> ssl.create_default_context().verify_mode <VerifyMode.CERT_REQUIRED: 2>
Сертификаты
В целом, сертификаты являются частью системы с открытым и закрытым ключами. В этой системе каждому субъекту (который может быть машиной, человеком или организацией) назначается уникальный двухчастный криптографический ключ. Одна часть ключа является открытой и называется открытым ключом; другая часть является секретной и называется закрытым ключом. Эти две части взаимосвязаны, так что если вы зашифруете сообщение с помощью одной из частей, вы сможете расшифровать его с помощью другой и только с помощью другой части.
Сертификат содержит информацию о двух субъектах. Он содержит имя субъекта и открытый ключ субъекта. Он также содержит утверждение второго субъекта, эмитента, о том, что субъект является тем, за кого себя выдает, и что это действительно открытый ключ субъекта. Утверждение эмитента подписано закрытым ключом эмитента, который известен только эмитенту. Однако любой может проверить утверждение эмитента, найдя открытый ключ эмитента, расшифровав утверждение с его помощью и сравнив его с другой информацией в сертификате. Сертификат также содержит информацию о периоде времени, в течение которого он действителен. Это выражается в двух полях, называемых «notBefore» и «notAfter».
При использовании сертификатов в Python клиент или сервер могут использовать сертификат для подтверждения своей личности. От другой стороны сетевого соединения также может потребоваться представить сертификат, и этот сертификат может быть проверен на удовлетворительность клиента или сервера, требующего такой проверки. Попытка подключения может быть настроена так, чтобы при неудачной проверке генерировать исключение. Проверка выполняется автоматически, с помощью базового фреймворка OpenSSL; приложение не должно беспокоиться о ее механизме. Но приложение обычно должно предоставить наборы сертификатов, чтобы этот процесс мог происходить.
Python использует файлы для хранения сертификатов. Они должны быть отформатированы как «PEM» (см. RFC 1422), который представляет собой кодировку в формате base-64, заключённую в заголовок и подвал:
-----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-----
Сертификаты CA
Если вы хотите выполнить проверку сертификата другой стороны соединения, вам нужно предоставить файл «CA certs», содержащий цепочки сертификатов для каждого эмитента, которому вы доверяете. Опять же, этот файл просто содержит эти цепочки, конкатенированные вместе. Для проверки 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")
(в этом фрагменте предполагается, что ваша операционная система размещает пакет всех сертификатов 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.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-handshake будет неблокирующим: метод
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-handshake асинхронно.
Поддержка BIO для памяти
Добавлена в версии 3.5.
С тех пор, как модуль SSL был представлен в Python 2.6, класс SSLSocket предоставляет две взаимосвязанные, но отличные функциональные области:
- Обработка протокола SSL
- Сеть IO
API сети IO идентичен API, предоставленному классом socket.socket, от которого класс SSLSocket также наследует. Это позволяет использовать сокет SSL как прямую замену обычного сокета, что значительно упрощает добавление поддержки SSL в существующее приложение.
Комбинирование обработки протокола SSL и сети IO обычно работает хорошо, но существуют случаи, когда это не так. Например, в фреймворках асинхронного ввода-вывода, которые хотят использовать другую модель мультиплексирования ввода-вывода, отличную от модели «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. - Вызов метода
unwrap()ничего не возвращает, в отличие от сокета SSL, где он возвращает базовый сокет. - Обратный вызов server_name_callback, переданный методу
SSLContext.set_servername_callback(), получит экземплярSSLObjectвместо экземпляраSSLSocketв качестве первого параметра.
Некоторые замечания, связанные с использованием
SSLObject:- Весь ввод-вывод для
SSLObjectявляется неблокирующим. Это означает, что, например,read()вызовет исключениеSSLWantReadError, если ему потребуется больше данных, чем доступно в объекте входящего BIO.
Изменено в версии 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.
-
Сессия 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(), соответствует нужному сервису. Для многих протоколов и приложений сервис можно идентифицировать по имени хоста. Эта распространённая проверка автоматически выполняется, когда 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 не обрабатывает правильно разветвлённые процессы. Приложения должны изменить состояние PRNG родительского процесса, если они используют любые SSL-функции с os.fork(). Любой успешный вызов RAND_add() или RAND_bytes() является достаточным.
TLS 1.3
Добавлена в версии 3.7.
Протокол TLS 1.3 немного отличается от предыдущих версий TLS/SSL. Некоторые новые возможности TLS 1.3 пока недоступны.
- TLS 1.3 использует отдельный набор наборов шифров. Все шифры AES-GCM и ChaCha20 включены по умолчанию. Метод
SSLContext.set_ciphers()пока не может включать или отключать шифры TLS 1.3, ноSSLContext.get_ciphers()возвращает их. - Билеты сессий больше не отправляются как часть начального рукопожатия и обрабатываются по-другому.
SSLSocket.sessionиSSLSessionне совместимы с TLS 1.3. - Сертификаты клиента также больше не проверяются во время начального рукопожатия. Сервер может запросить сертификат в любое время. Клиенты обрабатывают запросы сертификатов, когда они отправляют или получают данные приложения от сервера.
- Функции TLS 1.3, такие как ранние данные, отложенный запрос TLS-сертификата клиента, настройка алгоритмов подписи и переключение ключей, пока не поддерживаются.
См. также
-
Classsocket.socket -
Документация базового класса
socket - SSL/TLS Strong Encryption: An Introduction
-
Введение из документации Apache HTTP Server
- RFC 1422: Privacy Enhancement for Internet Electronic Mail: Part II: Certificate-Based Key Management
-
Стив Кент
- RFC 4086: Randomness Requirements for Security
-
Дональд Е., Джеффри И. Шилер
- RFC 5280: Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile
-
Д. Купер
- RFC 5246: The Transport Layer Security (TLS) Protocol Version 1.2
-
Т. Диеркс и др.
- RFC 6066: Transport Layer Security (TLS) Extensions
-
Д. Истлейк
- IANA TLS: Transport Layer Security (TLS) Parameters
-
IANA
- RFC 7525: Recommendations for Secure Use of Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS)
-
IETF
- Рекомендации Mozilla по TLS на стороне сервера
-
Mozilla
© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.12/library/ssl.html