ssl — TLS/SSL wrapper for socket objects

Вихідний код: 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.1 and TLSv1.2 come with openssl version 1.0.1.

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

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

У цьому розділі описано об’єкти та функції модуля ssl; для отримання більш загальної інформації про TLS, SSL і сертифікати, читач буде направлено до документів у розділі «Див. також» внизу.

This module provides a class, ssl.SSLSocket, which is derived from the socket.socket type, and provides a socket-like wrapper that also encrypts and decrypts the data going over the socket with SSL. It supports additional methods such as getpeercert(), which retrieves the certificate of the other side of the connection, and cipher(), which retrieves the cipher being used for the secure connection.

Для складніших програм клас 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.

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

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

Since Python 3.2 and 2.7.9, it is recommended to use the SSLContext.wrap_socket() of an SSLContext instance to wrap sockets as SSLSocket objects. The helper functions create_default_context() returns a new context with secure default settings. The old wrap_socket() function is deprecated since it is both inefficient and has no support for server name indication (SNI) and hostname matching.

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

Нове в версії 3.4.

Змінено в версії 3.4.4: RC4 було видалено з рядка шифру за замовчуванням.

Змінено в версії 3.6: ChaCha20/Poly1305 додано до рядка шифру за замовчуванням.

3DES було видалено з рядка шифру за замовчуванням.

Змінено в версії 3.8: Додано підтримку реєстрації ключів у SSLKEYLOGFILE.

Винятки

exception ssl.SSLError

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

Змінено в версії 3.3: SSLError раніше був підтипом socket.error.

library

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

Нове в версії 3.3.

reason

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

Нове в версії 3.3.

exception ssl.SSLZeroReturnError

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

Нове в версії 3.3.

exception ssl.SSLWantReadError

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

Нове в версії 3.3.

exception ssl.SSLWantWriteError

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

Нове в версії 3.3.

exception ssl.SSLSyscallError

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

Нове в версії 3.3.

exception ssl.SSLEOFError

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

Нове в версії 3.3.

exception ssl.SSLCertVerificationError

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

Нове в версії 3.7.

verify_code

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

verify_message

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

exception ssl.CertificateError

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

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

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

ssl.RAND_bytes(num)

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

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

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

Нове в версії 3.3.

ssl.RAND_pseudo_bytes(num)

Return (bytes, is_cryptographic): bytes are num pseudo-random bytes, is_cryptographic is True if the bytes generated are cryptographically strong. Raises an SSLError if the operation is not supported by the current RAND method.

Generated pseudo-random byte sequences will be unique if they are of sufficient length, but are not necessarily unpredictable. They can be used for non-cryptographic purposes and for certain purposes in cryptographic protocols, but usually not for key generation etc.

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

Нове в версії 3.3.

Застаріло починаючи з версії 3.6: OpenSSL has deprecated ssl.RAND_pseudo_bytes(), use ssl.RAND_bytes() instead.

ssl.RAND_status()

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

ssl.RAND_egd(path)

If you are running an entropy-gathering daemon (EGD) somewhere, and path is the pathname of a socket connection open to it, this will read 256 bytes of randomness from the socket, and add it to the SSL pseudo-random number generator to increase the security of generated secret keys. This is typically only necessary on systems without better sources of randomness.

See http://egd.sourceforge.net/ or http://prngd.sourceforge.net/ for sources of entropy-gathering daemons.

Availability: not available with LibreSSL and OpenSSL > 1.1.0.

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.match_hostname(cert, hostname)

Verify that cert (in decoded format as returned by SSLSocket.getpeercert()) matches the given hostname. The rules applied are those for checking the identity of HTTPS servers as outlined in RFC 2818, RFC 5280 and RFC 6125. In addition to HTTPS, this function should be suitable for checking the identity of servers in various SSL-based protocols such as FTPS, IMAPS, POPS and others.

CertificateError is raised on failure. On success, the function returns nothing:

