ssl —- 套接字对象的 TLS/SSL 包装器

ssl —- 套接字对象的 TLS/SSL 包装器

源代码: Lib/ssl.py


该模块提供了对传输层安全(通常称为 “安全套接字层”)加密和网络套接字的对等认证设施的访问,包括客户端和服务器端。 该模块使用 OpenSSL 库。它可以在所有现代 Unix 系统、 Windows 、 macOS 和可能的其他平台上使用,只要 OpenSSL 安装在该平台上。

备注

某些行为可能依赖于具体平台,因为调用了操作系统的套接字 API. 已安装的 OpenSSL 版本也可能会导致不同的行为。 比如,TLSv1.3 是 OpenSSL 1.1.1 版才提供的。

警告

在阅读 安全考量 前不要使用此模块。 这样做可能会导致虚假的安全感,因为ssl模块的默认设置不一定适合你的应用程序。

Availability: not WASI.

此模块在 WebAssembly 平台上无效或不可用。 请参阅 WebAssembly 平台 了解详情。

文档本文档记录 ssl 模块的对象和函数;更多关于TLS,SSL,和证书的信息,请参阅下方的“详情”选项

本模块提供了一个类 ssl.SSLSocket,它派生自 socket.socket 类型,并提供类似套接字的包装器,也能够使用 SSL 对通过套接字的数据进行加密和解密。 它支持一些额外方法例如 getpeercert(),该方法可以从连接的另一端获取证书,还有 cipher(),该方法可获取安全连接所使用的密码,以及 get_verified_chain()、get_unverified_chain(),它们可获取证书链。

对于更复杂的应用程序,ssl.SSLContext 类有助于管理设置项和证书,进而可以被使用 SSLContext.wrap_socket() 方法创建的 SSL 套接字继承。

在 3.5.3 版本发生变更: 更新以支持和 OpenSSL 1.1.0 的链接

在 3.6 版本发生变更: OpenSSL 0.9.8、1.0.0 和 1.0.1 已过时,将不再被支持。在 ssl 模块未来的版本中,最低需要 OpenSSL 1.0.2 或 1.1.0。

在 3.10 版本发生变更: PEP 644 已经实现。ssl 模块需要 OpenSSL 1.1.1 以上版本的支持。

使用废弃的常量和函数会导致废弃警告。

方法、常量和异常处理

套接字创建

SSLSocket 的实例必须使用 SSLContext.wrap_socket() 方法来创建。 辅助函数 create_default_context() 将返回一个使用安全的默认设置的新上下文。

客户端套接字实例,采用默认上下文和IPv4/IPv6双栈:

import socket
import ssl

hostname = 'www.python.org'
context = ssl.create_default_context()

with socket.create_connection((hostname, 443)) as sock:
    with context.wrap_socket(sock, server_hostname=hostname) as ssock:
        print(ssock.version())

客户端套接字示例,带有自定义上下文和IPv4:

hostname = 'www.python.org'
## PROTOCOL_TLS_CLIENT 需要有效的证书链和主机名
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
context.load_verify_locations('path/to/cabundle.pem')

with socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) as sock:
    with context.wrap_socket(sock, server_hostname=hostname) as ssock:
        print(ssock.version())

服务器套接字实例,在localhost上监听IPv4:

context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.load_cert_chain('/path/to/certchain.pem', '/path/to/private.key')

with socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) as sock:
    sock.bind(('127.0.0.1', 8443))
    sock.listen(5)
    with context.wrap_socket(sock, server_side=True) as ssock:
        conn, addr = ssock.accept()
        ...

上下文创建

便捷函数,可以帮助创建 SSLContext 对象,用于常见的目的。

ssl.create_default_context(purpose=Purpose.SERVER_AUTH , cafile=None , capath=None , cadata=None)

返回一个新的 SSLContext 对象,使用给定 purpose 的默认设置。 该设置由 ssl 模块选择,并且通常是代表一个比直接调用 SSLContext 构造器时更高的安全等级。

