ssl
--- 套接字对象的 TLS/SSL 包装器¶
源代码: Lib/ssl.py
本模块保证了对传安全传输层协议(TLS)的访问 (SSL)加密,并且提供客户端和服务端层面的网络嵌套字层面的对等连接认证技术。本模块使用OpenSSL库。适用于所有现代Unix系统、Windows以及Mac OS X。只要Open SSL存在的系统,都有机会正常使用。
備註
某些行为可能具有平台依赖,因为调用是根据操作系统的嵌套字API。不同版本的Open SSL也会引起差异:例如Open SSL版本1.0.1 自带TLSv1.1 和 TLSv1.2
警告
在阅读 Security considerations 前不要使用此模块。 这样做可能会导致虚假的安全感,因为ssl模块的默认设置不一定适合你的应用程序。
本文档记录"ssl"模块的对象和函数;更多关于TLS,SSL,和证书的信息,请参阅下方的“详情”选项
本模块提供了一个类 ssl.SSLSocket
,它派生自 socket.socket
类型,并提供类似套接字的包装器,也能够对通过带 SSL 套接字的数据进行加密和解密。 它支持一些额外方法例如 getpeercert()
,该方法可从连接的另一端获取证书,还有 cipher()
,该方法可获取安全连接所使用的密码。
对于更复杂的应用程序,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。
方法、常量和异常处理¶
套接字创建¶
从 Python 3.2 和 2.7.9 开始,建议使用 SSLContext
实例的 SSLContext.wrap_socket()
来将套接字包装为 SSLSocket
对象。 辅助函数 create_default_context()
会返回一个新的带有安全默认设置的上下文。 旧的 wrap_socket()
函数已被弃用,因为它效率较差并且不支持服务器名称提示(SNI)和主机匹配。
客户端套接字实例,采用默认上下文和IPv4/IPv6双栈:
import socket
import ssl
hostname = 'www.python.org'
context = ssl.create_default_context()
with socket.create_connection((hostname, 443)) as sock:
with context.wrap_socket(sock, server_hostname=hostname) as ssock:
print(ssock.version())
客户端套接字示例,带有自定义上下文和IPv4:
hostname = 'www.python.org'
# PROTOCOL_TLS_CLIENT requires valid cert chain and hostname
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
context.load_verify_locations('path/to/cabundle.pem')
with socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) as sock:
with context.wrap_socket(sock, server_hostname=hostname) as ssock:
print(ssock.version())
服务器套接字实例,在localhost上监听IPv4:
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.load_cert_chain('/path/to/certchain.pem', '/path/to/private.key')
with socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) as sock:
sock.bind(('127.0.0.1', 8443))
sock.listen(5)
with context.wrap_socket(sock, server_side=True) as ssock:
conn, addr = ssock.accept()
...
上下文创建¶
便捷函数,可以帮助创建 SSLContext
对象,用于常见的目的。
-
ssl.
create_default_context
(purpose=Purpose.SERVER_AUTH, cafile=None, capath=None, cadata=None)¶ 返回一个新的
SSLContext
对象,使用给定 purpose 的默认设置。 该设置由ssl
模块选择,并且通常是代表一个比直接调用SSLContext
构造器时更高的安全等级。cafile, capath, cadata 代表用于进行证书核验的可选受信任 CA 证书,与
SSLContext.load_verify_locations()
的一致。 如果三个参数均为None
,此函数可以转而选择信任系统的默认 CA 证书。设置包括:
PROTOCOL_TLS
,OP_NO_SSLv2
以及OP_NO_SSLv3
,具有不带 RC4 和不带无身份验证密码套件的高度加密密码套件。 传入SERVER_AUTH
作为 purpose 会把verify_mode
设为CERT_REQUIRED
并且加载指定 CA 证书(当给出 cafile, capath 和 cadata 中的至少一个)或者使用SSLContext.load_default_certs()
来加载默认 CA 证书。当
keylog_filename
受支持并且设置了环境变量SSLKEYLOGFILE
时,create_default_context()
会启用密钥日志记录。備註
协议、选项、密码和其他设置可随时更改为更具约束性的值而无须事先弃用。 这些值代表了兼容性和安全性之间的合理平衡。
如果你的应用需要特定的设置,你应当创建一个
SSLContext
并自行应用设置。備註
如果你发现当某些较旧的客户端或服务器尝试与用此函数创建的
SSLContext
进行连接时收到了报错提示 "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
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
的子类,当尝试读取或写入数据,但在请求被满足之前还需要在下层的 TCP 传输上接收更多数据时会被 非阻塞型 SSL 套接字 引发。3.3 版新加入.
-
exception
ssl.
SSLWantWriteError
¶ SSLError
的子类,当尝试读取或写入数据,但在请求被满足之前还需要在下层的 TCP 传输上发送更多数据时会被 非阻塞型 SSL 套接字 引发。3.3 版新加入.
-
exception
ssl.
SSLSyscallError
¶ SSLError
的子类,当尝试在 SSL 套接字上执行操作时遇到系统错误时会被引发。 不幸的是,没有简单的方式能检查原始 errno 编号。3.3 版新加入.
-
exception
ssl.
SSLCertVerificationError
¶ SSLError
的子类,当证书验证失败时会被引发。3.7 版新加入.
-
verify_code
¶ 一个数字形式的错误编号,用于表示验证错误。
-
verify_message
¶ 用于表示验证错误的人类可读的字符串。
-
-
exception
ssl.
CertificateError
¶ -
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) 以了解对于高加密强度生成器的具体要求。
3.3 版新加入.
-
ssl.
RAND_pseudo_bytes
(num)¶ 返回 (bytes, is_cryptographic): bytes 是 num 个伪随机字节数据,如果所生成的字节数据为高加密强度则 is_cryptographic 为
True
。 如果当前 RAND 方法不支持此操作则会引发SSLError
。所生成的伪随机字节序列如果具有足够的长度则将会具有唯一性,并是并非不可预测。 它们可被用于非加密目的以及加密协议中的特定目的,但通常不可被用于密钥生成等目的。
对于几乎所有应用程序都更推荐使用
os.urandom()
。3.3 版新加入.
3.6 版後已棄用: OpenSSL 已弃用了
ssl.RAND_pseudo_bytes()
,请改用ssl.RAND_bytes()
。
-
ssl.
RAND_status
()¶ 如果 SSL 伪随机数生成器已使用‘足够的’随机性作为种子则返回
True
,否则返回False
。 你可以使用ssl.RAND_egd()
和ssl.RAND_add()
来增加伪随机数生成器的随机性。
-
ssl.
RAND_egd
(path)¶ 如果你在某处运行了一个熵收集守护程序(EGD),且 path 是向其打开的套接字连接路径名,此函数将从该套接字读取 256 个字节的随机性数据,并将其添加到 SSL 伪随机数生成器以增加所生成密钥的安全性。 此操作通常只在没有更好随机性源的系统上才是必要的。
请查看 http://egd.sourceforge.net/ 或 http://prngd.sourceforge.net/ 来了解有关熵收集守护程序源的信息。
可用性: 对于 LibreSSL 和 OpenSSL > 1.1.0 不可用。
证书处理¶
-
ssl.
match_hostname
(cert, hostname)¶ 验证 cert (使用
SSLSocket.getpeercert()
所返回的已解码格式) 是否匹配给定的 hostname。 所应用的规则是在 RFC 2818, RFC 5280 和 RFC 6125 中描述的检查 HTTPS 服务器身份的规则。 除了 HTTPS,此函数还应当适用于各种基于 SSL 协议的服务器身份检查操作,例如 FTPS, IMAPS, POPS 等等。失败时引发
CertificateError
。 成功时此函数无返回值:>>> cert = {'subject': ((('commonName', 'example.com'),),)} >>> ssl.match_hostname(cert, "example.com") >>> ssl.match_hostname(cert, "example.org") Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/home/py3k/Lib/ssl.py", line 130, in match_hostname ssl.CertificateError: hostname 'example.org' doesn't match 'example.com'
3.2 版新加入.
3.3.3 版更變: 此函数现在遵循 RFC 6125, 6.4.3 小节,它不会匹配多个通配符 (例如
*.*.com
或*a*.example.org
) 也不匹配国际化域名 (IDN) 片段内部的通配符。 IDN A 标签例如www*.xn--pthon-kva.org
仍然受支持,但x*.python.org
不再能匹配xn--tda.python.org
。3.5 版更變: 现在支持匹配存在于证书的 subjectAltName 字段中的 IP 地址。
3.7 版更變: 此函数不再被用于 TLS 连接。 主机匹配现在是由 OpenSSL 执行的。
允许位于段的最左端且为唯一字符的通配符。 部分通配符例如
www*.example.com
已不再受支持。3.7 版後已棄用.
-
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, ca_certs=None)¶ 带 SSL 保护的服务器的地址
addr
以 (hostname, port-number) 对的形式给出,获取服务器的证书,并将其以 PEM 编码字符串的形式返回。 如果指定了ssl_version
,则使用该版本的 SSL 协议尝试连接服务器。 如果指定了ca_certs
,它应当是一个包含根证书列表的文件,使用与SSLContext.wrap_socket()
中同名形参一致的格式。 该调用将尝试根据指定的根证书集来验证服务器证书,如果验证失败则该调用也将失败。3.3 版更變: 此函数现在是 IPv6 兼容的。-compatible.
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
()¶ 返回包含 OpenSSL 的默认 cafile 和 capath 的路径的命名元组。 此路径与
SSLContext.set_default_verify_paths()
所使用的相同。 返回值是一个 named tupleDefaultVerifyPaths
:cafile
- 解析出的 cafile 路径或者如果文件不存在则为None
,capath
- 解析出的 capath 路径或者如果目录不存在则为None
,openssl_cafile_env
- 指向一个 cafile 的 OpenSSL 环境键,openssl_cafile
- 一个 cafile 的硬编码路径,openssl_capath_env
- 指向一个 capath 的 OpenSSL 环境键,openssl_capath
- 一个 capath 目录的硬编码路径
可用性: LibreSSL 会忽略环境变量
openssl_cafile_env
和openssl_capath_env
。3.4 版新加入.
-
ssl.
enum_certificates
(store_name)¶ 从 Windows 的系统证书库中检索证书。 store_name 可以是
CA
,ROOT
或MY
中的一个。 Windows 也可能会提供额外的证书库。此函数返回一个包含 (cert_bytes, encoding_type, trust) 元组的列表。 encoding_type 指明 cert_bytes 的编码格式。 它可以为
x509_asn
以表示 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)¶ 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 数据。可用性: 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)¶ 接受一个
socket.socket
的实例sock
,并返回一个ssl.SSLSocket
的实例,该类型是socket.socket
的子类型,它将下层的套接字包装在一个 SSL 上下文中。sock
必须是一个SOCK_STREAM
套接字;其他套接字类型不被支持。在内部,该函数会创建一个
SSLContext
,其协议版本为 ssl_version 且SSLContext.options
设为 cert_reqs。 如果设置了 keyfile, certfile, ca_certs 或 ciphers 等形参,则参数值会被传给SSLContext.load_cert_chain()
,SSLContext.load_verify_locations()
以及SSLContext.set_ciphers()
。参数 server_side, do_handshake_on_connect 和 suppress_ragged_eofs 具有与
SSLContext.wrap_socket()
相同的含义。3.7 版後已棄用: 从 Python 3.2 和 2.7.9 开始,建议使用
SSLContext.wrap_socket()
来代替wrap_socket()
。 模块级函数的功能受限并且将创建不安全的客户端套接字,不带服务器名称提示或主机名匹配。
常量¶
所有常量现在都是
enum.IntEnum
或enum.IntFlag
多项集的成员。3.6 版新加入.
-
ssl.
CERT_NONE
¶ SSLContext.verify_mode
或wrap_socket()
的cert_reqs
形参可能的取值。PROTOCOL_TLS_CLIENT
除外,这是默认的模式。 对于客户端套接字,几乎任何证书都是可接受的。 验证错误例如不受信任或过期的证书错误会被忽略并且不会中止 TLS/SSL 握手。在服务器模式下,不会从客户端请求任何证书,因此客户端不会发送任何用于客户端证书身份验证的证书。
参见下文对于 Security considerations 的讨论。
-
ssl.
CERT_OPTIONAL
¶ SSLContext.verify_mode
或wrap_socket()
的cert_reqs
形参可能的取值。CERT_OPTIONAL
具有与CERT_REQUIRED
相同的含义。 对于客户端套接字推荐改用CERT_REQUIRED
。在服务器模式下,客户端证书请求会被发送给客户端。 客户端可以忽略请求也可以发送一个证书以执行 TLS 客户端证书身份验证。 如果客户端选择发送证书,则将对其执行验证。 任何验证错误都将立即中止 TLS 握手。
使用此设置要求将一组有效的 CA 证书传递给
SSLContext.load_verify_locations()
或是作为wrap_socket()
的ca_certs
形参值。
-
ssl.
CERT_REQUIRED
¶ SSLContext.verify_mode
或wrap_socket()
的cert_reqs
形参可能的取值。 在此模式下,需要从套接字连接的另一端获取证书;如果未提供证书或验证失败则将引发SSLError
。 此模式 不能 在客户端模式下对证书进行验证,因为它不会匹配主机名。check_hostname
也必须被启用以验证证书的真实性。PROTOCOL_TLS_CLIENT
会使用CERT_REQUIRED
并默认启用check_hostname
。对于服务器套接字,此模式会提供强制性的 TLS 客户端证书验证。 客户端证书请求会被发送给客户端并且客户端必须提供有效且受信任的证书。
使用此设置要求将一组有效的 CA 证书传递给
SSLContext.load_verify_locations()
或是作为wrap_socket()
的ca_certs
形参值。
-
class
ssl.
VerifyMode
¶ CERT_* 常量的
enum.IntEnum
多项集。3.6 版新加入.
-
ssl.
VERIFY_DEFAULT
¶ SSLContext.verify_flags
可能的取值。 在此模式下,证书吊销列表(CRL)并不会被检查。 OpenSSL 默认不要求也不验证 CRL。3.4 版新加入.
-
ssl.
VERIFY_CRL_CHECK_LEAF
¶ SSLContext.verify_flags
可能的取值。 在此模式下, 只会检查对等证书而不检查任何中间 CA 证书。 此模式要求提供由对等证书颁发者(其直接上级 CA)签名的有效 CRL。 如果未使用SSLContext.load_verify_locations
加载正确的 CRL,则验证将失败。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
¶ VERIFY_* 常量的
enum.IntFlag
多项集。3.6 版新加入.
-
ssl.
PROTOCOL_TLS
¶ 选择客户端和服务器均支持的最高协议版本。 此选项名称并不准确,实际上 "SSL" 和 "TLS" 协议均可被选择。
3.6 版新加入.
-
ssl.
PROTOCOL_TLS_CLIENT
¶ 像
PROTOCOL_TLS
一样地自动协商最高协议版本,但是只支持客户端SSLSocket
连接。 此协议默认会启用CERT_REQUIRED
和check_hostname
。3.6 版新加入.
-
ssl.
PROTOCOL_TLS_SERVER
¶ 像
PROTOCOL_TLS
一样地自动协商最高协议版本,但是只支持服务器SSLSocket
连接。3.6 版新加入.
-
ssl.
PROTOCOL_SSLv23
¶ PROTOCOL_TLS
的别名。3.6 版後已棄用: 请改用
PROTOCOL_TLS
。
-
ssl.
PROTOCOL_SSLv2
¶ 选择 SSL 版本 2 作为通道加密协议。
如果 OpenSSL 编译时使用了
OPENSSL_NO_SSL2
旗标则此协议将不可用。警告
SSL 版本 2 并不安全。 极不建议使用它。
3.6 版後已棄用: OpenSSL 已经移除了对 SSLv2 的支持。
-
ssl.
PROTOCOL_SSLv3
¶ 选择 SSL 版本 3 作为通道加密协议。
如果 OpenSSL 编译时使用了
OPENSSL_NO_SSLv3
旗标则此协议将不可用。警告
SSL 版本 3 并不安全。 极不建议使用它。
3.6 版後已棄用: OpenSSL 已经弃用了所有带有特定版本号的协议。 请改用默认协议
PROTOCOL_TLS
并附带OP_NO_SSLv3
等旗标。
-
ssl.
PROTOCOL_TLSv1
¶ 选择 TLS 版本 1.0 作为通道加密协议。
3.6 版後已棄用: OpenSSL 已经弃用了所有带有特定版本号的协议。 请改用默认协议
PROTOCOL_TLS
并附带OP_NO_SSLv3
等旗标。
-
ssl.
PROTOCOL_TLSv1_1
¶ 选择 TLS 版本 1.1 作为通道加密协议。 仅适用于 openssl 版本 1.0.1+。
3.4 版新加入.
3.6 版後已棄用: OpenSSL 已经弃用了所有带有特定版本号的协议。 请改用默认协议
PROTOCOL_TLS
并附带OP_NO_SSLv3
等旗标。
-
ssl.
PROTOCOL_TLSv1_2
¶ 选译 TLS 版本 1.2 作为通道加密协议。 这是最新的版本,也应是能提供最大保护的最佳选择,如果通信双方都支持它的话。 仅适用于 openssl 版本 1.0.1+。
3.4 版新加入.
3.6 版後已棄用: OpenSSL 已经弃用了所有带有特定版本号的协议。 请改用默认协议
PROTOCOL_TLS
并附带OP_NO_SSLv3
等旗标。
-
ssl.
OP_ALL
¶ 对存在于其他 SSL 实现中的各种缺陷启用绕过操作。 默认会设置此选项。 没有必要设置与 OpenSSL 的
SSL_OP_ALL
常量同名的旗标。3.2 版新加入.
-
ssl.
OP_NO_SSLv2
¶ 阻止 SSLv2 连接。 此选项仅可与
PROTOCOL_TLS
结合使用。 它会阻止对等方选择 SSLv2 作为协议版本。3.2 版新加入.
3.6 版後已棄用: SSLv2 已被弃用
-
ssl.
OP_NO_SSLv3
¶ 阻止 SSLv3 连接。 此选项仅可与
PROTOCOL_TLS
结合使用。 它会阻止对等方选择 SSLv3 作为协议版本。3.2 版新加入.
3.6 版後已棄用: SSLv3 已被弃用
-
ssl.
OP_NO_TLSv1
¶ 阻止 TLSv1 连接。 此选项仅可与
PROTOCOL_TLS
结合使用。 它会阻止对等方选择 TLSv1 作为协议版本。3.2 版新加入.
3.7 版後已棄用: 此选项自 OpenSSL 1.1.0 起已被弃用,请改用新的
SSLContext.minimum_version
和SSLContext.maximum_version
。
-
ssl.
OP_NO_TLSv1_1
¶ 阻止 TLSv1.1 连接。 此选项仅可与
PROTOCOL_TLS
结合使用。 它会阻止对等方选择 TLSv1.1 作为协议版本。 仅适用于 openssl 版本 1.0.1+。3.4 版新加入.
3.7 版後已棄用: 此选项自 OpenSSL 1.1.0 起已被弃用。
-
ssl.
OP_NO_TLSv1_2
¶ 阻止 TLSv1.2 连接。 此选项仅可与
PROTOCOL_TLS
结合使用。 它会阻止对等方选择 TLSv1.2 作为协议版本。 仅适用于 openssl 版本 1.0.1+。3.4 版新加入.
3.7 版後已棄用: 此选项自 OpenSSL 1.1.0 起已被弃用。
-
ssl.
OP_NO_TLSv1_3
¶ 阻止 TLSv1.3 连接。 此选项仅可与
PROTOCOL_TLS
结合使用。 它会阻止对等方选择 TLSv1.3 作为协议版本。 TLS 1.3 适用于 OpenSSL 1.1.1 或更新的版本。 当 Python 编译是基于较旧版本的 OpenSSL 时,该旗标默认为 0。3.7 版新加入.
3.7 版後已棄用: 此选项自 OpenSSL 1.1.0 起已被弃用。 它被添加到 2.7.15, 3.6.3 和 3.7.0 是为了向下兼容 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
¶ 阻止对于单独的 SSL 会话重用相同的 DH 密钥。 这会提升前向保密性但需要更多的计算资源。 此选项仅适用于服务器套接字。
3.3 版新加入.
-
ssl.
OP_SINGLE_ECDH_USE
¶ 阻止对于单独的 SSL 会话重用相同的 ECDH 密钥。 这会提升前向保密性但需要更多的计算资源。 此选项仅适用于服务器套接字。
3.3 版新加入.
-
ssl.
OP_ENABLE_MIDDLEBOX_COMPAT
¶ 在 TLS 1.3 握手中发送虚拟更改密码规格(CCS)消息以使得 TLS 1.3 连接看起来更像是 TLS 1.2 连接。
此选项仅适用于 OpenSSL 1.1.1 及更新的版本。
3.8 版新加入.
-
ssl.
OP_NO_COMPRESSION
¶ 在 SSL 通道上禁用压缩。 这适用于应用协议支持自己的压缩方案的情况。
此选项仅适用于 OpenSSL 1.0.0 及更新的版本。
3.3 版新加入.
-
class
ssl.
Options
¶ OP_* 常量的
enum.IntFlag
多项集。
-
ssl.
OP_NO_TICKET
¶ 阻止客户端请求会话凭据。
3.6 版新加入.
-
ssl.
HAS_NEVER_CHECK_COMMON_NAME
¶ OpenSSL 库是否具有对不检测目标通用名称的内置支持且
SSLContext.hostname_checks_common_name
为可写状态。3.7 版新加入.
-
ssl.
HAS_ECDH
¶ OpenSSL 库是否具有对基于椭圆曲线的 Diffie-Hellman 密钥交换的内置支持。 此常量应当为真值,除非发布者明确地禁用了此功能。
3.3 版新加入.
-
ssl.
HAS_NPN
¶ OpenSSL 库是否具有对 应用层协议协商 中描述的 下一协议协商 的内置支持。 当此常量为真值时,你可以使用
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 Alert Registry 中包含了这个列表及对定义其含义的 RFC 引用。
被用作
SSLContext.set_servername_callback()
中的回调函数的返回值。3.4 版新加入.
-
class
ssl.
AlertDescription
¶ ALERT_DESCRIPTION_* 常量的
enum.IntEnum
多项集。3.6 版新加入.
-
Purpose.
SERVER_AUTH
¶ create_default_context()
和SSLContext.load_default_certs()
的选项值。 这个值表明此上下文可以被用来验证 Web 服务器(因此,它将被用来创建客户端套接字)。3.4 版新加入.
-
Purpose.
CLIENT_AUTH
¶ create_default_context()
和SSLContext.load_default_certs()
的选项值。 这个值表明此上下文可以被用来验证 Web 客户端(因此,它将被用来创建服务器端套接字)。3.4 版新加入.
-
class
ssl.
SSLErrorNumber
¶ SSL_ERROR_* 常量的
enum.IntEnum
多项集。3.6 版新加入.
-
class
ssl.
TLSVersion
¶ SSLContext.maximum_version
和SSLContext.minimum_version
中的 SSL 和 TLS 版本的enum.IntEnum
多项集。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 套接字提供了 套接字对象 的下列方法:
recv()
,recv_into()
(but passing a non-zeroflags
argument is not allowed)sendfile()
(butos.sendfile
will be used for plain-text sockets only, elsesend()
will be used)
但是,由于 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()
来创建。 在较早的版本中,直接创建实例是可能的。 但这从未被记入文档或是被正式支持。
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()
尚未被调用。
-
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}
備註
要验证特定服务的证书,你可以使用
match_hostname()
函数。如果
binary_form
形参为True
,并且提供了证书,此方法会将整个证书的 DER 编码形式作为字节序列返回,或者如果对等方未提供证书则返回None
。 对等方是否提供证书取决于 SSL 套接字的角色:对于客户端 SSL 套接字,服务器将总是提供证书,无论是否需要进行验证;
对于服务器 SSL 套接字,客户端将仅在服务器要求时才提供证书;因此如果你使用了
CERT_NONE
(而不是CERT_OPTIONAL
或CERT_REQUIRED
) 则getpeercert()
将返回None
。
3.2 版更變: 返回的字典包括额外的条目例如
issuer
和notBefore
。3.4 版更變: 如果握手未完成则会引发
ValueError
。 返回的字典包括额外的 X509v3 扩展条目例如crlDistributionPoints
,caIssuers
和OCSP
URI。3.9 版更變: IPv6 地址字符串不再附带末尾换行符。
-
SSLSocket.
cipher
()¶ 返回由三个值组成的元组,其中包含所使用的密码名称,定义其使用方式的 SSL 协议版本,以及所使用的加密比特位数。 如果尚未建立连接,则返回
None
。
返回在握手期间由客户端共享的密码列表。 所返回列表的每个条目都是由三个值组成的元组,其中包括密码名称,定义其使用方式的 SSL 协议版本,以及密码所使用的加密比特位数。 如果尚未建立连接或套接字为客户端套接字则
shared_ciphers()
将返回None
。3.5 版新加入.
-
SSLSocket.
compression
()¶ 以字符串形式返回所使用的压缩算法,或者如果连接没有使用压缩则返回
None
。如果高层级的协议支持自己的压缩机制,你可以使用
OP_NO_COMPRESSION
来禁用 SSL 层级的压缩。3.3 版新加入.
-
SSLSocket.
get_channel_binding
(cb_type="tls-unique")¶ 为当前连接获取字节串形式的通道绑定数据。 如果尚未连接或握手尚未完成则返回
None
。cb_type 形参允许选择需要的通道绑定类型。 有效的通道绑定类型在
CHANNEL_BINDING_TYPES
列表中列出。 目前只支持由 RFC 5929 所定义的 'tls-unique' 通道绑定。 如果请求了一个不受支持的通道绑定类型则将引发ValueError
。3.3 版新加入.
-
SSLSocket.
selected_alpn_protocol
()¶ Return the protocol that was selected during the TLS handshake. If
SSLContext.set_alpn_protocols()
was not called, if the other party does not support ALPN, if this socket does not support any of the client's proposed protocols, or if the handshake has not happened yet,None
is returned.3.5 版新加入.
-
SSLSocket.
selected_npn_protocol
()¶ Return the higher-level protocol that was selected during the TLS/SSL handshake. If
SSLContext.set_npn_protocols()
was not called, or if the other party does not support NPN, or if the handshake has not yet happened, this will returnNone
.3.3 版新加入.
-
SSLSocket.
unwrap
()¶ Performs the SSL shutdown handshake, which removes the TLS layer from the underlying socket, and returns the underlying socket object. This can be used to go from encrypted operation over a connection to unencrypted. The returned socket should always be used for further communication with the other side of the connection, rather than the original socket.
-
SSLSocket.
verify_client_post_handshake
()¶ Requests post-handshake authentication (PHA) from a TLS 1.3 client. PHA can only be initiated for a TLS 1.3 connection from a server-side socket, after the initial TLS handshake and with PHA enabled on both sides, see
SSLContext.post_handshake_auth
.The method does not perform a cert exchange immediately. The server-side sends a CertificateRequest during the next write event and expects the client to respond with a certificate on the next read event.
If any precondition isn't met (e.g. not TLS 1.3, PHA not enabled), an
SSLError
is raised.備註
Only available with OpenSSL 1.1.1 and TLS 1.3 enabled. Without TLS 1.3 support, the method raises
NotImplementedError
.3.8 版新加入.
-
SSLSocket.
version
()¶ Return the actual SSL protocol version negotiated by the connection as a string, or
None
is no secure connection is established. As of this writing, possible return values include"SSLv2"
,"SSLv3"
,"TLSv1"
,"TLSv1.1"
and"TLSv1.2"
. Recent OpenSSL versions may define more return values.3.5 版新加入.
-
SSLSocket.
pending
()¶ Returns the number of already decrypted bytes available for read, pending on the connection.
-
SSLSocket.
context
¶ The
SSLContext
object this SSL socket is tied to. If the SSL socket was created using the deprecatedwrap_socket()
function (rather thanSSLContext.wrap_socket()
), this is a custom context object created for this SSL socket.3.2 版新加入.
-
SSLSocket.
server_side
¶ A boolean which is
True
for server-side sockets andFalse
for client-side sockets.3.2 版新加入.
-
SSLSocket.
server_hostname
¶ Hostname of the server:
str
type, orNone
for server-side socket or if the hostname was not specified in the constructor.3.2 版新加入.
3.7 版更變: The attribute is now always ASCII text. When
server_hostname
is an internationalized domain name (IDN), this attribute now stores the A-label form ("xn--pythn-mua.org"
), rather than the U-label form ("pythön.org"
).
-
SSLSocket.
session
¶ The
SSLSession
for this SSL connection. The session is available for client and server side sockets after the TLS handshake has been performed. For client sockets the session can be set beforedo_handshake()
has been called to reuse a session.3.6 版新加入.
-
SSLSocket.
session_reused
¶ 3.6 版新加入.
SSL Contexts¶
3.2 版新加入.
An SSL context holds various data longer-lived than single SSL connections, such as SSL configuration options, certificate(s) and private key(s). It also manages a cache of SSL sessions for server-side sockets, in order to speed up repeated connections from the same clients.
-
class
ssl.
SSLContext
(protocol=PROTOCOL_TLS)¶ Create a new SSL context. You may pass protocol which must be one of the
PROTOCOL_*
constants defined in this module. The parameter specifies which version of the SSL protocol to use. Typically, the server chooses a particular protocol version, and the client must adapt to the server's choice. Most of the versions are not interoperable with the other versions. If not specified, the default isPROTOCOL_TLS
; it provides the most compatibility with other versions.Here's a table showing which versions in a client (down the side) can connect to which versions in a server (along the top):
脚注
- 1(1,2)
SSLContext
disables SSLv2 withOP_NO_SSLv2
by default.- 2(1,2)
SSLContext
disables SSLv3 withOP_NO_SSLv3
by default.- 3(1,2)
TLS 1.3 protocol will be available with
PROTOCOL_TLS
in OpenSSL >= 1.1.1. There is no dedicated PROTOCOL constant for just TLS 1.3.
也參考
create_default_context()
lets thessl
module choose security settings for a given purpose.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 forPROTOCOL_SSLv2
), andOP_NO_SSLv3
(except forPROTOCOL_SSLv3
) are set by default. The initial cipher suite list contains onlyHIGH
ciphers, noNULL
ciphers and noMD5
ciphers (except forPROTOCOL_SSLv2
).
SSLContext
objects have the following methods and attributes:
-
SSLContext.
cert_store_stats
()¶ Get statistics about quantities of loaded X.509 certificates, count of X.509 certificates flagged as CA certificates and certificate revocation lists as dictionary.
Example for a context with one CA cert and one other cert:
>>> context.cert_store_stats() {'crl': 0, 'x509_ca': 1, 'x509': 2}
3.4 版新加入.
-
SSLContext.
load_cert_chain
(certfile, keyfile=None, password=None)¶ Load a private key and the corresponding certificate. The certfile string must be the path to a single file in PEM format containing the certificate as well as any number of CA certificates needed to establish the certificate's authenticity. The keyfile string, if present, must point to a file containing the private key in. Otherwise the private key will be taken from certfile as well. See the discussion of Certificates for more information on how the certificate is stored in the certfile.
The password argument may be a function to call to get the password for decrypting the private key. It will only be called if the private key is encrypted and a password is necessary. It will be called with no arguments, and it should return a string, bytes, or bytearray. If the return value is a string it will be encoded as UTF-8 before using it to decrypt the key. Alternatively a string, bytes, or bytearray value may be supplied directly as the password argument. It will be ignored if the private key is not encrypted and no password is needed.
If the password argument is not specified and a password is required, OpenSSL's built-in password prompting mechanism will be used to interactively prompt the user for a password.
An
SSLError
is raised if the private key doesn't match with the certificate.3.3 版更變: New optional argument password.
-
SSLContext.
load_default_certs
(purpose=Purpose.SERVER_AUTH)¶ Load a set of default "certification authority" (CA) certificates from default locations. On Windows it loads CA certs from the
CA
andROOT
system stores. On other systems it callsSSLContext.set_default_verify_paths()
. In the future the method may load CA certificates from other locations, too.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)¶ Load a set of "certification authority" (CA) certificates used to validate other peers' certificates when
verify_mode
is other thanCERT_NONE
. At least one of cafile or capath must be specified.This method can also load certification revocation lists (CRLs) in PEM or DER format. In order to make use of CRLs,
SSLContext.verify_flags
must be configured properly.The cafile string, if present, is the path to a file of concatenated CA certificates in PEM format. See the discussion of Certificates for more information about how to arrange the certificates in this file.
The capath string, if present, is the path to a directory containing several CA certificates in PEM format, following an OpenSSL specific layout.
The cadata object, if present, is either an ASCII string of one or more PEM-encoded certificates or a bytes-like object of DER-encoded certificates. Like with capath extra lines around PEM-encoded certificates are ignored but at least one certificate must be present.
3.4 版更變: New optional argument cadata
-
SSLContext.
get_ca_certs
(binary_form=False)¶ Get a list of loaded "certification authority" (CA) certificates. If the
binary_form
parameter isFalse
each list entry is a dict like the output ofSSLSocket.getpeercert()
. Otherwise the method returns a list of DER-encoded certificates. The returned list does not contain certificates from capath unless a certificate was requested and loaded by a SSL connection.備註
Certificates in a capath directory aren't loaded unless they have been used at least once.
3.4 版新加入.
-
SSLContext.
get_ciphers
()¶ Get a list of enabled ciphers. The list is in order of cipher priority. See
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
()¶ Load a set of default "certification authority" (CA) certificates from a filesystem path defined when building the OpenSSL library. Unfortunately, there's no easy way to know whether this method succeeds: no error is returned if no certificates are to be found. When the OpenSSL library is provided as part of the operating system, though, it is likely to be configured properly.
-
SSLContext.
set_ciphers
(ciphers)¶ Set the available ciphers for sockets created with this context. It should be a string in the OpenSSL cipher list format. If no cipher can be selected (because compile-time options or other configuration forbids use of all the specified ciphers), an
SSLError
will be raised.備註
when connected, the
SSLSocket.cipher()
method of SSL sockets will give the currently selected cipher.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)¶ Specify which protocols the socket should advertise during the SSL/TLS handshake. It should be a list of ASCII strings, like
['http/1.1', 'spdy/2']
, ordered by preference. The selection of a protocol will happen during the handshake, and will play out according to RFC 7301. After a successful handshake, theSSLSocket.selected_alpn_protocol()
method will return the agreed-upon protocol.This method will raise
NotImplementedError
ifHAS_ALPN
isFalse
.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)¶ Specify which protocols the socket should advertise during the SSL/TLS handshake. It should be a list of strings, like
['http/1.1', 'spdy/2']
, ordered by preference. The selection of a protocol will happen during the handshake, and will play out according to the Application Layer Protocol Negotiation. After a successful handshake, theSSLSocket.selected_npn_protocol()
method will return the agreed-upon protocol.This method will raise
NotImplementedError
ifHAS_NPN
isFalse
.3.3 版新加入.
-
SSLContext.
sni_callback
¶ Register a callback function that will be called after the TLS Client Hello handshake message has been received by the SSL/TLS server when the TLS client specifies a server name indication. The server name indication mechanism is specified in RFC 6066 section 3 - Server Name Indication.
Only one callback can be set per
SSLContext
. If sni_callback is set toNone
then the callback is disabled. Calling this function a subsequent time will disable the previously registered callback.The callback function will be called with three arguments; the first being the
ssl.SSLSocket
, the second is a string that represents the server name that the client is intending to communicate (orNone
if the TLS Client Hello does not contain a server name) and the third argument is the originalSSLContext
. The server name argument is text. For internationalized domain name, the server name is an IDN A-label ("xn--pythn-mua.org"
).A typical use of this callback is to change the
ssl.SSLSocket
'sSSLSocket.context
attribute to a new object of typeSSLContext
representing a certificate chain that matches the server name.Due to the early negotiation phase of the TLS connection, only limited methods and attributes are usable like
SSLSocket.selected_alpn_protocol()
andSSLSocket.context
.SSLSocket.getpeercert()
,SSLSocket.getpeercert()
,SSLSocket.cipher()
andSSLSocket.compress()
methods require that the TLS connection has progressed beyond the TLS Client Hello and therefore will not contain return meaningful values nor can they be called safely.The sni_callback function must return
None
to allow the TLS negotiation to continue. If a TLS failure is required, a constantALERT_DESCRIPTION_*
can be returned. Other return values will result in a TLS fatal error withALERT_DESCRIPTION_INTERNAL_ERROR
.If an exception is raised from the sni_callback function the TLS connection will terminate with a fatal TLS alert message
ALERT_DESCRIPTION_HANDSHAKE_FAILURE
.This method will raise
NotImplementedError
if the OpenSSL library had OPENSSL_NO_TLSEXT defined when it was built.3.7 版新加入.
-
SSLContext.
set_servername_callback
(server_name_callback)¶ This is a legacy API retained for backwards compatibility. When possible, you should use
sni_callback
instead. The given server_name_callback is similar to sni_callback, except that when the server hostname is an IDN-encoded internationalized domain name, the server_name_callback receives a decoded U-label ("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)¶ Load the key generation parameters for Diffie-Hellman (DH) key exchange. Using DH key exchange improves forward secrecy at the expense of computational resources (both on the server and on the client). The dhfile parameter should be the path to a file containing DH parameters in PEM format.
This setting doesn't apply to client sockets. You can also use the
OP_SINGLE_DH_USE
option to further improve security.3.3 版新加入.
-
SSLContext.
set_ecdh_curve
(curve_name)¶ Set the curve name for Elliptic Curve-based Diffie-Hellman (ECDH) key exchange. ECDH is significantly faster than regular DH while arguably as secure. The curve_name parameter should be a string describing a well-known elliptic curve, for example
prime256v1
for a widely supported curve.This setting doesn't apply to client sockets. You can also use the
OP_SINGLE_ECDH_USE
option to further improve security.This method is not available if
HAS_ECDH
isFalse
.3.3 版新加入.
也參考
- SSL/TLS & Perfect Forward Secrecy
Vincent Bernat.
-
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
(defaultSSLSocket
). The returned SSL socket is tied to the context, its settings and certificates. sock must be aSOCK_STREAM
socket; other socket types are unsupported.The parameter
server_side
is a boolean which identifies whether server-side or client-side behavior is desired from this socket.For client-side sockets, the context construction is lazy; if the underlying socket isn't connected yet, the context construction will be performed after
connect()
is called on the socket. For server-side sockets, if the socket has no remote peer, it is assumed to be a listening socket, and the server-side SSL wrapping is automatically performed on client connections accepted via theaccept()
method. The method may raiseSSLError
.On client connections, the optional parameter server_hostname specifies the hostname of the service which we are connecting to. This allows a single server to host multiple SSL-based services with distinct certificates, quite similarly to HTTP virtual hosts. Specifying server_hostname will raise a
ValueError
if server_side is true.The parameter
do_handshake_on_connect
specifies whether to do the SSL handshake automatically after doing asocket.connect()
, or whether the application program will call it explicitly, by invoking theSSLSocket.do_handshake()
method. CallingSSLSocket.do_handshake()
explicitly gives the program control over the blocking behavior of the socket I/O involved in the handshake.The parameter
suppress_ragged_eofs
specifies how theSSLSocket.recv()
method should signal unexpected EOF from the other end of the connection. If specified asTrue
(the default), it returns a normal EOF (an empty bytes object) in response to unexpected EOF errors raised from the underlying socket; ifFalse
, it will raise the exceptions back to the caller.session, see
session
.3.5 版更變: Always allow a server_hostname to be passed, even if OpenSSL does not have SNI.
3.6 版更變: session argument was added.
3.7 版更變: The method returns on instance of
SSLContext.sslsocket_class
instead of hard-codedSSLSocket
.
-
SSLContext.
sslsocket_class
¶ The return type of
SSLContext.wrap_socket()
, defaults toSSLSocket
. The attribute can be overridden on instance of class in order to return a custom subclass ofSSLSocket
.3.7 版新加入.
-
SSLContext.
wrap_bio
(incoming, outgoing, server_side=False, server_hostname=None, session=None)¶ Wrap the BIO objects incoming and outgoing and return an instance of
SSLContext.sslobject_class
(defaultSSLObject
). The SSL routines will read input data from the incoming BIO and write data to the outgoing BIO.The server_side, server_hostname and session parameters have the same meaning as in
SSLContext.wrap_socket()
.3.6 版更變: session argument was added.
3.7 版更變: The method returns on instance of
SSLContext.sslobject_class
instead of hard-codedSSLObject
.
-
SSLContext.
sslobject_class
¶ The return type of
SSLContext.wrap_bio()
, defaults toSSLObject
. The attribute can be overridden on instance of class in order to return a custom subclass ofSSLObject
.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
¶ Whether to match the peer cert's hostname with
match_hostname()
inSSLSocket.do_handshake()
. The context'sverify_mode
must be set toCERT_OPTIONAL
orCERT_REQUIRED
, and you must pass server_hostname towrap_socket()
in order to match the hostname. Enabling hostname checking automatically setsverify_mode
fromCERT_NONE
toCERT_REQUIRED
. It cannot be set back toCERT_NONE
as long as hostname checking is enabled. ThePROTOCOL_TLS_CLIENT
protocol enables hostname checking by default. With other protocols, hostname checking must be enabled explicitly.示例:
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
is now automatically changed toCERT_REQUIRED
when hostname checking is enabled andverify_mode
isCERT_NONE
. Previously the same operation would have failed with aValueError
.備註
This features requires OpenSSL 0.9.8f or newer.
-
SSLContext.
keylog_filename
¶ Write TLS keys to a keylog file, whenever key material is generated or received. The keylog file is designed for debugging purposes only. The file format is specified by NSS and used by many traffic analyzers such as Wireshark. The log file is opened in append-only mode. Writes are synchronized between threads, but not between processes.
3.8 版新加入.
備註
This features requires OpenSSL 1.1.1 or newer.
-
SSLContext.
maximum_version
¶ A
TLSVersion
enum member representing the highest supported TLS version. The value defaults toTLSVersion.MAXIMUM_SUPPORTED
. The attribute is read-only for protocols other thanPROTOCOL_TLS
,PROTOCOL_TLS_CLIENT
, andPROTOCOL_TLS_SERVER
.The attributes
maximum_version
,minimum_version
andSSLContext.options
all affect the supported SSL and TLS versions of the context. The implementation does not prevent invalid combination. For example a context withOP_NO_TLSv1_2
inoptions
andmaximum_version
set toTLSVersion.TLSv1_2
will not be able to establish a TLS 1.2 connection.備註
This attribute is not available unless the ssl module is compiled with OpenSSL 1.1.0g or newer.
3.7 版新加入.
-
SSLContext.
minimum_version
¶ Like
SSLContext.maximum_version
except it is the lowest supported version orTLSVersion.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
¶ An integer representing the set of SSL options enabled on this context. The default value is
OP_ALL
, but you can specify other options such asOP_NO_SSLv2
by ORing them together.備註
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
returnsOptions
flags:>>> ssl.create_default_context().options <Options.OP_ALL|OP_NO_SSLv3|OP_NO_SSLv2|OP_NO_COMPRESSION: 2197947391>
-
SSLContext.
post_handshake_auth
¶ Enable TLS 1.3 post-handshake client authentication. Post-handshake auth is disabled by default and a server can only request a TLS client certificate during the initial handshake. When enabled, a server may request a TLS client certificate at any time after the handshake.
When enabled on client-side sockets, the client signals the server that it supports post-handshake authentication.
When enabled on server-side sockets,
SSLContext.verify_mode
must be set toCERT_OPTIONAL
orCERT_REQUIRED
, too. The actual client cert exchange is delayed untilSSLSocket.verify_client_post_handshake()
is called and some I/O is performed.備註
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
¶ The protocol version chosen when constructing the context. This attribute is read-only.
-
SSLContext.
hostname_checks_common_name
¶ Whether
check_hostname
falls back to verify the cert's subject common name in the absence of a subject alternative name extension (default: true).備註
Only writeable with OpenSSL 1.1.0 or higher.
3.7 版新加入.
-
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
returnsVerifyFlags
flags:>>> ssl.create_default_context().verify_flags <VerifyFlags.VERIFY_X509_TRUSTED_FIRST: 32768>
-
SSLContext.
verify_mode
¶ Whether to try to verify other peers' certificates and how to behave if verification fails. This attribute must be one of
CERT_NONE
,CERT_OPTIONAL
orCERT_REQUIRED
.3.6 版更變:
SSLContext.verify_mode
returnsVerifyMode
enum:>>> ssl.create_default_context().verify_mode <VerifyMode.CERT_REQUIRED: 2>
Certificates¶
Certificates in general are part of a public-key / private-key system. In this system, each principal, (which may be a machine, or a person, or an organization) is assigned a unique two-part encryption key. One part of the key is public, and is called the public key; the other part is kept secret, and is called the private key. The two parts are related, in that if you encrypt a message with one of the parts, you can decrypt it with the other part, and only with the other part.
A certificate contains information about two principals. It contains the name of a subject, and the subject's public key. It also contains a statement by a second principal, the issuer, that the subject is who they claim to be, and that this is indeed the subject's public key. The issuer's statement is signed with the issuer's private key, which only the issuer knows. However, anyone can verify the issuer's statement by finding the issuer's public key, decrypting the statement with it, and comparing it to the other information in the certificate. The certificate also contains information about the time period over which it is valid. This is expressed as two fields, called "notBefore" and "notAfter".
In the Python use of certificates, a client or server can use a certificate to prove who they are. The other side of a network connection can also be required to produce a certificate, and that certificate can be validated to the satisfaction of the client or server that requires such validation. The connection attempt can be set to raise an exception if the validation fails. Validation is done automatically, by the underlying OpenSSL framework; the application need not concern itself with its mechanics. But the application does usually need to provide sets of certificates to allow this process to take place.
Python uses files to contain certificates. They should be formatted as "PEM" (see RFC 1422), which is a base-64 encoded form wrapped with a header line and a footer line:
-----BEGIN CERTIFICATE-----
... (certificate in base64 PEM encoding) ...
-----END CERTIFICATE-----
Certificate chains¶
The Python files which contain certificates can contain a sequence of certificates, sometimes called a certificate chain. This chain should start with the specific certificate for the principal who "is" the client or server, and then the certificate for the issuer of that certificate, and then the certificate for the issuer of that certificate, and so on up the chain till you get to a certificate which is self-signed, that is, a certificate which has the same subject and issuer, sometimes called a root certificate. The certificates should just be concatenated together in the certificate file. For example, suppose we had a three certificate chain, from our server certificate to the certificate of the certification authority that signed our server certificate, to the root certificate of the agency which issued the certification authority's certificate:
-----BEGIN CERTIFICATE-----
... (certificate for your server)...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
... (the certificate for the CA)...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
... (the root certificate for the CA's issuer)...
-----END CERTIFICATE-----
CA certificates¶
If you are going to require validation of the other side of the connection's
certificate, you need to provide a "CA certs" file, filled with the certificate
chains for each issuer you are willing to trust. Again, this file just contains
these chains concatenated together. For validation, Python will use the first
chain it finds in the file which matches. The platform's certificates file can
be used by calling SSLContext.load_default_certs()
, this is done
automatically with create_default_context()
.
Combined key and certificate¶
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-----
Self-signed certificates¶
If you are going to create a server that provides SSL-encrypted connection services, you will need to acquire a certificate for that service. There are many ways of acquiring appropriate certificates, such as buying one from a certification authority. Another common practice is to generate a self-signed certificate. The simplest way to do this is with the OpenSSL package, using something like the following:
% 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
%
The disadvantage of a self-signed certificate is that it is its own root certificate, and no one else will have it in their cache of known (and trusted) root certificates.
示例¶
Testing for SSL support¶
To test for the presence of SSL support in a Python installation, user code should use the following idiom:
try:
import ssl
except ImportError:
pass
else:
... # do something that requires SSL support
Client-side operation¶
This example creates a SSL context with the recommended security settings for client sockets, including automatic certificate verification:
>>> context = ssl.create_default_context()
If you prefer to tune security settings yourself, you might create a context from scratch (but beware that you might not get the settings right):
>>> context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
>>> context.load_verify_locations("/etc/ssl/certs/ca-bundle.crt")
(this snippet assumes your operating system places a bundle of all CA
certificates in /etc/ssl/certs/ca-bundle.crt
; if not, you'll get an
error and have to adjust the location)
The PROTOCOL_TLS_CLIENT
protocol configures the context for cert
validation and hostname verification. verify_mode
is
set to CERT_REQUIRED
and check_hostname
is set
to True
. All other protocols create SSL contexts with insecure defaults.
When you use the context to connect to a server, CERT_REQUIRED
and check_hostname
validate the server certificate: it
ensures that the server certificate was signed with one of the CA
certificates, checks the signature for correctness, and verifies other
properties like validity and identity of the hostname:
>>> conn = context.wrap_socket(socket.socket(socket.AF_INET),
... server_hostname="www.python.org")
>>> conn.connect(("www.python.org", 443))
You may then fetch the certificate:
>>> cert = conn.getpeercert()
Visual inspection shows that the certificate does identify the desired service
(that is, the HTTPS host 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}
Now the SSL channel is established and the certificate verified, you can proceed to talk with the server:
>>> 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'']
参见下文对于 Security considerations 的讨论。
Server-side operation¶
For server operation, typically you'll need to have a server certificate, and
private key, each in a file. You'll first create a context holding the key
and the certificate, so that clients can check your authenticity. Then
you'll open a socket, bind it to a port, call listen()
on it, and start
waiting for clients to connect:
import socket, ssl
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
context.load_cert_chain(certfile="mycertfile", keyfile="mykeyfile")
bindsocket = socket.socket()
bindsocket.bind(('myaddr.mydomain.com', 10023))
bindsocket.listen(5)
When a client connects, you'll call accept()
on the socket to get the
new socket from the other end, and use the context's SSLContext.wrap_socket()
method to create a server-side SSL socket for the connection:
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()
Then you'll read data from the connstream
and do something with it till you
are finished with the client (or the client is finished with you):
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
And go back to listening for new client connections (of course, a real server would probably handle each client connection in a separate thread, or put the sockets in non-blocking mode and use an event loop).
Notes on non-blocking sockets¶
SSL sockets behave slightly different than regular sockets in non-blocking mode. When working with non-blocking sockets, there are thus several things you need to be aware of:
Most
SSLSocket
methods will raise eitherSSLWantWriteError
orSSLWantReadError
instead ofBlockingIOError
if an I/O operation would block.SSLWantReadError
will be raised if a read operation on the underlying socket is necessary, andSSLWantWriteError
for a write operation on the underlying socket. Note that attempts to write to an SSL socket may require reading from the underlying socket first, and attempts to read from the SSL socket may require a prior write to the underlying socket.3.5 版更變: In earlier Python versions, the
SSLSocket.send()
method returned zero instead of raisingSSLWantWriteError
orSSLWantReadError
.Calling
select()
tells you that the OS-level socket can be read from (or written to), but it does not imply that there is sufficient data at the upper SSL layer. For example, only part of an SSL frame might have arrived. Therefore, you must be ready to handleSSLSocket.recv()
andSSLSocket.send()
failures, and retry after another call toselect()
.Conversely, since the SSL layer has its own framing, a SSL socket may still have data available for reading without
select()
being aware of it. Therefore, you should first callSSLSocket.recv()
to drain any potentially available data, and then only block on aselect()
call if still necessary.(of course, similar provisions apply when using other primitives such as
poll()
, or those in theselectors
module)The SSL handshake itself will be non-blocking: the
SSLSocket.do_handshake()
method has to be retried until it returns successfully. Here is a synopsis usingselect()
to wait for the socket's readiness:while True: try: sock.do_handshake() break except ssl.SSLWantReadError: select.select([sock], [], []) except ssl.SSLWantWriteError: select.select([], [sock], [])
也參考
The asyncio
module supports non-blocking SSL sockets and provides a
higher level API. It polls for events using the selectors
module and
handles SSLWantWriteError
, SSLWantReadError
and
BlockingIOError
exceptions. It runs the SSL handshake asynchronously
as well.
Memory BIO Support¶
3.5 版新加入.
Ever since the SSL module was introduced in Python 2.6, the SSLSocket
class has provided two related but distinct areas of functionality:
SSL protocol handling
Network IO
The network IO API is identical to that provided by socket.socket
,
from which SSLSocket
also inherits. This allows an SSL socket to be
used as a drop-in replacement for a regular socket, making it very easy to add
SSL support to an existing application.
Combining SSL protocol handling and network IO usually works well, but there
are some cases where it doesn't. An example is async IO frameworks that want to
use a different IO multiplexing model than the "select/poll on a file
descriptor" (readiness based) model that is assumed by socket.socket
and by the internal OpenSSL socket IO routines. This is mostly relevant for
platforms like Windows where this model is not efficient. For this purpose, a
reduced scope variant of SSLSocket
called SSLObject
is
provided.
-
class
ssl.
SSLObject
¶ A reduced-scope variant of
SSLSocket
representing an SSL protocol instance that does not contain any network IO methods. This class is typically used by framework authors that want to implement asynchronous IO for SSL through memory buffers.This class implements an interface on top of a low-level SSL object as implemented by OpenSSL. This object captures the state of an SSL connection but does not provide any network IO itself. IO needs to be performed through separate "BIO" objects which are OpenSSL's IO abstraction layer.
This class has no public constructor. An
SSLObject
instance must be created using thewrap_bio()
method. This method will create theSSLObject
instance and bind it to a pair of BIOs. The incoming BIO is used to pass data from Python to the SSL protocol instance, while the outgoing BIO is used to pass data the other way around.可以使用以下方法:
When compared to
SSLSocket
, this object lacks the following features:Any form of network IO;
recv()
andsend()
read and write only to the underlyingMemoryBIO
buffers.There is no do_handshake_on_connect machinery. You must always manually call
do_handshake()
to start the handshake.There is no handling of suppress_ragged_eofs. All end-of-file conditions that are in violation of the protocol are reported via the
SSLEOFError
exception.The method
unwrap()
call does not return anything, unlike for an SSL socket where it returns the underlying socket.The server_name_callback callback passed to
SSLContext.set_servername_callback()
will get anSSLObject
instance instead of aSSLSocket
instance as its first parameter.
Some notes related to the use of
SSLObject
:All IO on an
SSLObject
is non-blocking. This means that for exampleread()
will raise anSSLWantReadError
if it needs more data than the incoming BIO has available.There is no module-level
wrap_bio()
call like there is forwrap_socket()
. AnSSLObject
is always created via anSSLContext
.
3.7 版更變:
SSLObject
instances must to created withwrap_bio()
. In earlier versions, it was possible to create instances directly. This was never documented or officially supported.
An SSLObject communicates with the outside world using memory buffers. The
class MemoryBIO
provides a memory buffer that can be used for this
purpose. It wraps an OpenSSL memory BIO (Basic IO) object:
-
class
ssl.
MemoryBIO
¶ A memory buffer that can be used to pass data between Python and an SSL protocol instance.
-
pending
¶ Return the number of bytes currently in the memory buffer.
-
eof
¶ A boolean indicating whether the memory BIO is current at the end-of-file position.
-
read
(n=-1)¶ Read up to n bytes from the memory buffer. If n is not specified or negative, all bytes are returned.
-
write
(buf)¶ Write the bytes from buf to the memory BIO. The buf argument must be an object supporting the buffer protocol.
The return value is the number of bytes written, which is always equal to the length of buf.
-
SSL session¶
3.6 版新加入.
Security considerations¶
Best defaults¶
For client use, if you don't have any special requirements for your
security policy, it is highly recommended that you use the
create_default_context()
function to create your SSL context.
It will load the system's trusted CA certificates, enable certificate
validation and hostname checking, and try to choose reasonably secure
protocol and cipher settings.
For example, here is how you would use the smtplib.SMTP
class to
create a trusted, secure connection to a SMTP server:
>>> 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')
If a client certificate is needed for the connection, it can be added with
SSLContext.load_cert_chain()
.
By contrast, if you create the SSL context by calling the SSLContext
constructor yourself, it will not have certificate validation nor hostname
checking enabled by default. If you do so, please read the paragraphs below
to achieve a good security level.
Manual settings¶
Verifying certificates¶
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 版更變: Hostname matchings is now performed by OpenSSL. Python no longer uses
match_hostname()
.
In server mode, if you want to authenticate your clients using the SSL layer
(rather than using a higher-level authentication mechanism), you'll also have
to specify CERT_REQUIRED
and similarly check the client certificate.
Protocol versions¶
SSL versions 2 and 3 are considered insecure and are therefore dangerous to
use. If you want maximum compatibility between clients and servers, it is
recommended to use PROTOCOL_TLS_CLIENT
or
PROTOCOL_TLS_SERVER
as the protocol version. SSLv2 and SSLv3 are
disabled by default.
>>> 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.
Cipher selection¶
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.
Multi-processing¶
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 uses a disjunct set of cipher suites. All AES-GCM and ChaCha20 cipher suites are enabled by default. The method
SSLContext.set_ciphers()
cannot enable or disable any TLS 1.3 ciphers yet, butSSLContext.get_ciphers()
returns them.Session tickets are no longer sent as part of the initial handshake and are handled differently.
SSLSocket.session
andSSLSession
are not compatible with TLS 1.3.Client-side certificates are also no longer verified during the initial handshake. A server can request a certificate at any time. Clients process certificate requests while they send or receive application data from the server.
TLS 1.3 features like early data, deferred TLS client cert request, signature algorithm configuration, and rekeying are not supported yet.
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.
LibreSSL >= 2.6.1 no longer supports NPN. The methods
SSLContext.set_npn_protocols()
andSSLSocket.selected_npn_protocol()
are not available.SSLContext.set_default_verify_paths()
ignores the env varsSSL_CERT_FILE
andSSL_CERT_PATH
althoughget_default_verify_paths()
still reports them.
也參考
- Class
socket.socket
Documentation of underlying
socket
class- SSL/TLS Strong Encryption: An Introduction
Apache HTTP Server文档介绍
- RFC 1422: Privacy Enhancement for Internet Electronic Mail: Part II: Certificate-Based Key Management
Steve Kent
- RFC 4086: Randomness Requirements for Security
Donald E., Jeffrey I. Schiller
- RFC 5280: Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile
D. Cooper
- RFC 5246: The Transport Layer Security (TLS) Protocol Version 1.2
T. Dierks et. al.
- RFC 6066: Transport Layer Security (TLS) Extensions
D. Eastlake
- IANA TLS: Transport Layer Security (TLS) Parameters
IANA
- RFC 7525: Recommendations for Secure Use of Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS)
IETF
- Mozilla's Server Side TLS recommendations
Mozilla