>>> 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: The function now follows RFC 6125, section 6.4.3 and does neither match multiple wildcards (e.g. *.*.com or *a*.example.org) nor a wildcard inside an internationalized domain names (IDN) fragment. IDN A-labels such as www*.xn--pthon-kva.org are still supported, but x*.python.org no longer matches xn--tda.python.org.

Змінено в версії 3.5: Matching of IP addresses, when present in the subjectAltName field of the certificate, is now supported.

Змінено в версії 3.7: The function is no longer used to TLS connections. Hostname matching is now performed by OpenSSL.

Allow wildcard when it is the leftmost and the only character in that segment. Partial wildcards like www*.example.com are no longer supported.

Застаріло починаючи з версії 3.7.

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)

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 same parameter in SSLContext.wrap_socket(). The call will attempt to validate the server certificate against that set of root certificates, and will fail if the validation attempt fails.

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

Availability: LibreSSL ignores the environment vars openssl_cafile_env and 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 для даних X.509 ASN.1, або pkcs_7_asn для даних PKCS#7 ASN.1. Trust визначає призначення сертифіката як набір OIDS або точно True, якщо сертифікат є надійним для всіх цілей.

Приклад:

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

Наявність: Windows.

Нове в версії 3.4.

ssl.enum_crls(store_name)

Отримати CRL із сховища системних сертифікатів Windows. store_name може бути одним із CA, ROOT або MY. Windows також може надавати додаткові сховища сертифікатів.

Функція повертає список кортежів (cert_bytes, encoding_type, trust). Encoding_type визначає кодування cert_bytes. Це або x509_asn для даних X.509 ASN.1, або pkcs_7_asn для даних PKCS#7 ASN.1.

Наявність: Windows.

Нове в версії 3.4.

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

Takes an instance sock of socket.socket, and returns an instance of ssl.SSLSocket, a subtype of socket.socket, which wraps the underlying socket in an SSL context. sock must be a SOCK_STREAM socket; other socket types are unsupported.

Internally, function creates a SSLContext with protocol ssl_version and SSLContext.options set to cert_reqs. If parameters keyfile, certfile, ca_certs or ciphers are set, then the values are passed to SSLContext.load_cert_chain(), SSLContext.load_verify_locations(), and SSLContext.set_ciphers().

The arguments server_side, do_handshake_on_connect, and suppress_ragged_eofs have the same meaning as SSLContext.wrap_socket().

Застаріло починаючи з версії 3.7: Since Python 3.2 and 2.7.9, it is recommended to use the SSLContext.wrap_socket() instead of wrap_socket(). The top-level function is limited and creates an insecure client socket without server name indication or hostname matching.

Константи

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

Нове в версії 3.6.

ssl.CERT_NONE

Possible value for SSLContext.verify_mode, or the cert_reqs parameter to wrap_socket(). 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, or the cert_reqs parameter to wrap_socket(). 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, either to SSLContext.load_verify_locations() or as a value of the ca_certs parameter to wrap_socket().

ssl.CERT_REQUIRED

Possible value for SSLContext.verify_mode, or the cert_reqs parameter to wrap_socket(). 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, either to SSLContext.load_verify_locations() or as a value of the ca_certs parameter to wrap_socket().

class ssl.VerifyMode

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

Нове в версії 3.6.

ssl.VERIFY_DEFAULT

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

Нове в версії 3.4.

ssl.VERIFY_CRL_CHECK_LEAF

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

Нове в версії 3.4.

ssl.VERIFY_CRL_CHECK_CHAIN

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

Нове в версії 3.4.

ssl.VERIFY_X509_STRICT

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

Нове в версії 3.4.

ssl.VERIFY_X509_TRUSTED_FIRST

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

Нове в версії 3.4.4.

class ssl.VerifyFlags

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

Нове в версії 3.6.

ssl.PROTOCOL_TLS

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

Нове в версії 3.6.

ssl.PROTOCOL_TLS_CLIENT

Auto-negotiate the highest protocol version like PROTOCOL_TLS, but only support client-side SSLSocket connections. The protocol enables CERT_REQUIRED and check_hostname by default.