cafile , capath , cadata 代表用于进行证书核验的可选受信任 CA 证书,与 SSLContext.load_verify_locations() 的一致。 如果三个参数均为 None,此函数可以转而选择信任系统的默认 CA 证书。

设置为: PROTOCOL_TLS_CLIENT 或 PROTOCOL_TLS_SERVER, OP_NO_SSLv2 和 OP_NO_SSLv3 带有不含 RC4 及未认证的高强度加密密码套件。 传入 SERVER_AUTH 作为 purpose 将把 verify_mode 设为 CERT_REQUIRED 并加载 CA 证书(若至少给出 cafile , capath 或 cadata 之一)或使用 SSLContext.load_default_certs() 加载默认的 CA 证书。

当 keylog_filename 受支持并且设置了环境变量 SSLKEYLOGFILE 时,create_default_context() 会启用密钥日志记录。

此上下文的默认设置包括 VERIFY_X509_PARTIAL_CHAIN 和 VERIFY_X509_STRICT。 这使得下层的 OpenSSL 实现的行为与符合 RFC 5280 的实现更为相似,代价则是与较旧的 X.509 证书存在少量不兼容。

备注

协议、选项、密码和其他设置可随时更改为更具约束性的值而无须事先弃用。 这些值代表了兼容性和安全性之间的合理平衡。

如果你的应用需要特定的设置,你应当创建一个 SSLContext 并自行应用设置。

备注

如果你发现当某些较旧的客户端或服务器尝试与用此函数创建的 SSLContext 进行连接时收到了报错提示 “Protocol or cipher suite mismatch”,这可能是因为它们只支持 SSL3.0 而它被此函数用 OP_NO_SSLv3 排除掉了。 SSL3.0 被广泛认为 完全不可用。 如果你仍希望继续使用此函数但仍允许 SSL 3.0 连接,你可以使用以下代码重新启用它们:

ctx = ssl.create_default_context(Purpose.CLIENT_AUTH)
ctx.options &= ~ssl.OP_NO_SSLv3

备注

此上下文默认会启用 VERIFY_X509_STRICT,它可能拒绝下层 OpenSSL 实现在其他情况下应当会接受的 RFC 5280 之前的证书或格式错误的证书。 虽然不建议禁用此功能,但你可以使用以下方式做到这一点:

ctx = ssl.create_default_context()
ctx.verify_flags &= ~ssl.VERIFY_X509_STRICT

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。

在 3.13 版本发生变更: 此上下文现在会在其默认验证旗标中使用 VERIFY_X509_PARTIAL_CHAIN 和 VERIFY_X509_STRICT。

异常

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 的子类,当尝试读取或写入数据,但在请求被满足之前还需要在下层的 TCP 传输上接收更多数据时会被 非阻塞型 SSL 套接字 引发。

Added in version 3.3.

exception ssl.SSLWantWriteError

SSLError 的子类,当尝试读取或写入数据,但在请求被满足之前还需要在下层的 TCP 传输上发送更多数据时会被 非阻塞型 SSL 套接字 引发。

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 个高加密强度伪随机字节数据。 如果 PRNG 未使用足够的数据作为随机种子或者如果当前 RAND 方法不支持该操作则会引发 SSLError。 RAND_status() 可被用来检查 PRNG 的状态而 RAND_add() 可被用来为 PRNG 设置随机种子。

对于几乎所有应用程序都更推荐使用 os.urandom()。

请阅读维基百科文章 Cryptographically secure pseudorandom number generator (CSPRNG) 以了解对于高加密强度生成器的具体要求。

Added in version 3.3.

ssl.RAND_status()

如果 SSL 伪随机数生成器已使用‘足够的’随机性作为种子则返回 True,否则返回 False。 你可以使用 ssl.RAND_egd() 和 ssl.RAND_add() 来增加伪随机数生成器的随机性。

ssl.RAND_add(bytes , entropy)

将给定的 bytes 混合到 SSL 伪随机数生成器中。 参数 entropy (浮点数) 是字符串中包含的熵值的下限 (因此可以始终使用 0.0)。 请参阅 RFC 1750 了解有关熵源的更多信息。

