ssl — оболонка TLS/SSL для об’єктів сокета

Вихідний код: Lib/ssl.py


Цей модуль надає доступ до шифрування транспортного рівня безпеки (часто відомого як «рівень захищених сокетів») і засобів автентифікації однорангових мережевих сокетів як на стороні клієнта, так і на стороні сервера. Цей модуль використовує бібліотеку OpenSSL. Він доступний у всіх сучасних системах Unix, Windows, macOS і, ймовірно, на додаткових платформах, якщо на цій платформі встановлено OpenSSL.

Примітка

Some behavior may be platform dependent, since calls are made to the operating system socket APIs. The installed version of OpenSSL may also cause variations in behavior. For example, TLSv1.3 comes with OpenSSL version 1.1.1.

Попередження

Не використовуйте цей модуль, не прочитавши Міркування безпеки. Це може призвести до помилкового відчуття безпеки, оскільки стандартні параметри модуля ssl не обов’язково підходять для вашої програми.

Availability: not Emscripten, not WASI.

This module does not work or is not available on WebAssembly platforms wasm32-emscripten and wasm32-wasi. See WebAssembly platforms for more information.

У цьому розділі описано об’єкти та функції модуля 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 або новішої версії.

Використання застарілих констант і функцій призводить до попереджень про застаріле.

Функції, константи та винятки

Створення розетки

Instances of SSLSocket must be created using the SSLContext.wrap_socket() method. The helper function create_default_context() returns a new context with secure default settings.

Приклад клієнтського сокета з контекстом за замовчуванням і подвійним стеком 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())

Приклад серверного сокета, який прослуховує локальний хост 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 із налаштуваннями за замовчуванням для заданої цілі. Параметри вибираються модулем ssl і зазвичай представляють вищий рівень безпеки, ніж під час безпосереднього виклику конструктора SSLContext.

cafile, capath, cadata представляють додаткові сертифікати ЦС, яким можна довіряти для перевірки сертифікатів, як у SSLContext.load_verify_locations(). Якщо всі три параметри None, ця функція може натомість довіряти стандартним сертифікатам ЦС системи.

The settings are: PROTOCOL_TLS_CLIENT or PROTOCOL_TLS_SERVER, OP_NO_SSLv2, and OP_NO_SSLv3 with high encryption cipher suites without RC4 and without unauthenticated cipher suites. Passing SERVER_AUTH as purpose sets verify_mode to CERT_REQUIRED and either loads CA certificates (when at least one of cafile, capath or cadata is given) or uses SSLContext.load_default_certs() to load default CA certificates.

Якщо підтримується 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

Added in version 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.

Added in version 3.3.

reason

Рядок мнемоніки, що вказує причину цієї помилки, наприклад CERTIFICATE_VERIFY_FAILED. Діапазон можливих значень залежить від версії OpenSSL.

Added in version 3.3.

exception ssl.SSLZeroReturnError

Підклас SSLError викликається під час спроби читання або запису, а SSL-з’єднання було закрито. Зауважте, що це не означає, що основний транспорт (читай TCP) закрито.

Added in version 3.3.

exception ssl.SSLWantReadError

Підклас SSLError, викликаний неблокуючим SSL-сокетом під час спроби прочитати або записати дані, але для виконання запиту потрібно отримати більше даних базовим транспортом TCP.

Added in version 3.3.

exception ssl.SSLWantWriteError

Підклас SSLError, викликаний неблокуючим SSL-сокетом під час спроби прочитати або записати дані, але більше даних потрібно надіслати базовим транспортом TCP, перш ніж запит буде виконано.

Added in version 3.3.

exception ssl.SSLSyscallError

Підклас SSLError викликається, коли виникла системна помилка під час спроби виконати операцію на SSL-сокеті. На жаль, немає простого способу перевірити оригінальний номер errno.

Added in version 3.3.

exception ssl.SSLEOFError

Підклас SSLError викликається, коли з’єднання SSL було раптово розірвано. Як правило, ви не повинні намагатися повторно використовувати базовий транспорт, коли виникає ця помилка.

Added in version 3.3.

exception ssl.SSLCertVerificationError

Підклас SSLError викликається, коли не вдається перевірити сертифікат.

Added in version 3.7.

verify_code

Числовий номер помилки, який позначає помилку підтвердження.

verify_message

Зрозумілий для людини рядок помилки перевірки.

exception ssl.CertificateError

Псевдонім для SSLCertVerificationError.

Змінено в версії 3.7: Винятком тепер є псевдонім для SSLCertVerificationError.

Випадкова генерація

ssl.RAND_bytes(num)

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

Майже для всіх програм os.urandom() є кращим.

Прочитайте статтю Вікіпедії Криптографічно захищений генератор псевдовипадкових чисел (CSPRNG), щоб дізнатися про вимоги до криптографічно надійного генератора.

Added in version 3.3.

ssl.RAND_status()

Повертає True, якщо генератор псевдовипадкових чисел SSL заповнено достатньою випадковістю, і False в іншому випадку. Ви можете використовувати ssl.RAND_egd() і ssl.RAND_add(), щоб збільшити випадковість генератора псевдовипадкових чисел.

ssl.RAND_add(bytes, entropy)

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

Змінено в версії 3.5: Записуваний bytes-like object тепер приймається.

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

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])

Given the address addr of an SSL-protected server, as a (hostname, port-number) pair, fetches the server’s certificate, and returns it as a PEM-encoded string. If ssl_version is specified, uses that version of the SSL protocol to attempt to connect to the server. If ca_certs is specified, it should be a file containing a list of root certificates, the same format as used for the cafile parameter in SSLContext.load_verify_locations(). The call will attempt to validate the server certificate against that set of root certificates, and will fail if the validation attempt fails. A timeout can be specified with the timeout parameter.

Змінено в версії 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(). Поверненим значенням є named tuple DefaultVerifyPaths:

  • cafile - визначений шлях до cafile або None, якщо файл не існує,

  • capath - дозволений шлях до capath або None, якщо каталог не існує,

  • openssl_cafile_env - ключ середовища OpenSSL, який вказує на cafile,

  • openssl_cafile - жорстко закодований шлях до cafile,

  • openssl_capath_env - ключ середовища OpenSSL, який вказує на capath,

  • openssl_capath - жорстко закодований шлях до каталогу capath

Added in version 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.

Added in version 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.

Added in version 3.4.

Константи

Усі константи тепер є колекціями enum.IntEnum або enum.IntFlag.

Added in version 3.6.

ssl.CERT_NONE

Possible value for SSLContext.verify_mode. Except for PROTOCOL_TLS_CLIENT, it is the default mode. With client-side sockets, just about any cert is accepted. Validation errors, such as untrusted or expired cert, are ignored and do not abort the TLS/SSL handshake.

У режимі сервера від клієнта не запитується сертифікат, тому клієнт не надсилає жодного сертифіката для автентифікації клієнта.

Дивіться обговорення Міркування безпеки нижче.

ssl.CERT_OPTIONAL

Possible value for SSLContext.verify_mode. In client mode, CERT_OPTIONAL has the same meaning as CERT_REQUIRED. It is recommended to use CERT_REQUIRED for client-side sockets instead.