Нове в версії 3.6.

ssl.PROTOCOL_TLS_SERVER

Auto-negotiate the highest protocol version like PROTOCOL_TLS, but only support server-side SSLSocket connections.

Нове в версії 3.6.

ssl.PROTOCOL_SSLv23

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

Застаріло починаючи з версії 3.6: Натомість використовуйте PROTOCOL_TLS.

ssl.PROTOCOL_SSLv2

Selects SSL version 2 as the channel encryption protocol.

This protocol is not available if OpenSSL is compiled with the OPENSSL_NO_SSL2 flag.

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

SSL version 2 is insecure. Its use is highly discouraged.

Застаріло починаючи з версії 3.6: OpenSSL has removed support for SSLv2.

ssl.PROTOCOL_SSLv3

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

This protocol is not be available if OpenSSL is compiled with the OPENSSL_NO_SSLv3 flag.

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

SSL версії 3 небезпечний. Його використання вкрай не рекомендується.

Застаріло починаючи з версії 3.6: OpenSSL has deprecated all version specific protocols. Use the default protocol PROTOCOL_TLS with flags like OP_NO_SSLv3 instead.

ssl.PROTOCOL_TLSv1

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

Застаріло починаючи з версії 3.6: OpenSSL has deprecated all version specific protocols. Use the default protocol PROTOCOL_TLS with flags like OP_NO_SSLv3 instead.

ssl.PROTOCOL_TLSv1_1

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

Нове в версії 3.4.

Застаріло починаючи з версії 3.6: OpenSSL has deprecated all version specific protocols. Use the default protocol PROTOCOL_TLS with flags like OP_NO_SSLv3 instead.

ssl.PROTOCOL_TLSv1_2

Selects TLS version 1.2 as the channel encryption protocol. This is the most modern version, and probably the best choice for maximum protection, if both sides can speak it. Available only with openssl version 1.0.1+.

Нове в версії 3.4.

Застаріло починаючи з версії 3.6: OpenSSL has deprecated all version specific protocols. Use the default protocol PROTOCOL_TLS with flags like OP_NO_SSLv3 instead.

ssl.OP_ALL

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

Нове в версії 3.2.

ssl.OP_NO_SSLv2

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

Нове в версії 3.2.

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

ssl.OP_NO_SSLv3

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

Нове в версії 3.2.

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

ssl.OP_NO_TLSv1

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

Нове в версії 3.2.

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

ssl.OP_NO_TLSv1_1

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

Нове в версії 3.4.

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

ssl.OP_NO_TLSv1_2

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

Нове в версії 3.4.

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

ssl.OP_NO_TLSv1_3

Запобігає підключенню TLSv1.3. Цей параметр застосовний лише в поєднанні з PROTOCOL_TLS. Це запобігає вибору одноранговими вузлами TLSv1.3 як версії протоколу. TLS 1.3 доступний з OpenSSL 1.1.1 або новішої версії. Якщо Python скомпільовано зі старішою версією OpenSSL, прапорець за замовчуванням має значення 0.

Нове в версії 3.7.

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

ssl.OP_NO_RENEGOTIATION

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

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

Нове в версії 3.7.

ssl.OP_CIPHER_SERVER_PREFERENCE

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

Нове в версії 3.3.

ssl.OP_SINGLE_DH_USE

Prevents re-use of the same DH key for distinct SSL sessions. This improves forward secrecy but requires more computational resources. This option only applies to server sockets.

Нове в версії 3.3.

ssl.OP_SINGLE_ECDH_USE

Prevents re-use of the same ECDH key for distinct SSL sessions. This improves forward secrecy but requires more computational resources. This option only applies to server sockets.

Нове в версії 3.3.

ssl.OP_ENABLE_MIDDLEBOX_COMPAT

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

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

Нове в версії 3.8.

ssl.OP_NO_COMPRESSION

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

This option is only available with OpenSSL 1.0.0 and later.

Нове в версії 3.3.

class ssl.Options

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