在 3.5 版本发生变更: 现在接受可写的 字节类对象。

证书处理

ssl.cert_time_to_seconds(cert_time)

返回距离 Unix 纪元零时的秒数,给定的 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])

给定使用 SSL 保护的服务器的地址 addr,形式为一个 (hostname , port-number) 对,获取该服务器的证书,并返回为 PEM 编码的字符串。 如果指定了 ssl_version,则使用该版本的 SSL 协议尝试连接该服务器。 如果指定了 ca_certs ,它应当是一个包含根证书列表的文件,与 SSLContext.load_verify_locations() 中 cafile 形参所使用的格式相同。 该调用将尝试根据该根证书集来难服务器的证书,如果验证失败则调用也将失败。 可以通过 timeout 形参来指定超时限制。

在 3.3 版本发生变更: 此函数现在是 IPv6 兼容的。-compatible.

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

返回包含 OpenSSL 的默认 cafile 和 capath 的路径的命名元组。 此路径与 SSLContext.set_default_verify_paths() 所使用的相同。 返回值是一个 named tuple DefaultVerifyPaths:

  • cafile - 解析出的 cafile 路径或者如果文件不存在则为 None,

  • capath - 解析出的 capath 路径或者如果目录不存在则为 None,

  • openssl_cafile_env - 指向一个 cafile 的 OpenSSL 环境键,

  • openssl_cafile - 一个 cafile 的硬编码路径,

  • openssl_capath_env - 指向一个 capath 的 OpenSSL 环境键,

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

Availability: Windows.

Added in version 3.4.

ssl.enum_crls(store_name)

Windows 的系统证书库中检索 CRL。 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 数据。

Availability: Windows.

Added in version 3.4.

常量

所有常量现在都是 enum.IntEnum 或 enum.IntFlag 多项集的成员。

Added in version 3.6.

ssl.CERT_NONE

SSLContext.verify_mode 可能的取值。 PROTOCOL_TLS_CLIENT 除外,这是默认的模式。 对于客户端套接字,几乎任何证书都会被接受。 验证错误,如不受信任或过期的证书等,会被忽略并且不会中止 TLS/SSL 握手。

在服务器模式下,不会从客户端请求任何证书,因此客户端不会发送任何用于客户端证书身份验证的证书。

参见下文对于 安全考量 的讨论。

ssl.CERT_OPTIONAL

SSLContext.verify_mode 可能的取值。 在客户端模式下,CERT_OPTIONAL 具有与 CERT_REQUIRED 相同的含义。 对于客户端套接字推荐改用 CERT_REQUIRED。

在服务器模式下,客户端证书请求会被发送给客户端。 客户端可以忽略请求也可以发送一个证书以执行 TLS 客户端证书身份验证。 如果客户端选择发送证书,则将对其执行验证。 任何验证错误都将立即中止 TLS 握手。

使用此设置要求将一组有效的 CA 证书传递给 SSLContext.load_verify_locations()。

ssl.CERT_REQUIRED

SSLContext.verify_mode 可能的取值。 在此模式下,需要从套接字连接的另一端获取证书;如果未提供证书,或验证失败则将引发 SSLError。 此模式 不能 在客户端模式下对证书进行验证因为它不会匹配主机名。 check_hostname 也必须被启用以验证证书的真实性。 PROTOCOL_TLS_CLIENT 会使用 CERT_REQUIRED 并默认启用 check_hostname。

对于服务器套接字,此模式会提供强制性的 TLS 客户端证书验证。 客户端证书请求会被发送给客户端并且客户端必须提供有效且受信任的证书。

使用此设置要求将一组有效的 CA 证书传递给 SSLContext.load_verify_locations()。

class ssl.VerifyMode