У режимі сервера клієнту надсилається запит на сертифікат клієнта. Клієнт може або проігнорувати запит, або надіслати сертифікат, щоб виконати автентифікацію клієнта за допомогою TLS. Якщо клієнт вирішує надіслати сертифікат, він перевіряється. Будь-яка помилка перевірки негайно перериває рукостискання TLS.

Use of this setting requires a valid set of CA certificates to be passed to SSLContext.load_verify_locations().

ssl.CERT_REQUIRED

Possible value for SSLContext.verify_mode. In this mode, certificates are required from the other side of the socket connection; an SSLError will be raised if no certificate is provided, or if its validation fails. This mode is not sufficient to verify a certificate in client mode as it does not match hostnames. check_hostname must be enabled as well to verify the authenticity of a cert. PROTOCOL_TLS_CLIENT uses CERT_REQUIRED and enables check_hostname by default.

З серверним сокетом цей режим забезпечує обов’язкову автентифікацію клієнта за допомогою TLS. Запит на сертифікат клієнта надсилається клієнту, і клієнт повинен надати дійсний і надійний сертифікат.

Use of this setting requires a valid set of CA certificates to be passed to SSLContext.load_verify_locations().

class ssl.VerifyMode

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

Added in version 3.6.

ssl.VERIFY_DEFAULT

Можливе значення для SSLContext.verify_flags. У цьому режимі списки відкликаних сертифікатів (CRL) не перевіряються. За замовчуванням OpenSSL не вимагає і не перевіряє CRL.

Added in version 3.4.

ssl.VERIFY_CRL_CHECK_LEAF

Можливе значення для SSLContext.verify_flags. У цьому режимі перевіряється лише одноранговий сертифікат, але не перевіряються проміжні сертифікати ЦС. Для режиму потрібен дійсний CRL, підписаний видавцем однорангового сертифіката (його прямим предком CA). Якщо не було завантажено відповідний CRL з SSLContext.load_verify_locations, перевірка не вдасться.

Added in version 3.4.

ssl.VERIFY_CRL_CHECK_CHAIN

Можливе значення для SSLContext.verify_flags. У цьому режимі перевіряються CRL усіх сертифікатів у ланцюжку однорангових сертифікатів.

Added in version 3.4.

ssl.VERIFY_X509_STRICT

Можливе значення для SSLContext.verify_flags для вимкнення обхідних шляхів для пошкоджених сертифікатів X.509.

Added in version 3.4.

ssl.VERIFY_ALLOW_PROXY_CERTS

Можливе значення для SSLContext.verify_flags для ввімкнення перевірки сертифіката проксі.

Added in version 3.10.

ssl.VERIFY_X509_TRUSTED_FIRST

Можливе значення для SSLContext.verify_flags. Він наказує OpenSSL віддавати перевагу надійним сертифікатам під час побудови ланцюжка довіри для перевірки сертифіката. Цей прапорець увімкнено за замовчуванням.

Added in version 3.4.4.

ssl.VERIFY_X509_PARTIAL_CHAIN

Можливе значення для SSLContext.verify_flags. Він наказує OpenSSL приймати проміжні ЦС у довірчому сховищі, щоб вони розглядалися як прив’язки довіри, так само, як і самопідписані кореневі сертифікати ЦС. Це дає змогу довіряти сертифікатам, виданим проміжним ЦС, не довіряючи кореневому ЦС предка.

Added in version 3.10.

class ssl.VerifyFlags

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

Added in version 3.6.

ssl.PROTOCOL_TLS

Вибирає найвищу версію протоколу, яку підтримують як клієнт, так і сервер. Незважаючи на назву, ця опція може вибрати як протоколи «SSL», так і «TLS».

Added in version 3.6.

Застаріло починаючи з версії 3.10: Клієнтам і серверам TLS потрібні різні параметри за замовчуванням для безпечного зв’язку. Загальна константа протоколу TLS застаріла на користь PROTOCOL_TLS_CLIENT і PROTOCOL_TLS_SERVER.

ssl.PROTOCOL_TLS_CLIENT

Автоматичне узгодження найвищої версії протоколу, яку підтримують як клієнт, так і сервер, і налаштування контекстних підключень на стороні клієнта. Протокол вмикає CERT_REQUIRED і check_hostname за умовчанням.

Added in version 3.6.

ssl.PROTOCOL_TLS_SERVER

Автоматичне узгодження найвищої версії протоколу, яку підтримують як клієнт, так і сервер, і налаштування контекстних підключень на стороні сервера.

Added in version 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+.

Added in version 3.4.

Застаріло починаючи з версії 3.6: OpenSSL не підтримує всі протоколи для окремих версій.

ssl.PROTOCOL_TLSv1_2

Вибирає TLS версії 1.2 як протокол шифрування каналу. Доступно лише з openssl версії 1.0.1+.

Added in version 3.4.

Застаріло починаючи з версії 3.6: OpenSSL не підтримує всі протоколи для окремих версій.

ssl.OP_ALL

Дозволяє обійти різні помилки, наявні в інших реалізаціях SSL. Ця опція встановлена за замовчуванням. Він не обов’язково встановлює ті самі позначки, що й константа SSL_OP_ALL OpenSSL.

Added in version 3.2.

ssl.OP_NO_SSLv2

Запобігає підключенню SSLv2. Цей параметр застосовний лише в поєднанні з PROTOCOL_TLS. Це запобігає вибору одноранговими вузлами SSLv2 як версії протоколу.

Added in version 3.2.

Застаріло починаючи з версії 3.6: SSLv2 застарів

ssl.OP_NO_SSLv3

Запобігає підключенню SSLv3. Цей параметр застосовний лише в поєднанні з PROTOCOL_TLS. Це запобігає вибору одноранговими вузлами SSLv3 як версії протоколу.

Added in version 3.2.

Застаріло починаючи з версії 3.6: SSLv3 застарів

ssl.OP_NO_TLSv1

Запобігає підключенню TLSv1. Цей параметр застосовний лише в поєднанні з PROTOCOL_TLS. Це запобігає вибору партнерами TLSv1 як версії протоколу.

Added in version 3.2.

Застаріло починаючи з версії 3.7: Опція застаріла з OpenSSL 1.1.0, замість неї використовуйте нові SSLContext.minimum_version і SSSLContext.maximum_version.

ssl.OP_NO_TLSv1_1

Запобігає підключенню TLSv1.1. Цей параметр застосовний лише в поєднанні з PROTOCOL_TLS. Це запобігає вибору одноранговими вузлами TLSv1.1 як версії протоколу. Доступно лише з openssl версії 1.0.1+.

Added in version 3.4.

Застаріло починаючи з версії 3.7: Опція застаріла з OpenSSL 1.1.0.

ssl.OP_NO_TLSv1_2

Запобігає підключенню TLSv1.2. Цей параметр застосовний лише в поєднанні з PROTOCOL_TLS. Це запобігає вибору одноранговими вузлами TLSv1.2 як версії протоколу. Доступно лише з openssl версії 1.0.1+.

Added in version 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.

Added in version 3.6.3.

