ssl — Обёртка TLS/SSL для сокетов
Исходный код: Lib/ssl.py
Этот модуль предоставляет доступ к шифрованию Transport Layer Security (часто известному как «Secure Sockets Layer») и средствам проверки подлинности узлов для сетевых сокетов, как со стороны клиента, так и со стороны сервера. Этот модуль использует библиотеку OpenSSL. Он доступен на всех современных Unix-системах, Windows, Mac OS X и, вероятно, на дополнительных платформах, при условии установки OpenSSL на этой платформе.
Примечание
Некоторые особенности могут зависеть от платформы, так как вызовы выполняются к API сокетов операционной системы. Установленная версия OpenSSL также может вызывать различия в поведении. Например, TLSv1.1 и TLSv1.2 поставляются с openssl версии 1.0.1.
Предупреждение
Не используйте этот модуль без прочтения Рекомендаций по безопасности. Это может привести к ложному ощущению безопасности, так как настройки по умолчанию модуля ssl необязательно подходят для вашего приложения.
В этом разделе документированы объекты и функции в модуле ssl; для получения более общей информации о TLS, SSL и сертификатах читатель обращается к документации в разделе «См. также» внизу.
Этот модуль предоставляет класс ssl.SSLSocket, который наследуется от типа socket.socket и предоставляет обёртку для сокета, которая также шифрует и расшифровывает данные, передаваемые по сокету с помощью SSL. Он поддерживает дополнительные методы, такие как getpeercert(), который извлекает сертификат другой стороны соединения, и cipher(), который извлекает шифр, используемый для защищённого соединения.
Для более сложных приложений класс ssl.SSLContext помогает управлять настройками и сертификатами, которые затем могут быть унаследованы сокетами SSL, созданными с помощью метода SSLContext.wrap_socket().
Изменено в версии 3.5.3: Обновлено для поддержки связывания с OpenSSL 1.1.0
Изменено в версии 3.6: OpenSSL 0.9.8, 1.0.0 и 1.0.1 устарели и больше не поддерживаются. В будущем модуль ssl будет требовать по крайней мере OpenSSL 1.0.2 или 1.1.0.
18.2.1. Функции, константы и исключения
-
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.CertificateError -
Выбрасывается для сигнализации об ошибке с сертификатом (например, несовпадение имени хоста). Однако ошибки сертификатов, обнаруженные OpenSSL, вызывают
SSLError.
18.2.1.1. Создание сокета
Следующая функция позволяет создавать автономные сокеты. Начиная с Python 3.2, использование SSLContext.wrap_socket() может быть более гибким.
-
ssl.wrap_socket(sock, keyfile=None, certfile=None, server_side=False, cert_reqs=CERT_NONE, ssl_version={see docs}, ca_certs=None, do_handshake_on_connect=True, suppress_ragged_eofs=True, ciphers=None) -
Принимает экземпляр
sockобъектаsocket.socketи возвращает экземплярssl.SSLSocket, подтипsocket.socket, который оборачивает базовый сокет в контекст SSL.sockдолжен быть сокетом типаSOCK_STREAM; другие типы сокетов не поддерживаются.Для сокетов стороны клиента создание контекста выполняется лениво; если базовый сокет ещё не подключён, создание контекста будет выполнено после вызова
connect()для сокета. Для сокетов стороны сервера, если сокет не имеет удалённого узла, он предполагается сокетом прослушивания, и оборачивание SSL для серверной стороны автоматически выполняется при подключении клиентов через методaccept().wrap_socket()может вызвать исключениеSSLError.Параметры
keyfileиcertfileзадают необязательные файлы, содержащие сертификат, который будет использоваться для идентификации локальной стороны подключения. Дополнительную информацию о том, как сертификат хранится вcertfile, см. в разделе Сертификаты.Параметр
server_side— это логическое значение, указывающее, нужно ли поведение сокета для серверной или клиентской стороны.Параметр
cert_reqsопределяет, требуется ли сертификат с другой стороны соединения и будет ли он проверен при предоставлении. Он должен быть одним из трёх значений:CERT_NONE(сертификаты игнорируются),CERT_OPTIONAL(необязательно, но проверяется при предоставлении) илиCERT_REQUIRED(требуется и проверяется). Если значение этого параметра неCERT_NONE, то параметрca_certsдолжен указывать на файл с сертификатами центров сертификации.Файл
ca_certsсодержит набор конкатенированных сертификатов «центра сертификации», используемых для проверки сертификатов, переданных с другой стороны соединения. Дополнительную информацию о том, как организовать сертификаты в этом файле, см. в разделе Сертификаты.Параметр
ssl_versionуказывает, какую версию протокола 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
нет
нет
да
нет
нет
да
Примечания
-
1(1,2) -
SSLContextпо умолчанию отключает SSLv2 с помощьюOP_NO_SSLv2. -
2(1,2) -
SSLContextпо умолчанию отключает SSLv3 с помощьюOP_NO_SSLv3. -
3(1,2) -
Протокол TLS 1.3 будет доступен с
PROTOCOL_TLSв OpenSSL >= 1.1.1. Нет специальной константы PROTOCOL для только TLS 1.3.
Примечание
Успешность подключений будет зависеть от версии OpenSSL. Например, до OpenSSL 1.0.0 клиент SSLv23 всегда пытался подключиться по протоколу SSLv2.
Параметр ciphers устанавливает доступные шифры для этого объекта SSL. Он должен быть строкой в формате списка шифров OpenSSL .
Параметр
do_handshake_on_connectуказывает, следует ли автоматически выполнить рукопожатие SSL после выполненияsocket.connect(), или приложение должно вызвать его явно, вызвав методSSLSocket.do_handshake(). Явное вызов методаSSLSocket.do_handshake()даёт программе контроль над блокирующим поведением операций ввода-вывода сокета, участвующих в рукопожатии.Параметр
suppress_ragged_eofsопределяет, как методSSLSocket.recv()должен сигнализировать о неожиданном конце файла (EOF) с другой стороны соединения. Если задано значениеTrue(по умолчанию), он возвращает нормальный EOF (пустой байтовый объект) в ответ на неожиданные ошибки EOF, поднятые базовым сокетом; еслиFalse, он передаст исключения вызывающей стороне.Изменено в версии 3.2: Новый необязательный аргумент ciphers.
-
18.2.1.2. Создание контекста
Функция-удобство помогает создавать объекты SSLContext для общих целей.
-
ssl.create_default_context(purpose=Purpose.SERVER_AUTH, cafile=None, capath=None, cadata=None) -
Возвращает новый объект
SSLContextс настройками по умолчанию для заданного назначения. Настройки выбираются модулемsslи обычно представляют более высокий уровень безопасности, чем при непосредственном вызове конструктораSSLContext.cafile, capath, cadata представляют необязательные сертификаты УЦ для проверки сертификатов, как в
SSLContext.load_verify_locations(). Если все три параметра равныNone, эта функция может выбрать доверие к сертификатам УЦ по умолчанию системы.Настройки включают:
PROTOCOL_TLS,OP_NO_SSLv2иOP_NO_SSLv3с высокошифровальными наборами шифров без RC4 и без ненастроенных наборов шифров. Передача значенияSERVER_AUTHв качестве назначения устанавливаетverify_modeв значениеCERT_REQUIREDи либо загружает сертификаты УЦ (если хотя бы один из cafile, capath или cadata задан), либо используетSSLContext.load_default_certs()для загрузки сертификатов УЦ по умолчанию.Примечание
Протокол, опции, шифры и другие настройки могут быть изменены на более строгие значения в любое время без предварительного уведомления. Эти значения представляют разумный баланс между совместимостью и безопасностью.
Если вашему приложению нужны определенные настройки, вы должны создать объект
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 был исключён из строковой спецификации шифрования по умолчанию.
18.2.1.3. Генерация случайных чисел
-
ssl.RAND_bytes(num) -
Возвращает num криптографически сильных псевдослучайных байтов. Возбуждает
SSLError, если генератор псевдослучайных чисел (ПСПЧ) не был инициализирован достаточным количеством данных или если операция не поддерживается текущим методом RAND.RAND_status()можно использовать для проверки состояния ПСПЧ, аRAND_add()можно использовать для инициализации ПСПЧ.Для почти всех приложений предпочтительнее
os.urandom().Прочтите статью Википедии Cryptographically secure pseudorandom number generator (CSPRNG), чтобы ознакомиться с требованиями к криптографически-безопасному генератору.
Новая версия с 3.3.
-
ssl.RAND_pseudo_bytes(num) -
Возвращает (байты, is_cryptographic): байты — это num псевдослучайных байтов, is_cryptographic —
True, если сгенерированные байты являются криптографически сильными. ВозбуждаетSSLError, если операция не поддерживается текущим методом RAND.Сгенерированные псевдослучайные последовательности байтов будут уникальными, если они достаточно длинные, но не обязательно предсказуемыми. Их можно использовать для некриптографических целей и для определённых целей в криптографических протоколах, но обычно не для генерации ключей и т. д.
Для почти всех приложений предпочтительнее
os.urandom().Новая версия с 3.3.
Устарело начиная с версии 3.6: OpenSSL устарел
ssl.RAND_pseudo_bytes(), используйтеssl.RAND_bytes()вместо него.
-
ssl.RAND_status() -
Возвращает
True, если генератор псевдослучайных чисел SSL был инициализирован достаточным количеством случайных данных, иFalse, в противном случае. Для увеличения случайности генератора псевдослучайных чисел можно использоватьssl.RAND_egd()иssl.RAND_add().
-
ssl.RAND_egd(path) -
Если у вас где-то запущен демон сбора энтропии (EGD), и path — это имя сокета, открытого для подключения к нему, эта функция прочитает 256 байтов случайных данных из сокета и добавит их в генератор псевдослучайных чисел SSL для повышения безопасности сгенерированных секретных ключей. Это обычно необходимо только на системах без более надёжных источников случайности.
См. http://egd.sourceforge.net/ или http://prngd.sourceforge.net/ для источников демонов сбора энтропии.
Доступность: недоступно с LibreSSL и OpenSSL > 1.1.0
-
ssl.RAND_add(bytes, entropy) -
Смешивает предоставленные байты в генератор псевдослучайных чисел SSL. Параметр entropy (число с плавающей запятой) — это нижняя граница энтропии, содержащейся в строке (поэтому вы всегда можете использовать
0.0). См. RFC 1750 для получения дополнительной информации о источниках энтропии.Изменено в версии 3.5: Теперь принимается объект типа bytes-like object.
18.2.1.4. Обработка сертификатов
-
ssl.match_hostname(cert, hostname) -
Проверяет, соответствует ли cert (в декодированном формате, возвращаемом
SSLSocket.getpeercert()) заданному hostname. Применяемые правила соответствуют проверке личности HTTPS-серверов, описанной в RFC 2818, RFC 5280 и RFC 6125. Кроме HTTPS, эта функция должна подходить для проверки личности серверов в различных SSL-протоколах, таких как FTPS, IMAPS, POPS и других.CertificateErrorгенерируется при ошибке. При успешном выполнении функция ничего не возвращает:>>> cert = {'subject': ((('commonName', 'example.com'),),)} >>> ssl.match_hostname(cert, "example.com") >>> ssl.match_hostname(cert, "example.org") Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/home/py3k/Lib/ssl.py", line 130, in match_hostname ssl.CertificateError: hostname 'example.org' doesn't match 'example.com'Новая версия с 3.2.
Изменено в версии 3.3.3: Функция теперь следует RFC 6125, раздел 6.4.3 и не сопоставляет несколько подстановок (например,
*.*.comили*a*.example.org) или подстановку внутри фрагмента доменного имени с международной кодировкой (IDN). Поддержка IDN меток (A-метки), таких какwww*.xn--pthon-kva.org, сохраняется, ноx*.python.orgбольше не соответствуетxn--tda.python.org.Изменено в версии 3.5: Теперь поддерживается сопоставление IP-адресов, когда они присутствуют в поле subjectAltName сертификата.
-
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, ca_certs=None) -
При заданном адресе
addrзащищенного SSL-сервера, как пары (имя_хоста, номер_порта), извлекает сертификат сервера и возвращает его в формате PEM. Еслиssl_versionуказан, используется указанная версия протокола SSL для подключения к серверу. Еслиca_certsуказан, он должен содержать список корневых сертификатов в том же формате, что и для этого параметра вwrap_socket(). Вызов попытается проверить сертификат сервера по отношению к этому набору корневых сертификатов и завершится ошибкой, если проверка не пройдёт.Изменено в версии 3.3: Эта функция теперь совместима с IPv6.
Изменено в версии 3.5: Значение по умолчанию для ssl_version изменено с
PROTOCOL_SSLv3наPROTOCOL_TLSдля максимальной совместимости с современными серверами.
-
ssl.DER_cert_to_PEM_cert(DER_cert_bytes) -
При заданном сертификате в формате DER-кодированного блока байтов возвращает строку в формате PEM для того же сертификата.
-
ssl.PEM_cert_to_DER_cert(PEM_cert_string) -
При заданном сертификате в формате 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
Доступность: LibreSSL игнорирует переменные окружения
openssl_cafile_envиopenssl_capath_env.Введено в версии 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для данных ASN.1 X.509, либоpkcs_7_asnдля данных ASN.1 PKCS#7. 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для данных ASN.1 X.509, либоpkcs_7_asnдля данных ASN.1 PKCS#7.Доступность: Windows.
Введено в версии 3.4.
18.2.1.5. Постоянные значения
Все константы теперь являются коллекциями enum.IntEnum или enum.IntFlag.
Введено в версии 3.6.
-
ssl.CERT_NONE -
Возможные значения для
SSLContext.verify_modeили параметраcert_reqsдляwrap_socket(). За исключениемPROTOCOL_TLS_CLIENT, это режим по умолчанию. При работе с клиентскими сокетами принимается практически любой сертификат. Ошибки проверки, такие как недоверенный или просроченный сертификат, игнорируются и не прерывают установление соединения TLS/SSL.В режиме сервера не запрашивается сертификат клиента, поэтому клиент не отправляет его для проверки сертификата клиента.
См. обсуждение Соображения по безопасности ниже.
-
ssl.CERT_OPTIONAL -
Возможные значения для
SSLContext.verify_modeили параметраcert_reqsдляwrap_socket(). В режиме клиентаCERT_OPTIONALимеет то же значение, что иCERT_REQUIRED. Рекомендуется использоватьCERT_REQUIREDдля клиентских сокетов.В режиме сервера запрос на сертификат клиента отправляется клиенту. Клиент может либо проигнорировать запрос, либо отправить сертификат, чтобы выполнить проверку сертификата клиента TLS. Если клиент выбирает отправку сертификата, он проверяется. Любая ошибка проверки немедленно прерывает установление соединения TLS.
Использование этого значения требует наличия набора действительных сертификатов CA, которые передаются либо в
SSLContext.load_verify_locations(), либо в качестве значения параметраca_certsдляwrap_socket().
-
ssl.CERT_REQUIRED -
Возможные значения для
SSLContext.verify_modeили параметраcert_reqsдляwrap_socket(). В этом режиме сертификаты требуются от другого конца соединения сокета; если сертификат не предоставлен или его проверка завершается ошибкой, будет поднята ошибкаSSLError. Этот режим недостаточен для проверки сертификата в режиме клиента, так как не соответствует именам хостов. Необходимо также включитьcheck_hostnameдля проверки подлинности сертификата.PROTOCOL_TLS_CLIENTиспользуетCERT_REQUIREDи по умолчанию включаетcheck_hostname.Для серверного сокета этот режим обеспечивает обязательную проверку сертификата клиента TLS. Запрос на сертификат клиента отправляется клиенту, и клиент должен предоставить действительный и надёжный сертификат.
Использование этого значения требует наличия набора действительных сертификатов CA, которые передаются либо в
SSLContext.load_verify_locations(), либо в качестве значения параметраca_certsдляwrap_socket().
-
class ssl.VerifyMode -
Коллекция
enum.IntEnumконстант CERT_*.Введено в версии 3.6.
-
ssl.VERIFY_DEFAULT -
Возможные значения для
SSLContext.verify_flags. В этом режиме списки отзыва сертификатов (CRL) не проверяются. По умолчанию OpenSSL не требует и не проверяет CRL.Введено в версии 3.4.
-
ssl.VERIFY_CRL_CHECK_LEAF -
Возможные значения для
SSLContext.verify_flags. В этом режиме проверяется только сертификат peer, но не промежуточные сертификаты CA. Этот режим требует действительный CRL, подписанный издателем сертификата peer (его прямым предком CA). Если не загружен соответствующий сертификат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_X509_TRUSTED_FIRST -
Возможная величина для
SSLContext.verify_flags. Она указывает OpenSSL на предпочтение проверенных сертификатов при построении цепочки доверия для проверки сертификата. Этот флаг включён по умолчанию.Новое в версии 3.4.4.
-
class ssl.VerifyFlags -
enum.IntFlagколлекция констант VERIFY_*.Новое в версии 3.6.
-
ssl.PROTOCOL_TLS -
Выбирает самую высокую версию протокола, поддерживаемую как клиентом, так и сервером. Несмотря на название, этот параметр может выбрать как протоколы «SSL», так и «TLS».
Новое в версии 3.6.
-
ssl.PROTOCOL_TLS_CLIENT -
Автоматически подбирает самую высокую версию протокола, как и
PROTOCOL_TLS, но поддерживает только подключения типа клиентскихSSLSocket. Протокол включаетCERT_REQUIREDиcheck_hostnameпо умолчанию.Новое в версии 3.6.
-
ssl.PROTOCOL_TLS_SERVER -
Автоматически подбирает самую высокую версию протокола, как и
PROTOCOL_TLS, но поддерживает только подключения типа серверныхSSLSocket.Новое в версии 3.6.
-
ssl.PROTOCOL_SSLv23 -
Псевдоним для данных:
PROTOCOL_TLS.Устаревшее с версии 3.6: Используйте
PROTOCOL_TLSвместо этого.
-
ssl.PROTOCOL_SSLv2 -
Выбирает SSL версии 2 в качестве протокола шифрования канала.
Этот протокол недоступен, если OpenSSL скомпилирован с флагом
OPENSSL_NO_SSL2.Предупреждение
SSL версии 2 небезопасен. Его использование крайне не рекомендуется.
Устаревшее с версии 3.6: OpenSSL удалил поддержку SSLv2.
-
ssl.PROTOCOL_SSLv3 -
Выбирает SSL версию 3 в качестве протокола шифрования канала.
Этот протокол недоступен, если OpenSSL скомпилирован с флагом
OPENSSL_NO_SSLv3.Предупреждение
SSL версии 3 небезопасен. Его использование крайне не рекомендуется.
Устаревшее с версии 3.6: OpenSSL устарел все протоколы, специфичные для версии. Используйте протокол по умолчанию
PROTOCOL_TLSс флагами, такими какOP_NO_SSLv3вместо этого.
-
ssl.PROTOCOL_TLSv1 -
Выбирает TLS версию 1.0 в качестве протокола шифрования канала.
Устаревшее с версии 3.6: OpenSSL устарел все протоколы, специфичные для версии. Используйте протокол по умолчанию
PROTOCOL_TLSс флагами, такими какOP_NO_SSLv3вместо этого.
-
ssl.PROTOCOL_TLSv1_1 -
Выбирает TLS версию 1.1 в качестве протокола шифрования канала. Доступен только с openssl версией 1.0.1+.
Новое в версии 3.4.
Устаревшее с версии 3.6: OpenSSL устарел все протоколы, специфичные для версии. Используйте протокол по умолчанию
PROTOCOL_TLSс флагами, такими какOP_NO_SSLv3вместо этого.
-
ssl.PROTOCOL_TLSv1_2 -
Выбирает TLS версию 1.2 в качестве протокола шифрования канала. Это самая современная версия, и, вероятно, лучший выбор для максимальной защиты, если обе стороны её поддерживают. Доступен только с openssl версией 1.0.1+.
Новое в версии 3.4.
Устаревшее с версии 3.6: OpenSSL устарел все протоколы, специфичные для версии. Используйте протокол по умолчанию
PROTOCOL_TLSс флагами, такими какOP_NO_SSLv3вместо этого.
-
ssl.OP_ALL -
Включает обходные пути для различных ошибок, присутствующих в других реализациях SSL. Этот параметр установлен по умолчанию. Он не обязательно устанавливает те же флаги, что и постоянная 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.
-
ssl.OP_NO_TLSv1_1 -
Предотвращает подключение TLSv1.1. Этот параметр применим только в сочетании с
PROTOCOL_TLS. Он предотвращает выбор TLSv1.1 в качестве версии протокола. Доступен только с openssl версией 1.0.1+.Новое в версии 3.4.
-
ssl.OP_NO_TLSv1_2 -
Предотвращает подключение TLSv1.2. Этот параметр применим только в сочетании с
PROTOCOL_TLS. Он предотвращает выбор TLSv1.2 в качестве версии протокола. Доступен только с openssl версией 1.0.1+.Новое в версии 3.4.
-
ssl.OP_NO_TLSv1_3 -
Предотвращает подключение TLSv1.3. Этот параметр применим только в сочетании с
PROTOCOL_TLS. Он предотвращает выбор TLSv1.3 в качестве версии протокола. TLS 1.3 доступен с OpenSSL 1.1.1 или более поздней версией. Когда Python был скомпилирован с более старой версией OpenSSL, флаг по умолчанию равен 0.Новое в версии 3.6.3.
-
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.6.7.
-
ssl.OP_NO_COMPRESSION -
Отключить сжатие на канале SSL. Это полезно, если протокол приложения поддерживает собственную схему сжатия.
Этот параметр доступен только с OpenSSL 1.0.0 и более поздними версиями.
Новая версия 3.3.
-
class ssl.Options -
enum.IntFlagколлекция констант OP_*.
-
ssl.OP_NO_TICKET -
Запретить клиенту запрашивать билет сессии.
Новая версия 3.6.
-
ssl.HAS_ALPN -
Поддерживает ли библиотека OpenSSL встроенную поддержку расширения TLS Application-Layer Protocol Negotiation, как описано в RFC 7301.
Новая версия 3.5.
-
ssl.HAS_ECDH -
Поддерживает ли библиотека OpenSSL встроенную поддержку обмена ключами Diffie-Hellman на основе эллиптических кривых. Это должно быть истинно, если функция не была явно отключена дистрибутивом.
Новая версия 3.3.
-
ssl.HAS_SNI -
Поддерживает ли библиотека OpenSSL встроенную поддержку расширения Server Name Indication (как определено в RFC 6066).
Новая версия 3.2.
-
ssl.HAS_NPN -
Поддерживает ли библиотека OpenSSL встроенную поддержку Next Protocol Negotiation, как описано в спецификации черновика NPN. Если значение истинно, можно использовать метод
SSLContext.set_npn_protocols(), чтобы указать поддерживаемые протоколы.Новая версия 3.3.
-
ssl.HAS_TLSv1_3 -
Поддерживает ли библиотека OpenSSL встроенную поддержку протокола TLS 1.3.
Новая версия 3.6.3.
-
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.
18.2.2. SSL Сокеты
-
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()для обертывания сокета.
Сокеты 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: Таймаут сокета больше не сбрасывается каждый раз, когда принимаются или отправляются байты. Таймаут сокета теперь представляет максимальное общее время рукопожатия.
-
SSLSocket.getpeercert(binary_form=False) -
Если для узла на другом конце соединения нет сертификата, возвращается
None. Если рукопожатие SSL ещё не завершено, генерируется исключениеValueError.Если параметр
binary_formравенFalse, а сертификат был получен от узла, этот метод возвращает экземплярdict. Если сертификат не был проверен, возвращается пустой словарь. Если сертификат был проверен, возвращается словарь с несколькими ключами, среди которыхsubject(субъект, для которого был выпущен сертификат) иissuer(субъект, выпустивший сертификат). Если сертификат содержит экземпляр расширения Subject Alternative Name (см. RFC 3280), в словаре также будет ключsubjectAltName.Поля
subjectиissuerпредставляют собой кортежи, содержащие последовательность относительных отличительных имён (RDNs), указанных в структуре данных сертификата для соответствующих полей, а каждое 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}Примечание
Для проверки сертификата конкретной службы можно использовать функцию
match_hostname().Если параметр
binary_formравенTrue, и сертификат был предоставлен, этот метод возвращает DER-кодированную форму всего сертификата в виде последовательности байтов илиNone, если узел не предоставил сертификат. Предоставление сертификата узлом зависит от роли сокета SSL:- для клиентского сокета SSL сервер всегда предоставляет сертификат, независимо от необходимости проверки;
- для серверного сокета SSL клиент предоставляет сертификат только по запросу сервера; поэтому
getpeercert()вернётNone, если вы использовалиCERT_NONE(а неCERT_OPTIONALилиCERT_REQUIRED).
Изменено в версии 3.2: Возвращаемый словарь включает дополнительные элементы, такие как
issuerиnotBefore.Изменено в версии 3.4: Исключение
ValueErrorгенерируется, если рукопожатие не завершено. Возвращаемый словарь включает дополнительные элементы расширений X509v3, такие какcrlDistributionPoints,caIssuersи URIOCSP.
-
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.
-
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.Добавлена в версии 3.6.7.
Примечание
Доступно только с OpenSSL 1.1.1 и включённым TLS 1.3. Без поддержки TLS 1.3 метод генерирует исключение
NotImplementedError.
-
SSLSocket.version() -
Возвращает фактическую версию протокола SSL, согласованную соединением, в виде строки или
Noneпри отсутствии защищённого соединения. Возможные значения, возвращаемые на момент написания, включают"SSLv2","SSLv3","TLSv1","TLSv1.1"и"TLSv1.2". Более поздние версии OpenSSL могут определять дополнительные значения возврата.Добавлена в версии 3.5.
-
SSLSocket.pending() -
Возвращает количество уже расшифрованных байтов, доступных для чтения, ожидающих обработки по соединению.
-
SSLSocket.context -
Объект
SSLContext, к которому привязан этот сокет SSL. Если сокет SSL был создан с использованием функции верхнего уровняwrap_socket()(а неSSLContext.wrap_socket()), это пользовательский объект контекста, созданный для этого сокета SSL.Добавлена в версии 3.2.
-
SSLSocket.server_side -
Булево значение, равное
Trueдля серверных сокетов иFalseдля клиентских сокетов.Добавлена в версии 3.2.
-
SSLSocket.server_hostname -
Имя хоста сервера: тип
str, илиNoneдля серверных сокетов или если имя хоста не было указано в конструкторе.Добавлена в версии 3.2.
-
SSLSocket.session -
Объект
SSLSessionдля этого SSL-соединения. Сессия доступна для сокетов клиента и сервера после выполнения рукопожатия TLS. Для сокетов клиента сессия может быть установлена перед вызовомdo_handshake()для повторного использования сессии.Добавлена в версии 3.6.
-
SSLSocket.session_reused -
Добавлена в версии 3.6.
18.2.3. Контексты SSL
Добавлена в версии 3.2.
Контекст SSL хранит различные данные, которые живут дольше, чем отдельные SSL-соединения, такие как параметры конфигурации SSL, сертификаты и закрытые ключи. Он также управляет кэшем SSL-сессий для сокетов сервера, чтобы ускорить повторные подключения от тех же клиентов.
-
class ssl.SSLContext(protocol=PROTOCOL_TLS) -
Создает новый контекст SSL. Можно передать protocol, которое должно быть одним из
PROTOCOL_*констант, определенных в этом модуле.PROTOCOL_TLSв настоящее время рекомендуется для максимальной совместимости и является значением по умолчанию.См. также
create_default_context()позволяет модулюsslвыбирать настройки безопасности для заданной цели.Изменено в версии 3.6: Контекст создается со значениями по умолчанию, соответствующими безопасности. Параметры
OP_NO_COMPRESSION,OP_CIPHER_SERVER_PREFERENCE,OP_SINGLE_DH_USE,OP_SINGLE_ECDH_USE,OP_NO_SSLv2(кромеPROTOCOL_SSLv2) иOP_NO_SSLv3(кромеPROTOCOL_SSLv3) устанавливаются по умолчанию. Начальный список наборов шифров содержит толькоHIGHшифры, не содержитNULLшифров и не содержитMD5шифров (кромеPROTOCOL_SSLv2).
Объекты SSLContext имеют следующие методы и атрибуты:
-
SSLContext.cert_store_stats() -
Получает статистику по количеству загруженных сертификатов X.509, количеству сертификатов X.509, помеченных как сертификаты CA, и спискам отозванных сертификатов в виде словаря.
Пример для контекста с одним сертификатом 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) -
Загружает набор стандартных сертификатов «центра сертификации» (CA) из стандартных расположений. В Windows он загружает сертификаты CA из системных хранилищ
CAиROOT. В других системах он вызываетSSLContext.set_default_verify_paths(). В будущем метод может загружать сертификаты CA и из других расположений.Флаг purpose определяет, какие сертификаты CA загружаются. Параметры по умолчанию
Purpose.SERVER_AUTHзагружают сертификаты, которые помечены и доверяются для проверки подлинности веб-сервера TLS (сокеты со стороны клиента).Purpose.CLIENT_AUTHзагружает сертификаты CA для проверки сертификата клиента на стороне сервера.Добавлена в версии 3.4.
-
SSLContext.load_verify_locations(cafile=None, capath=None, cadata=None) -
Загружает набор сертификатов «центра сертификации» (CA), используемых для проверки сертификатов других узлов, когда
verify_modeотличается отCERT_NONE. Должен быть указан хотя бы один из cafile или capath.Этот метод также может загрузить списки отозванных сертификатов (CRL) в форматах PEM или DER. Для использования CRL необходимо правильно настроить
SSLContext.verify_flags.Строка cafile, если указана, представляет путь к файлу, содержащему конкатенированные сертификаты CA в формате PEM. Подробности о расположении сертификатов в этом файле см. в разделе Сертификаты.
Строка capath, если указана, представляет путь к каталогу, содержащему несколько сертификатов CA в формате PEM, следуя специфической структуре OpenSSL.
Объект cadata, если указан, представляет собой строку ASCII с одним или несколькими сертификатами PEM или объект-подобный байтам с сертификатами DER. Как и в случае с capath, лишние строки вокруг сертификатов PEM игнорируются, но должен быть присутствовать хотя бы один сертификат.
Изменено в версии 3.4: Добавлен необязательный аргумент cadata
-
SSLContext.get_ca_certs(binary_form=False) -
Возвращает список загруженных сертификатов «центра сертификации» (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() # OpenSSL 1.0.x [{'alg_bits': 256, 'description': 'ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=RSA ' 'Enc=AESGCM(256) Mac=AEAD', 'id': 50380848, 'name': 'ECDHE-RSA-AES256-GCM-SHA384', 'protocol': 'TLSv1/SSLv3', 'strength_bits': 256}, {'alg_bits': 128, 'description': 'ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=RSA ' 'Enc=AESGCM(128) Mac=AEAD', 'id': 50380847, 'name': 'ECDHE-RSA-AES128-GCM-SHA256', 'protocol': 'TLSv1/SSLv3', 'strength_bits': 128}]- В OpenSSL 1.1 и более поздних версиях словарь шифра содержит дополнительные поля::
-
>>> ctx.get_ciphers() # OpenSSL 1.1+ [{'aead': True, 'alg_bits': 256, 'auth': 'auth-rsa', 'description': 'ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=RSA ' 'Enc=AESGCM(256) Mac=AEAD', 'digest': None, 'id': 50380848, 'kea': 'kx-ecdhe', 'name': 'ECDHE-RSA-AES256-GCM-SHA384', 'protocol': 'TLSv1.2', 'strength_bits': 256, 'symmetric': 'aes-256-gcm'}, {'aead': True, 'alg_bits': 128, 'auth': 'auth-rsa', 'description': 'ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=RSA ' 'Enc=AESGCM(128) Mac=AEAD', 'digest': None, 'id': 50380847, 'kea': 'kx-ecdhe', 'name': 'ECDHE-RSA-AES128-GCM-SHA256', 'protocol': 'TLSv1.2', 'strength_bits': 128, 'symmetric': 'aes-128-gcm'}]
Доступно: OpenSSL 1.0.2+
Добавлена в версии 3.6.
-
SSLContext.set_default_verify_paths() -
Загружает набор стандартных сертификатов «центра сертификации» (CA) из пути к файловой системе, определенного при построении библиотеки OpenSSL. К сожалению, нет простого способа узнать, удался ли этот метод: ошибка не возвращается, если сертификаты не найдены. Если библиотека OpenSSL предоставляется в составе операционной системы, то, скорее всего, она настроена должным образом.
-
SSLContext.set_ciphers(ciphers) -
Установите доступные шифры для сокетов, созданных с этим контекстом. Он должен быть строкой в формате списка шифров OpenSSL OpenSSL cipher list format. Если ни один шифр не может быть выбран (потому что опции времени компиляции или другие настройки запрещают использование всех указанных шифров), будет поднято исключение
SSLError.Примечание
при подключении метод
SSLSocket.cipher()сокетов SSL вернёт текущий выбранный шифр.В OpenSSL 1.1.1 наборы шифров TLS 1.3 включены по умолчанию. Их нельзя отключить с помощью
set_ciphers().
-
SSLContext.set_alpn_protocols(protocols) -
Укажите, какие протоколы должен рекламировать сокет во время рукопожатия SSL/TLS. Это должен быть список строк ASCII, таких как
['http/1.1', 'spdy/2'], упорядоченных по приоритету. Выбор протокола происходит во время рукопожатия и происходит в соответствии с RFC 7301. После успешного рукопожатия методSSLSocket.selected_alpn_protocol()вернёт согласованный протокол.Этот метод вызовет
NotImplementedError, еслиHAS_ALPNравно False.OpenSSL 1.1.0 до 1.1.0e прервёт рукопожатие и вызовет
SSLError, когда обе стороны поддерживают ALPN, но не могут договориться о протоколе. Версии 1.1.0f и выше ведут себя как 1.0.2,SSLSocket.selected_alpn_protocol()возвращает None.Добавлена в версии 3.5.
-
SSLContext.set_npn_protocols(protocols) -
Укажите, какие протоколы должен рекламировать сокет во время рукопожатия SSL/TLS. Это должен быть список строк, таких как
['http/1.1', 'spdy/2'], упорядоченных по приоритету. Выбор протокола происходит во время рукопожатия и происходит в соответствии с NPN draft specification. После успешного рукопожатия методSSLSocket.selected_npn_protocol()вернёт согласованный протокол.Этот метод вызовет
NotImplementedError, еслиHAS_NPNравно False.Добавлена в версии 3.3.
-
SSLContext.set_servername_callback(server_name_callback) -
Зарегистрируйте функцию обратного вызова, которая будет вызываться после получения сообщения TLS Client Hello сервером SSL/TLS, когда клиент TLS указывает указание имени сервера. Механизм указания имени сервера описан в RFC 6066 разделе 3 - Указание имени сервера.
Только один обратный вызов может быть установлен на
SSLContext. Если server_name_callback равноNone, обратный вызов отключён. Вызов этой функции в последующий раз отключит ранее зарегистрированный обратный вызов.Функция обратного вызова, server_name_callback, вызывается с тремя аргументами: первый —
ssl.SSLSocket, второй — строка, представляющая имя сервера, с которым клиент намерен общаться (илиNone, если TLS Client Hello не содержит имени сервера), и третий — исходныйSSLContext. Аргумент имени сервера — имя сервера, декодированное с помощью IDNA.Типичное использование этого обратного вызова — изменение атрибута
ssl.SSLSocket’sSSLSocket.contextна новый объект типаSSLContext, представляющий цепочку сертификатов, соответствующую имени сервера.Из-за ранней фазы согласования TLS доступны только ограниченные методы и атрибуты, такие как
SSLSocket.selected_alpn_protocol()иSSLSocket.context. МетодыSSLSocket.getpeercert(),SSLSocket.getpeercert(),SSLSocket.cipher()иSSLSocket.compress()требуют, чтобы соединение TLS продвинулось за пределы TLS Client Hello, поэтому они не будут содержать значимых значений и не могут быть безопасно вызваны.Функция server_name_callback должна возвращать
None, чтобы разрешить продолжение переговоров TLS. Если требуется ошибка TLS, можно вернуть константуALERT_DESCRIPTION_INTERNAL_ERROR. Другие возвращаемые значения приведут к ошибке TLS с фатальным сообщениемALERT_DESCRIPTION_INTERNAL_ERROR.Если при декодировании имени сервера IDNA произошла ошибка, соединение TLS завершится с фатальным TLS-сообщением об ошибке
ALERT_DESCRIPTION_INTERNAL_ERRORклиенту.Если из функции server_name_callback возникает исключение, соединение TLS завершится фатальным TLS-сообщением об ошибке
ALERT_DESCRIPTION_HANDSHAKE_FAILURE.Этот метод вызовет
NotImplementedError, если в библиотеке OpenSSL была определена OPENSSL_NO_TLSEXT при её сборке.Добавлена в версии 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 & Perfect Forward Secrecy
-
Винсент Бернат.
-
SSLContext.wrap_socket(sock, server_side=False, do_handshake_on_connect=True, suppress_ragged_eofs=True, server_hostname=None, session=None) -
Оборачивает существующий Python сокет sock и возвращает объект
SSLSocket. sock должен быть сокетомSOCK_STREAM; другие типы сокетов не поддерживаются.Возвращаемый SSL-сокет связан с контекстом, его настройками и сертификатами. Параметры server_side, do_handshake_on_connect и suppress_ragged_eofs имеют то же значение, что и в функции верхнего уровня
wrap_socket().При клиентских подключениях необязательный параметр server_hostname указывает имя хоста службы, к которой мы подключаемся. Это позволяет одному серверу размещать несколько SSL-сервисов с различными сертификатами, очень похожими на виртуальные хосты HTTP. Указание server_hostname вызовет
ValueError, если server_side имеет значение true.session, см.
session.Изменено в версии 3.5: Всегда разрешено передавать server_hostname, даже если OpenSSL не имеет SNI.
Изменено в версии 3.6: Добавлен аргумент session.
-
SSLContext.wrap_bio(incoming, outgoing, server_side=False, server_hostname=None, session=None) -
Создать новый экземпляр
SSLObject, обернув BIO-объекты incoming и outgoing. SSL-процедуры будут считывать входные данные из BIO incoming и записывать данные в BIO outgoing.Параметры server_side, server_hostname и session имеют такое же значение, как и в
SSLContext.wrap_socket().Изменено в версии 3.6: Добавлен аргумент session.
-
SSLContext.session_stats() -
Получить статистику о созданных или управляемых этим контекстом SSL-сессиях. Возвращается словарь, в котором имена каждого элемента информации сопоставлены с их числовыми значениями. Например, вот общее количество попаданий и промахов в кэш сессий с момента создания контекста:
>>> stats = context.session_stats() >>> stats['hits'], stats['misses'] (0, 0)
-
SSLContext.check_hostname -
Определяет, нужно ли сопоставлять имя хоста сертификата удаленного узла с помощью
match_hostname()вSSLSocket.do_handshake(). В контекстеverify_modeнеобходимо установить значениеCERT_OPTIONALилиCERT_REQUIRED, а параметр server_hostname необходимо передать вwrap_socket()для сопоставления имени хоста.Пример:
import socket, ssl context = ssl.SSLContext() 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.
Примечание
Эта функция требует OpenSSL 0.9.8f или более поздней версии.
-
SSLContext.options -
Целое число, представляющее набор SSL-параметров, включенных в этом контексте. Значение по умолчанию —
OP_ALL, но вы можете указать другие параметры, такие какOP_NO_SSLv2, объединяя их с помощью операции побитового ИЛИ.Примечание
С версиями OpenSSL, более ранними чем 0.9.8m, можно только устанавливать параметры, а не очищать их. Попытка очистить параметр (сбросить соответствующие биты) вызовет
ValueError.Изменено в версии 3.6:
SSLContext.optionsвозвращает флагиOptions:>>> ssl.create_default_context().options <Options.OP_ALL|OP_NO_SSLv3|OP_NO_SSLv2|OP_NO_COMPRESSION: 2197947391>
-
SSLContext.post_handshake_auth -
Включить пост-рукопожатие аутентификацию клиента TLS 1.3. По умолчанию аутентификация после рукопожатия отключена, и сервер может запросить сертификат TLS-клиента только во время начального рукопожатия. При включении сервер может запросить сертификат TLS-клиента в любое время после рукопожатия.
При включении на стороне клиентских сокетов клиент сигнализирует серверу, что он поддерживает аутентификацию после рукопожатия.
При включении на стороне серверных сокетов,
SSLContext.verify_modeтакже должен быть установлен наCERT_OPTIONALилиCERT_REQUIRED. Фактический обмен сертификатами клиента откладывается до вызоваSSLSocket.verify_client_post_handshake()и выполнения некоторых операций ввода-вывода.Введено в версии 3.6.7.
Примечание
Доступно только с OpenSSL 1.1.1 и включенным TLS 1.3. Без поддержки TLS 1.3 значение свойства равно None и его нельзя изменить
-
SSLContext.protocol -
Версия протокола, выбранная при построении контекста. Это свойство является только для чтения.
-
SSLContext.verify_flags -
Флаги для операций проверки сертификатов. Можно задавать флаги, такие как
VERIFY_CRL_CHECK_LEAF, объединяя их с помощью операции побитового ИЛИ. По умолчанию OpenSSL не требует и не проверяет списки отзыва сертификатов (CRL). Доступен только с openssl версией 0.9.8+.Введено в версии 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>
18.2.4. Сертификаты
Сертификаты в целом являются частью системы открытого и закрытого ключей. В этой системе каждому субъекту (которым может быть компьютер, человек или организация) назначается уникальный двухчастный криптографический ключ. Одна часть ключа является открытой и называется открытым ключом; другая часть держится в секрете и называется закрытым ключом. Эти две части связаны тем, что если вы зашифруете сообщение одной из частей, вы можете расшифровать его только другой частью.
Сертификат содержит информацию о двух субъектах. Он содержит имя субъекта и открытый ключ субъекта. Он также содержит утверждение второго субъекта, выдающего органа, что субъект является тем, за кого себя выдает, и что это действительно открытый ключ субъекта. Утверждение выдающего органа подписано закрытым ключом выдающего органа, который известен только выдающему органу. Однако любой может проверить утверждение выдающего органа, найдя его открытый ключ, расшифровав утверждение с помощью него и сравнив его с другой информацией в сертификате. Сертификат также содержит информацию о периоде его действия. Это выражается в двух полях, называемых «notBefore» и «notAfter».
При использовании сертификатов в Python клиент или сервер может использовать сертификат, чтобы доказать свою личность. От другой стороны сетевого подключения также может потребоваться предъявить сертификат, и этот сертификат может быть проверен клиентом или сервером, требующим такой проверки. Если проверка завершится неудачно, попытка подключения может вызвать исключение. Проверка выполняется автоматически, основополагающей системой OpenSSL; приложение не должно беспокоиться о ее механизме. Но приложение обычно должно предоставлять наборы сертификатов, чтобы этот процесс мог быть осуществлен.
Python использует файлы для хранения сертификатов. Они должны быть отформатированы в формате «PEM» (см. RFC 1422), представляющем собой закодированную в формате base-64 форму, обернутую заголовком и футером:
-----BEGIN CERTIFICATE----- ... (certificate in base64 PEM encoding) ... -----END CERTIFICATE-----
18.2.4.1. Цепочки сертификатов
Файлы 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-----
18.2.4.2. Сертификаты центров сертификации
Если вам требуется проверка сертификата другой стороны подключения, вам необходимо предоставить файл «сертификатов центров сертификации», заполненный цепочками сертификатов для каждого выдающего органа, которому вы доверяете. Этот файл также содержит конкатенацию этих цепочек. При проверке Python будет использовать первую цепочку в файле, которая совпадает. Файл сертификатов платформы может быть использован вызовом SSLContext.load_default_certs(), это делается автоматически с помощью create_default_context().
18.2.4.3. Объединенный ключ и сертификат
Часто закрытый ключ хранится в том же файле, что и сертификат; в этом случае, необходимо передать только параметр certfile к SSLContext.load_cert_chain() и wrap_socket(). Если закрытый ключ хранится вместе с сертификатом, он должен предшествовать первому сертификату в цепочке сертификатов:
-----BEGIN RSA PRIVATE KEY----- ... (private key in base64 encoding) ... -----END RSA PRIVATE KEY----- -----BEGIN CERTIFICATE----- ... (certificate in base64 PEM encoding) ... -----END CERTIFICATE-----
18.2.4.4. Самозаверяющие сертификаты
Если вы собираетесь создать сервер, предоставляющий услуги 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 %
Недостатком самозаверяющего сертификата является то, что он является собственной корневым сертификатом, и никто другой не будет иметь его в своём кэше известных (и доверенных) корневых сертификатов.
18.2.5. Примеры
18.2.5.1. Проверка поддержки SSL
Для проверки наличия поддержки SSL в установке Python код пользователя должен использовать следующий идиом:
try:
import ssl
except ImportError:
pass
else:
... # do something that requires SSL support
18.2.5.2. Операция на стороне клиента
Этот пример создаёт контекст SSL с рекомендуемыми настройками безопасности для сокетов клиента, включая автоматическую проверку сертификатов:
>>> context = ssl.create_default_context()
Если вы предпочитаете настраивать параметры безопасности самостоятельно, вы можете создать контекст с нуля (но будьте осторожны, что вы можете не угадать настройки):
>>> context = ssl.SSLContext()
>>> context.verify_mode = ssl.CERT_REQUIRED
>>> context.check_hostname = True
>>> context.load_verify_locations("/etc/ssl/certs/ca-bundle.crt")
(Этот фрагмент предполагает, что ваша операционная система размещает набор всех сертификатов центров сертификации в /etc/ssl/certs/ca-bundle.crt; если нет, вы получите ошибку и должны будете настроить расположение)
Когда вы используете контекст для подключения к серверу, CERT_REQUIRED проверяет сертификат сервера: он гарантирует, что сертификат сервера был подписан одним из сертификатов центров сертификации и проверяет правильность подписи:
>>> 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'']
См. обсуждение Соображения по безопасности ниже.
18.2.5.3. Операция на стороне сервера
Для работы на стороне сервера обычно необходимо иметь сертификат сервера и закрытый ключ, каждый в отдельном файле. Сначала вы создадите контекст, содержащий ключ и сертификат, чтобы клиенты могли проверить вашу подлинность. Затем вы откроете сокет, привяжете его к порту, вызовете listen() на нём и начнёте ожидать подключения клиентов:
import socket, ssl
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
context.load_cert_chain(certfile="mycertfile", keyfile="mykeyfile")
bindsocket = socket.socket()
bindsocket.bind(('myaddr.mydomain.com', 10023))
bindsocket.listen(5)
Когда клиент подключается, вы вызываете accept() на сокете, чтобы получить новый сокет с другой стороны, и используете метод контекста SSLContext.wrap_socket() для создания SSL-сокета на стороне сервера для подключения:
while True:
newsocket, fromaddr = bindsocket.accept()
connstream = context.wrap_socket(newsocket, server_side=True)
try:
deal_with_client(connstream)
finally:
connstream.shutdown(socket.SHUT_RDWR)
connstream.close()
Затем вы будете читать данные из connstream и делать с ними что-то, пока вы не закончите с клиентом (или клиент не закончит с вами):
def deal_with_client(connstream):
data = connstream.recv(1024)
# 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
И возвращайтесь к прослушиванию новых подключений клиентов (конечно, реальный сервер, вероятно, обрабатывал бы каждое подключение клиента в отдельном потоке или помещал бы сокеты в неблокирующий режим и использовал цикл событий).
18.2.6. Примечания по неблокирующим сокетам
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-установление асинхронно.
18.2.7. Поддержка BIO в памяти
Новое в версии 3.5.
С тех пор, как модуль SSL был представлен в Python 2.6, класс SSLSocket предоставляет две связанные, но отличные области функциональности:
- Обработка протокола SSL
- Сетевой ввод-вывод
API сетевого ввода-вывода идентичен API, предоставляемому socket.socket, от которого SSLSocket также наследует. Это позволяет использовать SSL-сокет как прямую замену обычного сокета, что значительно упрощает добавление поддержки SSL в существующее приложение.
Комбинирование обработки протокола SSL и сетевого ввода-вывода обычно работает хорошо, но есть некоторые случаи, когда это не так. Пример — асинхронные фреймворки ввода-вывода, которые хотят использовать другую модель мультиплексирования ввода-вывода, отличную от модели «select/poll на дескрипторе файла» (базирующейся на готовности), которая предполагается socket.socket и внутренними OpenSSL-сокетами IO. Это в основном актуально для платформ, таких как Windows, где эта модель неэффективна. Для этой цели предоставляется сокращённая версия SSLSocket с именем SSLObject.
-
class ssl.SSLObject -
Упрощённая версия
SSLSocket, представляющая собой экземпляр протокола SSL, не содержащий методов сетевого ввода-вывода. Этот класс обычно используется разработчиками фреймворков, которые хотят реализовать асинхронный ввод-вывод для SSL через буферы памяти.Этот класс реализует интерфейс поверх низкоуровневого объекта SSL, реализованного в OpenSSL. Этот объект сохраняет состояние соединения SSL, но не предоставляет собственный сетевой ввод-вывод. Ввод-вывод должен выполняться через отдельные объекты «BIO», которые являются уровнем абстракции ввода-вывода OpenSSL.
Экземпляр
SSLObjectможно создать, используя методwrap_bio(). Этот метод создаст экземплярSSLObjectи свяжет его с парой BIO. Входящий BIO используется для передачи данных из Python в экземпляр протокола SSL, а исходящий BIO — для передачи данных в обратном направлении.Доступны следующие методы:
contextserver_sideserver_hostnamesessionsession_reusedread()write()getpeercert()selected_npn_protocol()cipher()shared_ciphers()compression()pending()do_handshake()unwrap()get_channel_binding()
По сравнению с
SSLSocket, этот объект не имеет следующих функций:- Любой формы сетевого ввода-вывода;
recv()иsend()читают и записывают только в базовые буферыMemoryBIO. - Нет механизма do_handshake_on_connect. Вы всегда должны вручную вызвать
do_handshake()для начала рукопожатия. - Нет обработки suppress_ragged_eofs. Все условия конца файла, нарушающие протокол, сообщаются с помощью исключения
SSLEOFError. - Вызов метода
unwrap()ничего не возвращает, в отличие от сокета SSL, где он возвращает базовый сокет. - Обратный вызов server_name_callback, переданный в
SSLContext.set_servername_callback(), получит экземплярSSLObjectвместо экземпляраSSLSocketв качестве первого параметра.
Некоторые замечания, связанные с использованием
SSLObject:- Все операции ввода-вывода с
SSLObjectявляются неоперативными. Это означает, что, например,read()вызоветSSLWantReadError, если ему потребуется больше данных, чем доступно в входящем BIO. - Нет вызова
wrap_bio()на уровне модуля, как дляwrap_socket(). ЭкземплярSSLObjectвсегда создаётся с помощьюSSLContext.
SSLObject взаимодействует с внешним миром с помощью буферов памяти. Класс MemoryBIO предоставляет буфер памяти, который можно использовать для этой цели. Он оборачивает объект памяти OpenSSL BIO (Basic IO):
-
class ssl.MemoryBIO -
Буфер памяти, который можно использовать для передачи данных между Python и экземпляром протокола SSL.
-
pending -
Возвращает количество байтов, в настоящее время находящихся в буфере памяти.
-
eof -
Булево значение, указывающее, находится ли текущее состояние памяти BIO в конце файла.
-
read(n=-1) -
Считывает до n байтов из буфера памяти. Если n не указано или отрицательно, возвращаются все байты.
-
write(buf) -
Записывает байты из buf в память BIO. Аргумент buf должен быть объектом, поддерживающим протокол буфера.
Значение возврата — количество записанных байтов, которое всегда равно длине buf.
-
18.2.8. Сессия SSL
Введено в версии 3.6.
-
class ssl.SSLSession -
Объект сессии, используемый в
session.-
id
-
time
-
timeout
-
ticket_lifetime_hint
-
has_ticket
-
18.2.9. Учёт безопасности
18.2.9.1. Наилучшие значения по умолчанию
Для использования клиентом, если у вас нет особых требований к политике безопасности, настоятельно рекомендуется использовать функцию 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 самостоятельно, он по умолчанию не будет иметь проверки сертификатов или проверки имени хоста. Если вы сделаете это, пожалуйста, прочитайте параграфы ниже, чтобы достичь хорошего уровня безопасности.
18.2.9.2. Настройка вручную
18.2.9.2.1. Проверка сертификатов
При прямом вызове конструктора SSLContext, по умолчанию используется значение CERT_NONE. Поскольку это не выполняет аутентификацию другого узла, это может быть небезопасно, особенно в режиме клиента, где в большинстве случаев необходимо гарантировать подлинность сервера, с которым вы взаимодействуете. Поэтому в режиме клиента настоятельно рекомендуется использовать CERT_REQUIRED. Однако этого недостаточно; необходимо также проверить, что сертификат сервера, который можно получить, вызвав SSLSocket.getpeercert(), соответствует требуемому сервису. Для многих протоколов и приложений сервис можно определить по имени хоста; в этом случае можно использовать функцию match_hostname(). Эта общая проверка автоматически выполняется при включении SSLContext.check_hostname.
В режиме сервера, если вы хотите аутентифицировать своих клиентов с помощью SSL-слоя (вместо использования механизма аутентификации более высокого уровня), вам также необходимо указать CERT_REQUIRED и аналогично проверить сертификат клиента.
18.2.9.2.2. Версии протоколов
SSL-версии 2 и 3 считаются небезопасными и поэтому их опасно использовать. Если вы хотите максимальную совместимость между клиентами и серверами, рекомендуется использовать PROTOCOL_TLS_CLIENT или PROTOCOL_TLS_SERVER в качестве версии протокола. SSLv2 и SSLv3 отключены по умолчанию.
>>> client_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) >>> client_context.options |= ssl.OP_NO_TLSv1 >>> client_context.options |= ssl.OP_NO_TLSv1_1
Созданный выше контекст SSL будет разрешать подключения к серверу только по протоколу TLSv1.2 и более поздним версиям (если это поддерживается вашей системой). PROTOCOL_TLS_CLIENT по умолчанию подразумевает проверку сертификатов и проверки имени хоста. Вам необходимо загрузить сертификаты в контекст.
18.2.9.2.3. Выбор шифров
Если у вас есть расширенные требования к безопасности, то тонкую настройку шифров, используемых при установлении SSL-сессии, можно выполнить с помощью метода SSLContext.set_ciphers(). Начиная с Python 3.2.3, модуль ssl по умолчанию отключает определённые слабые шифры, но вы можете ещё более ограничить выбор шифров. Обязательно ознакомьтесь с документацией OpenSSL по формату списка шифров. Если вы хотите проверить, какие шифры включены в данном списке шифров, воспользуйтесь SSLContext.get_ciphers() или командой openssl ciphers на вашей системе.
18.2.9.3. Многопроцессорность
Если вы используете этот модуль в рамках многопроцессорного приложения (например, используя модули multiprocessing или concurrent.futures), имейте в виду, что внутренний генератор случайных чисел OpenSSL не обрабатывает корректно разветвлённые процессы. Приложения должны изменить состояние PRNG родительского процесса, если они используют какие-либо SSL-функции с os.fork(). Любой успешный вызов RAND_add(), RAND_bytes() или RAND_pseudo_bytes() достаточно.
18.2.10. Поддержка LibreSSL
LibreSSL — это вилка OpenSSL 1.0.1. Модуль ssl имеет ограниченную поддержку LibreSSL. Некоторые функции недоступны, когда модуль ssl скомпилирован с LibreSSL.
- LibreSSL >= 2.6.1 больше не поддерживает NPN. Методы
SSLContext.set_npn_protocols()иSSLSocket.selected_npn_protocol()недоступны. -
SSLContext.set_default_verify_paths()игнорирует переменные средыSSL_CERT_FILEиSSL_CERT_PATH, хотяget_default_verify_paths()по-прежнему их отображает.
См. также
-
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’s Server Side TLS recommendations
-
Mozilla
© 2001–2020 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.6/library/ssl.html