CERT_* 常量的 enum.IntEnum 多项集。

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 可能的取值。 在此模式下, 只会检查对等证书而不检查任何中间 CA 证书。 此模式要求提供由对等证书颁发者(其直接上级 CA)签名的有效 CRL。 如果未使用 SSLContext.load_verify_locations 加载正确的 CRL,则验证将失败。

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 接受信任存储中的中间 CA 作为信任锚,与自我签名的根 CA 证书的方式相同。这样就能信任中间 CA 颁发的证书,而不一定非要去信任其祖先的根 CA。

Added in version 3.10.

class ssl.VerifyFlags

VERIFY_* 常量的 enum.IntFlag 多项集。

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 已经废弃了所有特定于版本的协议。请换用带有 SSLContext.minimum_version 和 SSLContext.maximum_version 的默认协议 PROTOCOL_TLS_SERVER 或 PROTOCOL_TLS_CLIENT 。

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 实现中的各种缺陷启用绕过操作。 默认会设置此选项。 没有必要设置与 OpenSSL 的 SSL_OP_ALL 常量同名的旗标。

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 和 SSLContext.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 版本弃用: 此选项自 OpenSSL 1.1.0 起已被弃用。 它被添加到 2.7.15 和 3.6.3 是为了向下兼容 OpenSSL 1.0.2。

ssl.OP_NO_RENEGOTIATION

禁用所有 TLSv1.2 和更早版本的重协商操作。 不发送 HelloRequest 消息,并忽略通过 ClientHello 发起的重协商请求。

此选项仅适用于 OpenSSL 1.1.0h 及更新的版本。

Added in version 3.7.

ssl.OP_CIPHER_SERVER_PREFERENCE

使用服务器的密码顺序首选项,而不是客户端的首选项。 此选项在客户端套接字和 SSLv2 服务器套接字上无效。

Added in version 3.3.

ssl.OP_SINGLE_DH_USE

防止对于单独 SSL 会话重用相同的 DH 密钥。 这会提升前向保密性但需要更多的计算资源。 此选项仅适用于服务器套接字。

Added in version 3.3.

ssl.OP_SINGLE_ECDH_USE

防止对于单独 SSL 会话重用相同的 ECDH 密钥。 这会提升前向保密性但需要更多的计算资源。 此选项仅适用于服务器套接字。

Added in version 3.3.

ssl.OP_ENABLE_MIDDLEBOX_COMPAT

在 TLS 1.3 握手中发送虚拟更改密码规格(CCS)消息以使得 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

OP_* 常量的 enum.IntFlag 多项集。

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

启用内核 TLS。 为了利用该特征,OpenSSL 编译时必须附带对它的支持,并且协商的密码套件和扩展必须被它所支持(受支持项的列表可能因平台和内核版本而有所变化)。

请注意当启用内核 TLS 时某些加解密操作将由内核直接执行而不是通过任何可用的 OpenSSL 提供程序。 这可能并不是你想要的,例如,当应用程序要求所有加解密操作由 FIPS 提供程序执行时。

此选项仅适用于 OpenSSL 3.0.0 及更新的版本。

Added in version 3.12.

ssl.OP_LEGACY_SERVER_CONNECT

允许只在 OpenSSL 和未打补丁的服务器之间进行旧式的不安全协商。

Added in version 3.12.

ssl.HAS_ALPN

OpenSSL 库是否具有对 RFC 7301 中描述的 应用层协议协商 TLS 扩展的内置支持。

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 库是否具有对基于椭圆曲线的 Diffie-Hellman 密钥交换的内置支持。 此常量应当为真值,除非发布者明确地禁用了此功能。

Added in version 3.3.

ssl.HAS_SNI

OpenSSL 库是否具有对 服务器名称提示 扩展(在 RFC 6066 中定义)的内置支持。

Added in version 3.2.

ssl.HAS_NPN

OpenSSL 库是否具有对 应用层协议协商 中描述的 下一协议协商 的内置支持。 当此常量为真值时,你可以使用 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.HAS_PSK

OpenSSL 库是否具有对 TLS-PSK 的内置支持。

Added in version 3.13.

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 Alert Registry 中包含了这个列表及对定义其含义的 RFC 引用。