Застаріло починаючи з версії 3.7: The option is deprecated since OpenSSL 1.1.0. It was added to 2.7.15 and 3.6.3 for backwards compatibility with OpenSSL 1.0.2.

ssl.OP_NO_RENEGOTIATION

Вимкніть усі повторні узгодження в TLSv1.2 і попередніх версіях. Не надсилайте повідомлення HelloRequest і ігноруйте запити на повторне узгодження через ClientHello.

Ця опція доступна лише для OpenSSL 1.1.0h і пізніших версій.

Added in version 3.7.

ssl.OP_CIPHER_SERVER_PREFERENCE

Використовуйте параметри впорядкування шифрів сервера, а не клієнта. Цей параметр не впливає на клієнтські сокети та серверні сокети SSLv2.

Added in version 3.3.

ssl.OP_SINGLE_DH_USE

Запобігає повторному використанню того самого ключа DH для різних сеансів SSL. Це покращує пряму секретність, але вимагає більше обчислювальних ресурсів. Цей параметр стосується лише серверних сокетів.

Added in version 3.3.

ssl.OP_SINGLE_ECDH_USE

Запобігає повторному використанню того самого ключа ECDH для різних сеансів SSL. Це покращує пряму секретність, але вимагає більше обчислювальних ресурсів. Цей параметр стосується лише серверних сокетів.

Added in version 3.3.

ssl.OP_ENABLE_MIDDLEBOX_COMPAT

Надсилайте фіктивні повідомлення про зміну шифру (CCS) у рукостисканні TLS 1.3, щоб зробити з’єднання TLS 1.3 більш схожим на з’єднання TLS 1.2.

Ця опція доступна лише з OpenSSL 1.1.1 і новіших версій.

Added in version 3.8.

ssl.OP_NO_COMPRESSION

Вимкніть стиснення на каналі SSL. Це корисно, якщо протокол програми підтримує власну схему стиснення.

Added in version 3.3.

class ssl.Options

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

ssl.OP_NO_TICKET

Заборонити стороні клієнта запитувати квиток сеансу.

Added in version 3.6.

ssl.OP_IGNORE_UNEXPECTED_EOF

Ігноруйте несподіване завершення з’єднань TLS.

Цей параметр доступний лише з OpenSSL 3.0.0 і пізніших версій.

Added in version 3.10.

ssl.OP_ENABLE_KTLS

Enable the use of the kernel TLS. To benefit from the feature, OpenSSL must have been compiled with support for it, and the negotiated cipher suites and extensions must be supported by it (a list of supported ones may vary by platform and kernel version).

Note that with enabled kernel TLS some cryptographic operations are performed by the kernel directly and not via any available OpenSSL Providers. This might be undesirable if, for example, the application requires all cryptographic operations to be performed by the FIPS provider.

Цей параметр доступний лише з OpenSSL 3.0.0 і пізніших версій.

Added in version 3.12.

ssl.OP_LEGACY_SERVER_CONNECT

Allow legacy insecure renegotiation between OpenSSL and unpatched servers only.

Added in version 3.12.

ssl.HAS_ALPN

Чи має бібліотека OpenSSL вбудовану підтримку розширення TLS Application-Layer Protocol Negotiation, як описано в RFC 7301.

Added in version 3.5.

ssl.HAS_NEVER_CHECK_COMMON_NAME

Чи має бібліотека OpenSSL вбудовану підтримку, яка не перевіряє загальне ім’я суб’єкта та SSLContext.hostname_checks_common_name, доступний для запису.

Added in version 3.7.

ssl.HAS_ECDH

Чи має бібліотека OpenSSL вбудовану підтримку для обміну ключами Діффі-Хеллмана на основі еліптичної кривої. Це має бути правдою, якщо цю функцію явно не вимкнув розповсюджувач.

Added in version 3.3.

ssl.HAS_SNI

Чи має бібліотека OpenSSL вбудовану підтримку розширення Індикація імені сервера (як визначено в RFC 6066).

Added in version 3.2.

ssl.HAS_NPN

Чи має бібліотека OpenSSL вбудовану підтримку Узгодження наступного протоколу, як описано в розділі Узгодження протоколу прикладного рівня. Якщо значення true, ви можете використовувати метод SSLContext.set_npn_protocols(), щоб повідомити, які протоколи ви хочете підтримувати.

Added in version 3.3.

ssl.HAS_SSLv2

Чи бібліотека OpenSSL має вбудовану підтримку протоколу SSL 2.0.

Added in version 3.7.

ssl.HAS_SSLv3

Чи має бібліотека OpenSSL вбудовану підтримку протоколу SSL 3.0.

Added in version 3.7.

ssl.HAS_TLSv1

Чи бібліотека OpenSSL має вбудовану підтримку протоколу TLS 1.0.

Added in version 3.7.

ssl.HAS_TLSv1_1

Чи має бібліотека OpenSSL вбудовану підтримку протоколу TLS 1.1.

Added in version 3.7.

ssl.HAS_TLSv1_2

Чи бібліотека OpenSSL має вбудовану підтримку протоколу TLS 1.2.

Added in version 3.7.

ssl.HAS_TLSv1_3

Чи має бібліотека OpenSSL вбудовану підтримку протоколу TLS 1.3.

Added in version 3.7.

ssl.CHANNEL_BINDING_TYPES

Список підтримуваних типів прив’язки каналу TLS. Рядки в цьому списку можна використовувати як аргументи для SSLSocket.get_channel_binding().

Added in version 3.3.

ssl.OPENSSL_VERSION

Рядок версії бібліотеки OpenSSL, завантажений інтерпретатором:

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

Added in version 3.2.

ssl.OPENSSL_VERSION_INFO

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

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

Added in version 3.2.

ssl.OPENSSL_VERSION_NUMBER

Необроблений номер версії бібліотеки OpenSSL у вигляді одного цілого числа:

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

Added in version 3.2.

ssl.ALERT_DESCRIPTION_HANDSHAKE_FAILURE
ssl.ALERT_DESCRIPTION_INTERNAL_ERROR
ALERT_DESCRIPTION_*

Описи сповіщень від RFC 5246 та інших. Реєстр сповіщень IANA TLS містить цей список і посилання на RFC, де визначено їх значення.

Використовується як значення, що повертається функцією зворотного виклику в SSLContext.set_servername_callback().

Added in version 3.4.

class ssl.AlertDescription

enum.IntEnum колекція констант ALERT_DESCRIPTION_*.

Added in version 3.6.

Purpose.SERVER_AUTH

Опція для create_default_context() і SSLContext.load_default_certs(). Це значення вказує на те, що контекст можна використовувати для автентифікації веб-серверів (отже, він використовуватиметься для створення сокетів на стороні клієнта).

Added in version 3.4.

Purpose.CLIENT_AUTH

Опція для create_default_context() і SSLContext.load_default_certs(). Це значення вказує на те, що контекст можна використовувати для автентифікації веб-клієнтів (отже, він використовуватиметься для створення сокетів на стороні сервера).

Added in version 3.4.

class ssl.SSLErrorNumber

enum.IntEnum колекція констант SSL_ERROR_*.

Added in version 3.6.

class ssl.TLSVersion