ssl.OP_NO_TICKET

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

Нове в версії 3.6.

ssl.OP_IGNORE_UNEXPECTED_EOF

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

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

Нове в версії 3.10.

ssl.HAS_ALPN

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

Нове в версії 3.5.

ssl.HAS_NEVER_CHECK_COMMON_NAME

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

Нове в версії 3.7.

ssl.HAS_ECDH

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

Нове в версії 3.3.

ssl.HAS_SNI

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

Нове в версії 3.2.

ssl.HAS_NPN

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

Нове в версії 3.3.

ssl.HAS_SSLv2

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

Нове в версії 3.7.

ssl.HAS_SSLv3

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

Нове в версії 3.7.

ssl.HAS_TLSv1

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

Нове в версії 3.7.

ssl.HAS_TLSv1_1

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

Нове в версії 3.7.

ssl.HAS_TLSv1_2

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

Нове в версії 3.7.

ssl.HAS_TLSv1_3

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

Нове в версії 3.7.

ssl.CHANNEL_BINDING_TYPES

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

Нове в версії 3.3.

ssl.OPENSSL_VERSION

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

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

Нове в версії 3.2.

ssl.OPENSSL_VERSION_INFO

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

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

Нове в версії 3.2.

ssl.OPENSSL_VERSION_NUMBER

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

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

Нове в версії 3.2.

ssl.ALERT_DESCRIPTION_HANDSHAKE_FAILURE
ssl.ALERT_DESCRIPTION_INTERNAL_ERROR
ALERT_DESCRIPTION_*

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

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

Нове в версії 3.4.

class ssl.AlertDescription

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

Нове в версії 3.6.

Purpose.SERVER_AUTH

Option for create_default_context() and SSLContext.load_default_certs(). This value indicates that the context may be used to authenticate Web servers (therefore, it will be used to create client-side sockets).

Нове в версії 3.4.

Purpose.CLIENT_AUTH

Option for create_default_context() and SSLContext.load_default_certs(). This value indicates that the context may be used to authenticate Web clients (therefore, it will be used to create server-side sockets).

Нове в версії 3.4.

class ssl.SSLErrorNumber

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

Нове в версії 3.6.

class ssl.TLSVersion

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

Нове в версії 3.7.

TLSVersion.MINIMUM_SUPPORTED
TLSVersion.MAXIMUM_SUPPORTED

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

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

SSL 3.0 до TLS 1.3.

SSL-сокети

class ssl.SSLSocket(socket.socket)

SSL-сокети надають такі методи Об’єкти 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 to maximum total duration of the shutdown.

Застаріло починаючи з версії 3.6: Безпосереднє створення екземпляра SSLSocket є застарілим, використовуйте SSSLContext.wrap_socket() для упаковки сокета.

Змінено в версії 3.7: SSLSocket екземпляри повинні бути створені за допомогою wrap_socket(). У попередніх версіях можна було створювати екземпляри безпосередньо. Це ніколи не було задокументовано чи офіційно підтверджено.

SSL-сокети також мають такі додаткові методи та атрибути:

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

Читайте до len байтів даних із SSL-сокета та повертайте результат як екземпляр bytes. Якщо вказано buffer, то замість цього зчитується в буфер і повертається кількість прочитаних байтів.

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

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

Змінено в версії 3.5: The socket timeout is no more reset each time bytes are received or sent. The socket timeout is now to 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 more reset each time bytes are received or sent. The socket timeout is now to 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 more reset each time bytes are received or sent. The socket timeout is now to 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 send 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}

Примітка

To validate a certificate for a particular service, you can use the match_hostname() function.

Якщо параметр binary_form має значення True і надано сертифікат, цей метод повертає закодовану DER форму всього сертифіката у вигляді послідовності байтів або None, якщо одноранговий сертифікат не надав. Чи надає партнер сертифікат, залежить від ролі SSL-сокета:

  • для клієнтського SSL-сокета сервер завжди надаватиме сертифікат, незалежно від того, чи була потрібна перевірка;

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

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

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

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