被用作 SSLContext.set_servername_callback() 中的回调函数的返回值。

Added in version 3.4.

class ssl.AlertDescription

ALERT_DESCRIPTION_* 常量的 enum.IntEnum 多项集。

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

SSL_ERROR_* 常量的 enum.IntEnum 多项集。

Added in version 3.6.

class ssl.TLSVersion

SSLContext.maximum_version 和 SSLContext.minimum_version 中的 SSL 和 TLS 版本的 enum.IntEnum 多项集。

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 套接字提供了 套接字对象 的下列方法:

但是,由于 SSL(和 TLS)协议在 TCP 之上具有自己的框架,因此 SSL 套接字抽象在某些方面可能与常规的 OS 层级套接字存在差异。 特别是要查看 非阻塞型套接字说明。

SSLSocket 的实例必须使用 SSLContext.wrap_socket() 方法来创建。

在 3.5 版本发生变更: 新增了 sendfile() 方法。

在 3.5 版本发生变更: shutdown() 不会在每次接收或发送字节数据后重置套接字超时。 现在套接字超时为关闭的最大总持续时间。

自 3.6 版本弃用: 直接创建 SSLSocket 实例的做法已被弃用,请使用 SSLContext.wrap_socket() 来包装套接字。

在 3.7 版本发生变更: SSLSocket 的实例必须使用 wrap_socket() 来创建。 在较早的版本中,直接创建实例是可能的。 但这从未被记入文档或是被正式支持。

在 3.10 版本发生变更: Python 内部现在使用 SSL_read_ex 和 SSL_write_ex。这些函数支持读取和写入大于 2GB 的数据。写入零长数据不再出现违反协议的错误。

SSL 套接字还具有下列方法和属性:

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

从 SSL 套接字读取至多 len 个字节的数据并将结果作为 bytes 实例返回。 如果指定了 buffer ,则改为读取到缓冲区,并返回所读取的字节数。

如果套接字为 非阻塞型 则会引发 SSLWantReadError 或 SSLWantWriteError 且读取将阻塞。

由于在任何时候重新协商都是可能的,因此调用 read() 也可能导致写入操作。

在 3.5 版本发生变更: 套接字超时在每次接收或发送字节数据后不会再被重置。 现在套接字超时为读取至多 len 个字节数据的最大总持续时间。

自 3.6 版本弃用: 请使用 recv() 来代替 read()。

SSLSocket.write(buf)

将 buf 写入到 SSL 套接字并返回所写入的字节数。 buf 参数必须为支持缓冲区接口的对象。

如果套接字为 非阻塞型 则会引发 SSLWantReadError 或 SSLWantWriteError 且读取将阻塞。

由于在任何时候重新协商都是可能的,因此调用 write() 也可能导致读取操作。

在 3.5 版本发生变更: 套接字超时在每次接收或发送字节数据后不会再被重置。 现在套接字超时为写入 buf 的最大总持续时间。

自 3.6 版本弃用: 请使用 send() 来代替 write()。

备注

read() 和 write() 方法是读写未加密的应用级数据,并将其解密/加密为带加密的线路级数据的低层级方法。 这些方法需要有激活的 SSL 连接,即握手已完成而 SSLSocket.unwrap() 尚未被调用。

通常你应当使用套接字 API 方法例如 recv() 和 send() 来代替这些方法。

SSLSocket.do_handshake()

执行 SSL 设置握手。

在 3.4 版本发生变更: 当套接字的 context 的 check_hostname 属性为真值时此握手方法还会执行 match_hostname()。

在 3.5 版本发生变更: 套接字超时在每次接收或发送字节数据时不会再被重置。 现在套接字超时为握手的最大总持续时间。

在 3.7 版本发生变更: 主机名或 IP 地址会在握手期间由 OpenSSL 进行匹配。 函数 match_hostname() 不再被使用。 在 OpenSSL 拒绝主机名或 IP 地址的情况下,握手将提前被中止并向对等方发送 TLS 警告消息。