enum.IntEnum колекція версій SSL і TLS для SSLContext.maximum_version і SSLContext.minimum_version.

Added in version 3.7.

TLSVersion.MINIMUM_SUPPORTED
TLSVersion.MAXIMUM_SUPPORTED

Мінімальна або максимальна підтримувана версія SSL або TLS. Це магічні константи. Їх значення не відображають найнижчу та найвищу доступні версії TLS/SSL.

TLSVersion.SSLv3
TLSVersion.TLSv1
TLSVersion.TLSv1_1
TLSVersion.TLSv1_2
TLSVersion.TLSv1_3

SSL 3.0 до TLS 1.3.

Застаріло починаючи з версії 3.10: Усі члени TLSVersion, крім TLSVersion.TLSv1_2 і TLSVersion.TLSv1_3, застаріли.

SSL-сокети

class ssl.SSLSocket(socket.socket)

SSL-сокети надають такі методи Об’єкти Socket:

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

Примірники SSLSocket повинні бути створені за допомогою методу SSSLContext.wrap_socket().

Змінено в версії 3.5: Додано метод sendfile().

Змінено в версії 3.5: The shutdown() does not reset the socket timeout each time bytes are received or sent. The socket timeout is now the maximum total duration of the shutdown.

Застаріло починаючи з версії 3.6: Безпосереднє створення екземпляра SSLSocket є застарілим, використовуйте SSSLContext.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: The socket timeout is no longer reset each time bytes are received or sent. The socket timeout is now the maximum total duration to read up to len bytes.

Застаріло починаючи з версії 3.6: Використовуйте recv() замість read().

SSLSocket.write(buf)

Запишіть buf у SSL-сокет і поверніть кількість записаних байтів. Аргумент buf має бути об’єктом, що підтримує інтерфейс буфера.

Викликайте SSLWantReadError або SSLWantWriteError, якщо сокет неблокує, і запис буде заблоковано.

Оскільки в будь-який час можливе повторне узгодження, виклик write() також може викликати операції читання.

Змінено в версії 3.5: The socket timeout is no longer reset each time bytes are received or sent. The socket timeout is now the maximum total duration to write 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: The socket timeout is no longer reset each time bytes are received or sent. The socket timeout is now the maximum total duration of the handshake.

Змінено в версії 3.7: Hostname or IP address is matched by OpenSSL during handshake. The function match_hostname() is no longer used. In case OpenSSL refuses a hostname or IP address, the handshake is aborted early and a TLS alert message is sent to the peer.

SSLSocket.getpeercert(binary_form=False)

Якщо немає сертифіката для вузла на іншому кінці з’єднання, поверніть None. Якщо SSL-рукостискання ще не виконано, підніміть ValueError.

Якщо параметр binary_form має значення False, а сертифікат отримано від однорангового пристрою, цей метод повертає екземпляр dict. Якщо сертифікат не підтверджено, dict порожній. Якщо сертифікат перевірено, він повертає 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).

See also SSLContext.check_hostname.

Змінено в версії 3.2: Повернений словник містить додаткові елементи, такі як issuer і notBefore.

Змінено в версії 3.4: ValueError виникає, коли рукостискання не виконано. Повернений словник містить додаткові елементи розширення X509v3, такі як crlDistributionPoints, caIssuers і OCSP URI.

Змінено в версії 3.9: Рядки адрес IPv6 більше не мають кінцевого нового рядка.

SSLSocket.cipher()

Повертає кортеж із трьох значень, що містить назву шифру, який використовується, версію протоколу SSL, яка визначає його використання, і кількість секретних бітів, які використовуються. Якщо з’єднання не встановлено, повертає None.

SSLSocket.shared_ciphers()

Return the list of ciphers available in both the client and server. Each entry of the returned list is a three-value tuple containing the name of the cipher, the version of the SSL protocol that defines its use, and the number of secret bits the cipher uses. shared_ciphers() returns None if no connection has been established or the socket is a client socket.

Added in version 3.5.

SSLSocket.compression()

Повертає використаний алгоритм стиснення у вигляді рядка або None, якщо з’єднання не стиснуте.

Якщо протокол вищого рівня підтримує власний механізм стиснення, ви можете використовувати OP_NO_COMPRESSION, щоб вимкнути стиснення на рівні SSL.

Added in version 3.3.

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

Отримайте дані прив’язки каналу для поточного з’єднання як об’єкт bytes. Повертає None, якщо немає підключення або рукостискання не було завершено.

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

Added in version 3.3.

SSLSocket.selected_alpn_protocol()

Повернути протокол, вибраний під час рукостискання TLS. Якщо SSLContext.set_alpn_protocols() не було викликано, якщо інша сторона не підтримує ALPN, якщо цей сокет не підтримує жодного із запропонованих клієнтом протоколів або якщо рукостискання ще не відбулося, None буде повернувся.

Added in version 3.5.

SSLSocket.selected_npn_protocol()

Повернути протокол вищого рівня, вибраний під час рукостискання TLS/SSL. Якщо SSLContext.set_npn_protocols() не було викликано, або якщо інша сторона не підтримує NPN, або якщо рукостискання ще не відбулося, це поверне None.

Added in version 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.

Added in version 3.8.

SSLSocket.version()

Повертає фактичну версію протоколу SSL, узгоджену з’єднанням, у вигляді рядка або «Немає», якщо безпечне з’єднання не встановлено. На момент написання цієї статті можливі значення, що повертаються, включають "SSLv2", "SSLv3", "TLSv1", "TLSv1.1" і "TLSv1.2". Останні версії OpenSSL можуть визначати більше значень, що повертаються.

Added in version 3.5.

SSLSocket.pending()

Повертає кількість уже розшифрованих байтів, доступних для читання, які очікують підключення.

SSLSocket.context

The SSLContext object this SSL socket is tied to.

Added in version 3.2.

SSLSocket.server_side

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

Added in version 3.2.

SSLSocket.server_hostname

Ім’я хоста сервера: тип str або None для серверного сокета або якщо ім’я хосту не було вказано в конструкторі.

Added in version 3.2.

Змінено в версії 3.7: Тепер атрибут завжди є текстом ASCII. Якщо server_hostname є інтернаціоналізованим доменним іменем (IDN), цей атрибут тепер зберігає форму A-мітки ("xn--pythn-mua.org"), а не форму U-мітки ("pythön.org").

SSLSocket.session

SSLSession для цього з’єднання SSL. Сеанс доступний для сокетів на стороні клієнта та сервера після того, як було виконано рукостискання TLS. Для клієнтських сокетів сеанс можна встановити до виклику do_handshake() для повторного використання сеансу.

Added in version 3.6.

SSLSocket.session_reused

Added in version 3.6.

Контексти SSL

Added in version 3.2.

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

class ssl.SSLContext(protocol=None)

Створіть новий контекст SSL. Ви можете передати протокол, який має бути однією з констант PROTOCOL_*, визначених у цьому модулі. Параметр визначає, яку версію протоколу SSL використовувати. Як правило, сервер вибирає певну версію протоколу, а клієнт повинен адаптуватися до вибору сервера. Більшість версій не сумісні з іншими версіями. Якщо не вказано, типовим є PROTOCOL_TLS; він забезпечує найбільшу сумісність з іншими версіями.