SSLSocket.cipher()

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

SSLSocket.shared_ciphers()

Return the list of ciphers shared by the client during the handshake. 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.

Нове в версії 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.

Примітка

Доступно лише з увімкненими OpenSSL 1.1.1 і TLS 1.3. Без підтримки TLS 1.3 метод викликає NotImplementedError.

Нове в версії 3.8.

SSLSocket.version()

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

Нове в версії 3.5.

SSLSocket.pending()

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

SSLSocket.context

The SSLContext object this SSL socket is tied to. If the SSL socket was created using the deprecated wrap_socket() function (rather than SSLContext.wrap_socket()), this is a custom context object created for this SSL socket.

Нове в версії 3.2.

SSLSocket.server_side

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

Нове в версії 3.2.

SSLSocket.server_hostname

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

Нове в версії 3.2.

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

SSLSocket.session

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

Нове в версії 3.6.

SSLSocket.session_reused

Нове в версії 3.6.

Контексти SSL

Нове в версії 3.2.

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

class ssl.SSLContext(protocol=PROTOCOL_TLS)

Створіть новий контекст 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

ні

ні

так

ні

ні

так

Виноски

1(1,2)

SSLContext вимикає SSLv2 за допомогою OP_NO_SSLv2 за замовчуванням.

2(1,2)

SSLContext вимикає SSLv3 за допомогою OP_NO_SSLv3 за замовчуванням.

3(1,2)

Протокол TLS 1.3 буде доступний із PROTOCOL_TLS у OpenSSL >= 1.1.1. Немає виділеної константи PROTOCOL лише для TLS 1.3.

Дивись також

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

Змінено в версії 3.6: 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 (except for PROTOCOL_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 (except for PROTOCOL_SSLv2).

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

SSLContext.cert_store_stats()

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

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

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

Нове в версії 3.4.

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

Завантажте закритий ключ і відповідний сертифікат. Рядок certfile має бути шляхом до одного файлу у форматі PEM, що містить сертифікат, а також будь-яку кількість сертифікатів ЦС, необхідних для встановлення автентичності сертифіката. Рядок 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.

Нове в версії 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 не завантажуються, якщо вони не були використані принаймні один раз.

Нове в версії 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}]

On OpenSSL 1.1 and newer the cipher dict contains additional fields:

>>> 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'}]

Availability: OpenSSL 1.0.2+.

Нове в версії 3.6.

SSLContext.set_default_verify_paths()

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

SSLContext.set_ciphers(ciphers)

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

Примітка

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

OpenSSL 1.1.1 has TLS 1.3 cipher suites enabled by default. The suites cannot be disabled with 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 to 1.1.0e will abort the handshake and raise SSLError when both sides support ALPN but cannot agree on a protocol. 1.1.0f+ behaves like 1.0.2, SSLSocket.selected_alpn_protocol() returns None.

Нове в версії 3.5.

SSLContext.set_npn_protocols(protocols)

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

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

Нове в версії 3.3.

SSLContext.sni_callback

Зареєструйте функцію зворотного виклику, яка буде викликана після отримання повідомлення рукостискання TLS 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, який представляє ланцюжок сертифікатів, який відповідає імені сервера .

Due to the early negotiation phase of the TLS connection, only limited methods and attributes are usable like SSLSocket.selected_alpn_protocol() and SSLSocket.context. The SSLSocket.getpeercert(), SSLSocket.cipher() and SSLSocket.compression() methods require that the TLS connection has progressed beyond the TLS Client Hello and therefore will not return meaningful values nor can they be called safely.

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

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

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

Нове в версії 3.7.

SSLContext.set_servername_callback(server_name_callback)

Це застарілий API, збережений для зворотної сумісності. Якщо можливо, замість цього слід використовувати sni_callback. Наданий server_name_callback подібний до sni_callback, за винятком того, що коли ім’я хосту сервера є інтернаціоналізованим доменним ім’ям із кодуванням IDN, server_name_callback отримує декодовану U-мітку ("pythön.org").