SSLSocket.getpeercert(binary_form=False)

如果连接另一端的对等方没有证书,则返回 None。 如果 SSL 握手还未完成,则会引发 ValueError。

如果 binary_form 形参为 False,并且从对等方接收到了证书,此方法将返回一个 dict 实例。 如果证书未通过验证,则字典将为空。 如果证书通过验证,它将返回由多个密钥组成的字典,其中包括 subject (证书颁发给的主体) 和 issuer (颁发证书的主体)。 如果证书包含一个 Subject Alternative Name 扩展的实例 (see RFC 3280),则字典中还将有一个 subjectAltName 键。

subject 和 issuer 字段都是包含在证书中相应字段的数据结构中给出的相对专有名称(RDN)序列的元组,每个 RDN 均为 name-value 对的序列。 这里是一个实际的示例:

{'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 套接字,客户端将仅在服务器要求时才提供证书;因此如果你使用了 CERT_NONE (而不是 CERT_OPTIONAL 或 CERT_REQUIRED) 则 getpeercert() 将返回 None。

另请参阅 SSLContext.check_hostname。

在 3.2 版本发生变更: 返回的字典包括额外的条目例如 issuer 和 notBefore。

在 3.4 版本发生变更: 如果握手未完成则会引发 ValueError。 返回的字典包括额外的 X509v3 扩展条目例如 crlDistributionPoints, caIssuers 和 OCSP URI。

在 3.9 版本发生变更: IPv6 地址字符串不再附带末尾换行符。

SSLSocket.get_verified_chain()

返回由 SSL 通道另一端以 DER 编码字节列表形式提供的经过验证的证书链。 如果证书验证被禁用则此方法的行为与 get_unverified_chain() 相同。

Added in version 3.13.

SSLSocket.get_unverified_chain()

返回由 SSL 通道另一端以 DER 编码字节列表形式提供的原始证书链。

Added in version 3.13.

SSLSocket.cipher()

返回由三个值组成的元组,其中包含所使用的密码名称,定义其使用方式的 SSL 协议版本,以及所使用的加密比特位数。 如果尚未建立连接,则返回 None。

SSLSocket.shared_ciphers()

返回在客户端和服务器均可用的密码列表。 所返回列表的每个条目都是由三个值组成的元组其中包含密码名称、定义其使用方式的 SSL 协议版本,以及密码所使用的加密比特位数量。 如果连接尚未建立或套接字为客户端套接字则 shared_ciphers() 将返回 None。

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

为当前连接获取字节串形式的通道绑定数据。 如果尚未连接或握手尚未完成则返回 None。

cb_type 形参允许选择需要的通道绑定类型。 有效的通道绑定类型在 CHANNEL_BINDING_TYPES 列表中列出。 目前只支持由 RFC 5929 所定义的 ‘tls-unique’ 通道绑定。 如果请求了一个不受支持的通道绑定类型则将引发 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()

返回在Return the higher-level protocol that was selected during the 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()

向一个 TLS 1.3 客户端请求握手后身份验证(PHA)。 只有在初始 TLS 握手之后且双方都启用了 PHA 的情况下才能为服务器端套接字的 TLS 1.3 连接启用 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 协议版本,或者如果未建立安全连接则返回 None。 在撰写本文档时,可能的返回值包括 "SSLv2", "SSLv3", "TLSv1", "TLSv1.1" 和 "TLSv1.2"。 最新的 OpenSSL 版本可能会定义更多的返回值。

Added in version 3.5.

SSLSocket.pending()

返回在连接上等待被读取的已解密字节数。

SSLSocket.context

该 SSL 套接字所关联的 SSLContext 对象。

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

用于 SSL 连接的 SSLSession。 该会话将在执行 TLS 握手后对客户端和服务器端套接字可用。 对于客户端套接字该会话可以在调用 do_handshake() 之前被设置以重用一个会话。

Added in version 3.6.

SSLSocket.session_reused

Added in version 3.6.

(本文超出站点单文档体积上限,已按小节截断)