Ось таблиця, яка показує, які версії клієнта (збоку) можуть підключатися до яких версій на сервері (вгорі):

клієнт / сервер

SSLv2

SSLv3

TLS [3]

TLSv1

TLSv1.1

TLSv1.2

SSLv2

так

ні

ні [1]

ні

ні

ні

SSLv3

ні

так

ні [2]

ні

ні

ні

TLS (SSLv23) [3]

ні [1]

ні [2]

так

так

так

так

TLSv1

ні

ні

так

так

ні

ні

TLSv1.1

ні

ні

так

ні

так

ні

TLSv1.2

ні

ні

так

ні

ні

так

Виноски

Дивись також

create_default_context() дозволяє модулю ssl вибрати параметри безпеки для певної мети.

Змінено в версії 3.6: The context is created with secure default values. The options OP_NO_COMPRESSION, OP_CIPHER_SERVER_PREFERENCE, OP_SINGLE_DH_USE, OP_SINGLE_ECDH_USE, OP_NO_SSLv2, and OP_NO_SSLv3 (except for PROTOCOL_SSLv3) are set by default. The initial cipher suite list contains only HIGH ciphers, no NULL ciphers and no MD5 ciphers.

Застаріло починаючи з версії 3.10: SSLContext без аргументу протоколу застаріло. У майбутньому клас контексту потребуватиме протоколу PROTOCOL_TLS_CLIENT або PROTOCOL_TLS_SERVER.

Змінено в версії 3.10: Набір шифрів за замовчуванням тепер включає лише захищені шифри AES і ChaCha20 із прямою секретністю та рівнем безпеки 2. Ключі RSA та DH із менш ніж 2048 бітами та ключі ECC із менш ніж 224 бітами заборонені. PROTOCOL_TLS, PROTOCOL_TLS_CLIENT і PROTOCOL_TLS_SERVER використовують TLS 1.2 як мінімальну версію TLS.

SSLContext об’єкти мають такі методи та атрибути:

SSLContext.cert_store_stats()

Отримайте статистичні дані про кількість завантажених сертифікатів X.509, кількість сертифікатів X.509, позначених як сертифікати ЦС, і списки відкликаних сертифікатів як словник.

Приклад для контексту з одним сертифікатом CA та одним іншим сертифікатом:

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

Added in version 3.4.

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

Завантажте закритий ключ і відповідний сертифікат. Рядок certfile має бути шляхом до одного файлу у форматі PEM, що містить сертифікат, а також будь-яку кількість сертифікатів ЦС, необхідних для встановлення автентичності сертифіката. Рядок keyfile, якщо він присутній, має вказувати на файл, що містить закритий ключ. Інакше закритий ключ також буде взято з certfile. Перегляньте обговорення Сертифікати для отримання додаткової інформації про те, як сертифікат зберігається у certfile.

Аргумент password може бути функцією для виклику, щоб отримати пароль для розшифровки закритого ключа. Він буде викликаний, лише якщо закритий ключ зашифрований і потрібен пароль. Він буде викликаний без аргументів і повинен повернути рядок, байти або масив байтів. Якщо значення, що повертається, є рядком, воно буде закодовано як UTF-8 перед використанням для розшифровки ключа. Крім того, значення рядка, байтів або масиву байтів можна надати безпосередньо як аргумент пароль. Він буде проігнорований, якщо закритий ключ не зашифрований і пароль не потрібен.

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

SSLError виникає, якщо закритий ключ не збігається з сертифікатом.

Змінено в версії 3.3: Новий необов’язковий аргумент пароль.

SSLContext.load_default_certs(purpose=Purpose.SERVER_AUTH)

Завантажте набір стандартних сертифікатів «центру сертифікації» (CA) із стандартних розташувань. У Windows він завантажує сертифікати ЦС із системних сховищ CA і ROOT. У всіх системах він викликає SSLContext.set_default_verify_paths(). У майбутньому цей метод може також завантажувати сертифікати ЦС з інших місць.

The purpose flag specifies what kind of CA certificates are loaded. The default settings Purpose.SERVER_AUTH loads certificates, that are flagged and trusted for TLS web server authentication (client side sockets). Purpose.CLIENT_AUTH loads CA certificates for client certificate verification on the server side.

Added in version 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, якщо він присутній, є шляхом до файлу об’єднаних сертифікатів ЦС у форматі PEM. Перегляньте обговорення Сертифікати для отримання додаткової інформації про те, як упорядкувати сертифікати в цьому файлі.

Рядок capath, якщо він присутній, є шляхом до каталогу, що містить кілька сертифікатів ЦС у форматі PEM, відповідно до спеціального макета OpenSSL.

Об’єкт cadata, якщо він присутній, є рядком ASCII одного чи кількох сертифікатів у кодуванні PEM або bytes-like object сертифікатів у кодуванні DER. Подібно до capath додаткові рядки навколо PEM-кодованих сертифікатів ігноруються, але принаймні один сертифікат має бути присутнім.

Змінено в версії 3.4: Новий необов’язковий аргумент cadata

SSLContext.get_ca_certs(binary_form=False)

Отримайте список завантажених сертифікатів «центру сертифікації» (CA). Якщо параметр binary_form має значення False, кожен запис у списку є диктофоном, подібним до результату SSLSocket.getpeercert(). В іншому випадку метод повертає список сертифікатів, закодованих DER. Повернений список не містить сертифікатів від capath, якщо тільки сертифікат не було запитано та завантажено через підключення SSL.

Примітка

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

Added in version 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'}]

Added in version 3.6.

SSLContext.set_default_verify_paths()

Завантажте набір стандартних сертифікатів «центру сертифікації» (CA) із шляху файлової системи, визначеного під час створення бібліотеки OpenSSL. На жаль, немає простого способу дізнатися, чи цей метод успішний: помилка не повертається, якщо сертифікати не знайдені. Однак, коли бібліотека OpenSSL надається як частина операційної системи, вона, швидше за все, буде налаштована належним чином.

SSLContext.set_ciphers(ciphers)

Встановіть доступні шифри для сокетів, створених із цим контекстом. Це має бути рядок у форматі списку шифрів OpenSSL. Якщо жоден шифр не може бути обраний (оскільки параметри під час компіляції чи інша конфігурація забороняють використовувати всі вказані шифри), буде викликано SSLError.

Примітка

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

Набори шифрів TLS 1.3 не можна вимкнути за допомогою set_ciphers().

SSLContext.set_alpn_protocols(protocols)

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

Цей метод викличе NotImplementedError, якщо HAS_ALPN має значення False.

Added in version 3.5.

SSLContext.set_npn_protocols(protocols)

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

Цей метод викличе NotImplementedError, якщо HAS_NPN має значення False.

Added in version 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").

Типовим використанням цього зворотного виклику є зміна атрибута SSLSocket.context ssl.SSLSocket на новий об’єкт типу SSLContext, який представляє ланцюжок сертифікатів, який відповідає імені сервера .

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