If there is an decoding error on the server name, the TLS connection will terminate with an ALERT_DESCRIPTION_INTERNAL_ERROR fatal TLS alert message to the client.

Нове в версії 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)

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.

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

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

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

SSLContext.sslsocket_class

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

Нове в версії 3.7.

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

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

Параметри server_side, server_hostname і session мають те саме значення, що й у SSLContext.wrap_socket().

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

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

SSLContext.sslobject_class

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

Нове в версії 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))

Нове в версії 3.4.

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

Примітка

This features requires OpenSSL 0.9.8f or newer.

SSLContext.keylog_filename

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

Нове в версії 3.8.

Примітка

This features requires OpenSSL 1.1.1 or newer.

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

Примітка

This attribute is not available unless the ssl module is compiled with OpenSSL 1.1.0g or newer.

Нове в версії 3.7.

SSLContext.minimum_version

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

Примітка

This attribute is not available unless the ssl module is compiled with OpenSSL 1.1.0g or newer.

Нове в версії 3.7.

SSLContext.num_tickets

Control the number of TLS 1.3 session tickets of a TLS_PROTOCOL_SERVER context. The setting has no impact on TLS 1.0 to 1.2 connections.

Примітка

This attribute is not available unless the ssl module is compiled with OpenSSL 1.1.1 or newer.

Нове в версії 3.8.

SSLContext.options

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

Примітка

With versions of OpenSSL older than 0.9.8m, it is only possible to set options, not to clear them. Attempting to clear an option (by resetting the corresponding bits) will raise a 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() і не буде виконано деякий ввід-вивід.

Примітка

Only available with OpenSSL 1.1.1 and TLS 1.3 enabled. Without TLS 1.3 support, the property value is None and can’t be modified

Нове в версії 3.8.

SSLContext.protocol

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

SSLContext.hostname_checks_common_name

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

Примітка

Only writeable with OpenSSL 1.1.0 or higher.

Нове в версії 3.7.

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

SSLContext.verify_flags

The flags for certificate verification operations. You can set flags like VERIFY_CRL_CHECK_LEAF by ORing them together. By default OpenSSL does neither require nor verify certificate revocation lists (CRLs). Available only with openssl version 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 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() and wrap_socket() 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 пам’яті

Нове в версії 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 to 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

Нове в версії 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; in this case, the match_hostname() function can be used. 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.options |= ssl.OP_NO_TLSv1
>>> client_context.options |= ssl.OP_NO_TLSv1_1

The SSL context created above will only allow TLSv1.2 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(), RAND_bytes() or RAND_pseudo_bytes() is sufficient.

TLS 1.3

Нове в версії 3.7.

Python has provisional and experimental support for TLS 1.3 with OpenSSL 1.1.1. The new protocol behaves slightly differently than previous version of TLS/SSL. Some new TLS 1.3 features are not yet available.

  • TLS 1.3 використовує диз’юнктний набір наборів шифрів. Усі набори шифрів AES-GCM і ChaCha20 увімкнено за замовчуванням. Метод SSLContext.set_ciphers() ще не може ввімкнути чи вимкнути будь-які шифри TLS 1.3, але SSLContext.get_ciphers() повертає їх.

  • Заявки на сеанс більше не надсилаються як частина початкового рукостискання та обробляються інакше. SSLSocket.session і SSLSession несумісні з TLS 1.3.

  • Клієнтські сертифікати також більше не перевіряються під час початкового рукостискання. Сервер може запитати сертифікат у будь-який час. Клієнти обробляють запити на сертифікати, коли вони надсилають або отримують дані програми з сервера.

  • Такі функції TLS 1.3, як ранні дані, відкладений запит на сертифікат клієнта TLS, конфігурація алгоритму підпису та повторне введення ключів, ще не підтримуються.

LibreSSL support

LibreSSL is a fork of OpenSSL 1.0.1. The ssl module has limited support for LibreSSL. Some features are not available when the ssl module is compiled with LibreSSL.