Функція sni_callback має повертати None, щоб узгодження TLS продовжилося. Якщо потрібна помилка TLS, можна повернути константу ALERT_DESCRIPTION_*. Інші значення, що повертаються, призведуть до фатальної помилки TLS із ALERT_DESCRIPTION_INTERNAL_ERROR.

Якщо функція sni_callback викликає виняток, TLS-з’єднання буде розірвано з небезпечним TLS-повідомленням ALERT_DESCRIPTION_HANDSHAKE_FAILURE.

Цей метод викличе NotImplementedError, якщо під час створення бібліотеки OpenSSL було визначено OPENSSL_NO_TLSEXT.

Added in version 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.

Added in version 3.4.

SSLContext.load_dh_params(dhfile)

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

Цей параметр не застосовується до клієнтських сокетів. Ви також можете використовувати параметр OP_SINGLE_DH_USE для подальшого покращення безпеки.

Added in version 3.3.

SSLContext.set_ecdh_curve(curve_name)

Встановіть назву кривої для обміну ключами Діффі-Хеллмана (ECDH) на основі еліптичної кривої. ECDH значно швидший, ніж звичайний DH, але, можливо, такий же безпечний. Параметр curve_name має бути рядком, що описує добре відому еліптичну криву, наприклад prime256v1 для широко підтримуваної кривої.

Цей параметр не застосовується до клієнтських сокетів. Ви також можете використовувати опцію OP_SINGLE_ECDH_USE для подальшого покращення безпеки.

Цей метод недоступний, якщо HAS_ECDH має значення False.

Added in version 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)

Wrap an existing Python socket sock and return an instance of SSLContext.sslsocket_class (default SSLSocket). The returned SSL socket is tied to the context, its settings and certificates. sock must be a SOCK_STREAM socket; other socket types are unsupported.

Параметр server_side є логічним значенням, яке визначає, яка поведінка для цього сокета – серверна чи клієнтська.

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

У клієнтських з’єднаннях необов’язковий параметр server_hostname визначає ім’я хоста служби, до якої ми під’єднуємося. Це дозволяє одному серверу розміщувати кілька служб на основі SSL з окремими сертифікатами, подібно до віртуальних хостів HTTP. Якщо вказати server_hostname, виникне ValueError, якщо server_side має значення true.

Параметр do_handshake_on_connect визначає, чи виконувати SSL-рукостискання автоматично після виконання socket.connect(), чи прикладна програма викличе його явно, викликаючи метод SSLSocket.do_handshake(). Виклик SSLSocket.do_handshake() явно дає програмі контроль над поведінкою блокування вводу-виводу сокета, залученого до рукостискання.

Параметр suppress_ragged_eofs визначає, як метод SSLSocket.recv() повинен сигналізувати про неочікуваний EOF з іншого боку з’єднання. Якщо вказано як True (за замовчуванням), він повертає звичайний EOF (порожній об’єкт байтів) у відповідь на неочікувані помилки EOF, викликані базовим сокетом; якщо False, винятки повертаються до абонента.

сеанс, див. session.

To wrap an SSLSocket in another SSLSocket, use SSLContext.wrap_bio().

Змінено в версії 3.5: Завжди дозволяйте передачу server_hostname, навіть якщо OpenSSL не має SNI.

Змінено в версії 3.6: Додано аргумент сеанс.

Змінено в версії 3.7: The method returns an instance of SSLContext.sslsocket_class instead of hard-coded SSLSocket.

SSLContext.sslsocket_class

Тип повернення SSLContext.wrap_socket() за замовчуванням SSLSocket. Атрибут можна перевизначити в екземплярі класу, щоб повернути настроюваний підклас SSLSocket.

Added in version 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: Додано аргумент сеанс.

Змінено в версії 3.7: The method returns an instance of SSLContext.sslobject_class instead of hard-coded SSLObject.

SSLContext.sslobject_class

Тип повернення SSLContext.wrap_bio() за замовчуванням SSLObject. Атрибут можна перевизначити в екземплярі класу, щоб повернути настроюваний підклас SSLObject.

Added in version 3.7.

SSLContext.session_stats()

Get statistics about the SSL sessions created or managed by this context. A dictionary is returned which maps the names of each piece of information to their numeric values. For example, here is the total number of hits and misses in the session cache since the context was created:

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

Added in version 3.4.

Змінено в версії 3.7: verify_mode тепер автоматично змінюється на CERT_REQUIRED, коли перевірку імені хоста ввімкнено, а verify_mode має значення CERT_NONE. Раніше ця сама операція не виконувалася з помилкою ValueError.

SSLContext.keylog_filename

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

Added in version 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 підключення.

Added in version 3.7.

SSLContext.minimum_version

Як SSLContext.maximum_version, за винятком того, що це найнижча підтримувана версія або TLSVersion.MINIMUM_SUPPORTED.

Added in version 3.7.

SSLContext.num_tickets

Контролюйте кількість квитків сесії TLS 1.3 контексту PROTOCOL_TLS_SERVER. Параметр не впливає на підключення TLS 1.0 до 1.2.

Added in version 3.8.

SSLContext.options

Ціле число, що представляє набір параметрів SSL, увімкнених у цьому контексті. Стандартним значенням є OP_ALL, але ви можете вказати інші параметри, наприклад OP_NO_SSLv2, об’єднавши їх разом.

Змінено в версії 3.6: SSLContext.options повертає прапорці Options:

>>> ssl.create_default_context().options  
<Options.OP_ALL|OP_NO_SSLv3|OP_NO_SSLv2|OP_NO_COMPRESSION: 2197947391>

Застаріло починаючи з версії 3.7: Усі параметри OP_NO_SSL* і OP_NO_TLS* стали застарілими з Python 3.7. Замість цього використовуйте SSLContext.minimum_version і SSLContext.maximum_version.

SSLContext.post_handshake_auth

Увімкнути автентифікацію клієнта після рукостискання TLS 1.3. Автентифікація після рукостискання вимкнена за замовчуванням, і сервер може запитувати сертифікат клієнта TLS лише під час початкового рукостискання. Якщо ввімкнено, сервер може запитувати сертифікат клієнта TLS у будь-який час після рукостискання.

Якщо ввімкнено на сокетах на стороні клієнта, клієнт сигналізує серверу, що він підтримує автентифікацію після рукостискання.

Якщо ввімкнено на серверних сокетах, SSLContext.verify_mode також має бути встановлено на CERT_OPTIONAL або CERT_REQUIRED. Фактичний обмін сертифікатами клієнта відкладено, доки не буде викликано SSLSocket.verify_client_post_handshake() і не буде виконано деякий ввід-вивід.

Added in version 3.8.

SSLContext.protocol

Версія протоколу, обрана під час побудови контексту. Цей атрибут доступний лише для читання.

SSLContext.hostname_checks_common_name

Чи повертається check_hostname для перевірки загальної назви суб’єкта сертифіката за відсутності альтернативного розширення імені суб’єкта (за умовчанням: істина).

Added in version 3.7.

Змінено в версії 3.10: The flag had no effect with OpenSSL before version 1.1.1l. Python 3.8.9, 3.9.3, and 3.10 include workarounds for previous versions.

SSLContext.security_level

Ціле число, що представляє рівень безпеки для контексту. Цей атрибут доступний лише для читання.

Added in version 3.10.

SSLContext.verify_flags

Прапори для операцій перевірки сертифіката. Ви можете встановити такі прапорці, як VERIFY_CRL_CHECK_LEAF, об’єднавши їх разом. За замовчуванням OpenSSL не вимагає і не перевіряє списки відкликаних сертифікатів (CRL).

Added in version 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 enum:

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

Сертифікати

Загалом сертифікати є частиною системи відкритого/приватного ключа. У цій системі кожному принципалу (яким може бути машина, або особа, або організація) призначається унікальний ключ шифрування, що складається з двох частин. Одна частина ключа є відкритою і називається відкритим ключем; інша частина зберігається в таємниці та називається приватним ключем. Ці дві частини пов’язані між собою, оскільки якщо ви зашифровуєте повідомлення за допомогою однієї з частин, ви можете розшифрувати його за допомогою іншої частини та тільки за допомогою іншої частини.

Сертифікат містить інформацію про двох принципалів. Він містить назву суб’єкта та відкритий ключ суб’єкта. Він також містить заяву другого принципала, емітента, про те, що суб’єкт є тим, за кого себе видає, і що це справді відкритий ключ суб’єкта. Заява емітента підписується закритим ключем емітента, який відомий лише емітенту. Проте будь-хто може перевірити заяву емітента, знайшовши відкритий ключ емітента, розшифрувавши за його допомогою заяву та порівнявши її з іншою інформацією в сертифікаті. Сертифікат також містить інформацію про термін його дії. Це виражається двома полями, які називаються «notBefore» і «notAfter».

При використанні сертифікатів Python клієнт або сервер можуть використовувати сертифікат, щоб підтвердити, ким вони є. Інша сторона мережевого з’єднання також може вимагати створення сертифіката, і цей сертифікат може бути перевірений відповідно до вимог клієнта або сервера, які потребують такої перевірки. Спробу підключення можна налаштувати так, щоб викликати виняток, якщо перевірка не вдається. Перевірка виконується автоматично базовою структурою OpenSSL; програмі не потрібно займатися своєю механікою. Але програмі зазвичай потрібно надати набори сертифікатів, щоб дозволити цей процес.

Python використовує файли для зберігання сертифікатів. Вони повинні бути відформатовані як «PEM» (див. RFC 1422), який є формою, закодованою на базі 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-----

сертифікати ЦС

Якщо ви збираєтеся вимагати підтвердження іншої сторони сертифіката з’єднання, вам потрібно надати файл «сертифікатів ЦС», заповнений ланцюжками сертифікатів для кожного видавця, якому ви готові довіряти. Знову ж таки, цей файл містить ці ланцюжки, об’єднані разом. Для перевірки Python використовуватиме перший ланцюжок, знайдений у файлі, який відповідає. Файл сертифікатів платформи можна використовувати, викликавши SSLContext.load_default_certs(), це робиться автоматично за допомогою create_default_context().

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

Often the private key is stored in the same file as the certificate; in this case, only the certfile parameter to SSLContext.load_cert_chain() needs to be passed. If the private key is stored with the certificate, it should come before the first certificate in the certificate chain:

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

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

Якщо ви збираєтеся створити сервер, який надає послуги з’єднання з шифруванням SSL, вам потрібно буде отримати сертифікат для цієї послуги. Є багато способів отримати відповідні сертифікати, наприклад придбати сертифікат в центрі сертифікації. Іншою поширеною практикою є створення самопідписаного сертифіката. Найпростіший спосіб зробити це за допомогою пакета OpenSSL, використовуючи щось на зразок наступного:

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

Недоліком самопідписаного сертифіката є те, що це його власний кореневий сертифікат, і ніхто інший не матиме його в кеш-пам’яті відомих (і надійних) кореневих сертифікатів.

Приклади

Тестування підтримки SSL

Щоб перевірити наявність підтримки SSL у встановленому Python, код користувача має використовувати таку ідіому:

try:
    import ssl
except ImportError:
    pass
else:
    ...  # do something that requires SSL support

Робота на стороні клієнта

У цьому прикладі створюється контекст SSL із рекомендованими налаштуваннями безпеки для клієнтських сокетів, включаючи автоматичну перевірку сертифіката:

>>> context = ssl.create_default_context()

Якщо ви бажаєте налаштувати параметри безпеки самостійно, ви можете створити контекст з нуля (але пам’ятайте, що ви можете неправильно встановити параметри):

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

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

Протокол PROTOCOL_TLS_CLIENT налаштовує контекст для перевірки сертифіката та перевірки імені хоста. verify_mode встановлено на CERT_REQUIRED, а check_hostname встановлено на True. Усі інші протоколи створюють контексти SSL із незахищеними значеннями за умовчанням.

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

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

Потім ви можете отримати сертифікат:

>>> cert = conn.getpeercert()

Візуальна перевірка показує, що сертифікат ідентифікує потрібну службу (тобто хост HTTPS www.python.org):

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

Тепер SSL-канал встановлено та сертифікат перевірено, ви можете продовжити спілкування з сервером:

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

Дивіться обговорення Міркування безпеки нижче.

Робота на стороні сервера

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

import socket, ssl

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

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

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

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

Потім ви будете читати дані з connstream і щось робити з ними, поки не закінчите роботу з клієнтом (або клієнт не закінчить роботу з вами):

def deal_with_client(connstream):
    data = connstream.recv(1024)
    # empty data means the client is finished with us
    while data:
        if not do_something(connstream, data):
            # we'll assume do_something returns False
            # when we're finished with client
            break
        data = connstream.recv(1024)
    # finished with client

І поверніться до прослуховування нових клієнтських з’єднань (звичайно, реальний сервер, ймовірно, оброблятиме кожне клієнтське з’єднання в окремому потоці або переведе сокети в неблокуючий режим і використає цикл подій).

Примітки щодо неблокуючих розеток

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

  • Більшість методів SSLSocket викликають або SSLWantWriteError, або SSLWantReadError замість BlockingIOError, якщо операція вводу/виводу буде заблокована. SSLWantReadError буде викликано, якщо операція читання базового сокета є необхідною, і SSLWantWriteError для операції запису базового сокета. Зауважте, що спроби запису в сокет SSL можуть вимагати спочатку читання з базового сокета, а спроби читання з сокета SSL можуть вимагати попереднього запису в базовий сокет.

    Змінено в версії 3.5: У попередніх версіях Python метод SSLSocket.send() повертав нуль замість того, щоб викликати SSLWantWriteError або SSLWantReadError.

  • Виклик select() повідомляє вам, що сокет рівня ОС можна зчитувати (або записувати), але це не означає, що на верхньому рівні SSL достатньо даних. Наприклад, могла надійти лише частина кадру SSL. Таким чином, ви повинні бути готові впоратися з помилками SSLSocket.recv() і SSLSocket.send() і повторити спробу після іншого виклику select().

  • І навпаки, оскільки рівень SSL має власне фреймування, сокет SSL все ще може мати дані, доступні для читання, не знаючи про це select(). Таким чином, ви повинні спочатку викликати SSLSocket.recv(), щоб вичерпати будь-які потенційно доступні дані, а потім лише заблокувати виклик select(), якщо все ще необхідно.

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

  • Саме рукостискання SSL буде неблокуючим: метод SSLSocket.do_handshake() потрібно повторити, поки він не повернеться успішно. Ось короткий опис використання select() для очікування готовності сокета:

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

Дивись також

Модуль asyncio підтримує неблокуючі сокети SSL і забезпечує API вищого рівня. Він опитує події за допомогою модуля selectors і обробляє винятки SSLWantWriteError, SSLWantReadError і BlockingIOError. Він також запускає рукостискання SSL асинхронно.

Підтримка BIO пам’яті

Added in version 3.5.

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

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

  • Мережа IO

Мережевий IO API ідентичний тому, який надає socket.socket, від якого також успадковується SSLSocket. Це дозволяє використовувати сокет SSL як додаткову заміну звичайного сокета, що дозволяє дуже легко додати підтримку SSL до існуючої програми.

Поєднання обробки протоколу SSL і мережевого введення-виведення зазвичай працює добре, але в деяких випадках це не так. Прикладом є асинхронні структури вводу-виводу, які хочуть використовувати іншу модель мультиплексування вводу-виводу, ніж модель «вибір/опитування дескриптора файлу» (на основі готовності), яка передбачається socket.socket і внутрішнім вводом-виводом сокета OpenSSL рутини. Це в основному актуально для таких платформ, як Windows, де ця модель не ефективна. Для цього надається зменшений варіант SSLSocket під назвою SSLObject.

class ssl.SSLObject

Зменшений варіант SSLSocket, що представляє екземпляр протоколу SSL, який не містить жодних мережевих методів введення-виведення. Цей клас зазвичай використовується авторами фреймворків, які хочуть реалізувати асинхронний IO для SSL через буфери пам’яті.

Цей клас реалізує інтерфейс поверх об’єкта SSL низького рівня, реалізованого OpenSSL. Цей об’єкт фіксує стан SSL-з’єднання, але сам не надає мережевий IO. IO потрібно виконувати через окремі об’єкти «BIO», які є рівнем абстракції IO OpenSSL.

Цей клас не має публічного конструктора. Екземпляр SSLObject має бути створений за допомогою методу wrap_bio(). Цей метод створить екземпляр SSLObject і прив’яже його до пари BIO. Вхідний BIO використовується для передачі даних від Python до примірника протоколу SSL, тоді як вихідний BIO використовується для передачі даних навпаки.

Доступні такі методи:

У порівнянні з SSLSocket цьому об’єкту бракує наступних функцій:

  • Будь-яка форма мережевого вводу-виводу; recv() і send() читають і записують лише в базові буфери MemoryBIO.

  • Не існує механізму do_handshake_on_connect. Ви завжди повинні вручну викликати do_handshake(), щоб почати рукостискання.

  • Немає обробки suppress_ragged_eofs. Усі умови кінця файлу, які порушують протокол, повідомляються через виняток SSLEOFError.

  • Виклик методу unwrap() нічого не повертає, на відміну від сокета SSL, де він повертає основний сокет.

  • Зворотний виклик server_name_callback, переданий SSLContext.set_servername_callback(), отримає екземпляр SSLObject замість екземпляра SSLSocket як перший параметр.

Деякі зауваження щодо використання SSLObject:

Змінено в версії 3.7: SSLObject instances must be created with wrap_bio(). In earlier versions, it was possible to create instances directly. This was never documented or officially supported.

SSLObject спілкується із зовнішнім світом за допомогою буферів пам’яті. Клас MemoryBIO забезпечує буфер пам’яті, який можна використовувати для цієї мети. Він обертає об’єкт BIO пам’яті OpenSSL (Basic IO):

class ssl.MemoryBIO

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

pending

Повертає кількість байтів у буфері пам’яті.

eof

Логічне значення, яке вказує, чи є BIO пам’яті поточним у позиції кінця файлу.

read(n=-1)

Прочитати до n байт із буфера пам’яті. Якщо n не вказано або має негативне значення, повертаються всі байти.

write(buf)

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

Поверненим значенням є кількість записаних байтів, яка завжди дорівнює довжині buf.

write_eof()

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

Сеанс SSL

Added in version 3.6.

class ssl.SSLSession

Об’єкт сеансу, який використовує session.

id
time
timeout
ticket_lifetime_hint
has_ticket

Міркування безпеки

Найкращі параметри за замовчуванням

Для користування клієнтом, якщо у вас немає особливих вимог до вашої політики безпеки, настійно рекомендується використовувати функцію create_default_context() для створення контексту SSL. Він завантажить довірені сертифікати ЦС системи, увімкне перевірку сертифіката та перевірку імені хоста, а також спробує вибрати достатньо безпечний протокол і налаштування шифру.

Наприклад, ось як можна використовувати клас smtplib.SMTP для створення надійного безпечного з’єднання з сервером SMTP:

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

Якщо для підключення потрібен сертифікат клієнта, його можна додати за допомогою SSSLContext.load_cert_chain().

Навпаки, якщо ви створюєте контекст SSL, викликаючи конструктор SSLContext самостійно, за замовчуванням не буде ввімкнено ні перевірку сертифіката, ні перевірку імені хоста. Якщо ви це зробите, будь ласка, прочитайте параграфи нижче, щоб досягти хорошого рівня безпеки.

Ручні налаштування

Перевірка сертифікатів

When calling the SSLContext constructor directly, CERT_NONE is the default. Since it does not authenticate the other peer, it can be insecure, especially in client mode where most of time you would like to ensure the authenticity of the server you’re talking to. Therefore, when in client mode, it is highly recommended to use CERT_REQUIRED. However, it is in itself not sufficient; you also have to check that the server certificate, which can be obtained by calling SSLSocket.getpeercert(), matches the desired service. For many protocols and applications, the service can be identified by the hostname. This common check is automatically performed when SSLContext.check_hostname is enabled.

Змінено в версії 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

The SSL context created above will only allow TLSv1.3 and later (if supported by your system) connections to a server. PROTOCOL_TLS_CLIENT implies certificate validation and hostname checks by default. You have to load certificates into the context.

Вибір шифру

If you have advanced security requirements, fine-tuning of the ciphers enabled when negotiating a SSL session is possible through the SSLContext.set_ciphers() method. Starting from Python 3.2.3, the ssl module disables certain weak ciphers by default, but you may want to further restrict the cipher choice. Be sure to read OpenSSL’s documentation about the cipher list format. If you want to check which ciphers are enabled by a given cipher list, use SSLContext.get_ciphers() or the openssl ciphers command on your system.

Багатопроцесорність

If using this module as part of a multi-processed application (using, for example the multiprocessing or concurrent.futures modules), be aware that OpenSSL’s internal random number generator does not properly handle forked processes. Applications must change the PRNG state of the parent process if they use any SSL feature with os.fork(). Any successful call of RAND_add() or RAND_bytes() is sufficient.

TLS 1.3

Added in version 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, конфігурація алгоритму підпису та повторне введення ключів, ще не підтримуються.