2635 lines
302 KiB
HTML
2635 lines
302 KiB
HTML
|
||
<!DOCTYPE html>
|
||
|
||
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh_CN">
|
||
<head>
|
||
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||
|
||
<title>ssl --- 套接字对象的 TLS/SSL 包装器 — Python 3.8.20 文档</title><meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
|
||
<link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
|
||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||
|
||
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||
<script src="../_static/jquery.js"></script>
|
||
<script src="../_static/underscore.js"></script>
|
||
<script src="../_static/doctools.js"></script>
|
||
<script src="../_static/language_data.js"></script>
|
||
<script src="../_static/translations.js"></script>
|
||
|
||
<script src="../_static/sidebar.js"></script>
|
||
|
||
<link rel="search" type="application/opensearchdescription+xml"
|
||
title="在 Python 3.8.20 文档 中搜索"
|
||
href="../_static/opensearch.xml"/>
|
||
<link rel="author" title="关于这些文档" href="../about.html" />
|
||
<link rel="index" title="索引" href="../genindex.html" />
|
||
<link rel="search" title="搜索" href="../search.html" />
|
||
<link rel="copyright" title="版权所有" href="../copyright.html" />
|
||
<link rel="next" title="select --- 等待 I/O 完成" href="select.html" />
|
||
<link rel="prev" title="socket --- 底层网络接口" href="socket.html" />
|
||
<link rel="canonical" href="https://docs.python.org/3/library/ssl.html" />
|
||
|
||
|
||
|
||
|
||
|
||
<style>
|
||
@media only screen {
|
||
table.full-width-table {
|
||
width: 100%;
|
||
}
|
||
}
|
||
</style>
|
||
<link rel="shortcut icon" type="image/png" href="../_static/py.svg" />
|
||
<script type="text/javascript" src="../_static/copybutton.js"></script>
|
||
<script type="text/javascript" src="../_static/menu.js"></script>
|
||
|
||
</head>
|
||
<body>
|
||
<div class="mobile-nav">
|
||
<input type="checkbox" id="menuToggler" class="toggler__input" aria-controls="navigation"
|
||
aria-pressed="false" aria-expanded="false" role="button" aria-label="Menu" />
|
||
<label for="menuToggler" class="toggler__label">
|
||
<span></span>
|
||
</label>
|
||
<nav class="nav-content" role="navigation">
|
||
<a href="https://www.python.org/" class="nav-logo">
|
||
<img src="../_static/py.svg" alt="Logo"/>
|
||
</a>
|
||
<div class="version_switcher_placeholder"></div>
|
||
<form role="search" class="search" action="../search.html" method="get">
|
||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" class="search-icon">
|
||
<path fill-rule="nonzero"
|
||
d="M15.5 14h-.79l-.28-.27a6.5 6.5 0 001.48-5.34c-.47-2.78-2.79-5-5.59-5.34a6.505 6.505 0 00-7.27 7.27c.34 2.8 2.56 5.12 5.34 5.59a6.5 6.5 0 005.34-1.48l.27.28v.79l4.25 4.25c.41.41 1.08.41 1.49 0 .41-.41.41-1.08 0-1.49L15.5 14zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z" fill="#444"></path>
|
||
</svg>
|
||
<input type="text" name="q" aria-label="快速搜索"/>
|
||
<input type="submit" value="转向"/>
|
||
</form>
|
||
</nav>
|
||
<div class="menu-wrapper">
|
||
<nav class="menu" role="navigation" aria-label="main navigation">
|
||
<div class="language_switcher_placeholder"></div>
|
||
<h3><a href="../contents.html">目录</a></h3>
|
||
<ul>
|
||
<li><a class="reference internal" href="#"><code class="xref py py-mod docutils literal notranslate"><span class="pre">ssl</span></code> --- 套接字对象的 TLS/SSL 包装器</a><ul>
|
||
<li><a class="reference internal" href="#functions-constants-and-exceptions">方法、常量和异常处理</a><ul>
|
||
<li><a class="reference internal" href="#socket-creation">套接字创建</a></li>
|
||
<li><a class="reference internal" href="#context-creation">上下文创建</a></li>
|
||
<li><a class="reference internal" href="#exceptions">异常</a></li>
|
||
<li><a class="reference internal" href="#random-generation">随机生成</a></li>
|
||
<li><a class="reference internal" href="#certificate-handling">证书处理</a></li>
|
||
<li><a class="reference internal" href="#constants">常量</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#ssl-sockets">SSL 套接字</a></li>
|
||
<li><a class="reference internal" href="#ssl-contexts">SSL 上下文</a></li>
|
||
<li><a class="reference internal" href="#certificates">证书</a><ul>
|
||
<li><a class="reference internal" href="#certificate-chains">证书链</a></li>
|
||
<li><a class="reference internal" href="#ca-certificates">CA 证书</a></li>
|
||
<li><a class="reference internal" href="#combined-key-and-certificate">合并的密钥和证书</a></li>
|
||
<li><a class="reference internal" href="#self-signed-certificates">自签名证书</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#examples">例子</a><ul>
|
||
<li><a class="reference internal" href="#testing-for-ssl-support">检测 SSL 支持</a></li>
|
||
<li><a class="reference internal" href="#client-side-operation">客户端操作</a></li>
|
||
<li><a class="reference internal" href="#server-side-operation">服务器端操作</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#notes-on-non-blocking-sockets">关于非阻塞套接字的说明</a></li>
|
||
<li><a class="reference internal" href="#memory-bio-support">内存 BIO 支持</a></li>
|
||
<li><a class="reference internal" href="#ssl-session">SSL 会话</a></li>
|
||
<li><a class="reference internal" href="#security-considerations">安全考量</a><ul>
|
||
<li><a class="reference internal" href="#best-defaults">最佳默认值</a></li>
|
||
<li><a class="reference internal" href="#manual-settings">手动设置</a><ul>
|
||
<li><a class="reference internal" href="#verifying-certificates">验证证书</a></li>
|
||
<li><a class="reference internal" href="#protocol-versions">协议版本</a></li>
|
||
<li><a class="reference internal" href="#cipher-selection">密码选择</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#multi-processing">多进程</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#tls-1-3">TLS 1.3</a></li>
|
||
<li><a class="reference internal" href="#libressl-support">LibreSSL 支持</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
<h4>上一个主题</h4>
|
||
<p class="topless"><a href="socket.html"
|
||
title="上一章"><code class="xref py py-mod docutils literal notranslate"><span class="pre">socket</span></code> --- 底层网络接口</a></p>
|
||
<h4>下一个主题</h4>
|
||
<p class="topless"><a href="select.html"
|
||
title="下一章"><code class="xref py py-mod docutils literal notranslate"><span class="pre">select</span></code> --- 等待 I/O 完成</a></p>
|
||
<div role="note" aria-label="source link">
|
||
<h3>本页</h3>
|
||
<ul class="this-page-menu">
|
||
<li><a href="../bugs.html">报告 Bug</a></li>
|
||
<li>
|
||
<a href="https://github.com/python/cpython/blob/3.8/Doc/library/ssl.rst"
|
||
rel="nofollow">显示源代码
|
||
</a>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</nav>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="outdated-warning" style="padding: .5em; text-align: center; background-color: #FFBABA; color: #6A0E0E;">
|
||
这个文档所针对的是一个已不再受支持的 Python 旧版本。
|
||
你应当升级版本,并阅读
|
||
<a href="/3/library/ssl.html"> Python 当前稳定版本的文档</a>.
|
||
</div>
|
||
|
||
<div class="related" role="navigation" aria-label="related navigation">
|
||
<h3>导航</h3>
|
||
<ul>
|
||
<li class="right" style="margin-right: 10px">
|
||
<a href="../genindex.html" title="总目录"
|
||
accesskey="I">索引</a></li>
|
||
<li class="right" >
|
||
<a href="../py-modindex.html" title="Python 模块索引"
|
||
>模块</a> |</li>
|
||
<li class="right" >
|
||
<a href="select.html" title="select --- 等待 I/O 完成"
|
||
accesskey="N">下一页</a> |</li>
|
||
<li class="right" >
|
||
<a href="socket.html" title="socket --- 底层网络接口"
|
||
accesskey="P">上一页</a> |</li>
|
||
|
||
<li><img src="../_static/py.svg" alt="python logo" style="vertical-align: middle; margin-top: -1px"/></li>
|
||
<li><a href="https://www.python.org/">Python</a> »</li>
|
||
<li class="switchers">
|
||
<div class="language_switcher_placeholder"></div>
|
||
<div class="version_switcher_placeholder"></div>
|
||
</li>
|
||
<li>
|
||
|
||
</li>
|
||
<li id="cpython-language-and-version">
|
||
<a href="../index.html">3.8.20 Documentation</a> »
|
||
</li>
|
||
|
||
<li class="nav-item nav-item-1"><a href="index.html" >Python 标准库</a> »</li>
|
||
<li class="nav-item nav-item-2"><a href="ipc.html" accesskey="U">网络和进程间通信</a> »</li>
|
||
<li class="right">
|
||
|
||
|
||
<div class="inline-search" role="search">
|
||
<form class="inline-search" action="../search.html" method="get">
|
||
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
|
||
<input type="submit" value="转向" />
|
||
<input type="hidden" name="check_keywords" value="yes" />
|
||
<input type="hidden" name="area" value="default" />
|
||
</form>
|
||
</div>
|
||
|
|
||
</li>
|
||
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="document">
|
||
<div class="documentwrapper">
|
||
<div class="bodywrapper">
|
||
<div class="body" role="main">
|
||
|
||
<section id="module-ssl">
|
||
<span id="ssl-tls-ssl-wrapper-for-socket-objects"></span><h1><a class="reference internal" href="#module-ssl" title="ssl: TLS/SSL wrapper for socket objects"><code class="xref py py-mod docutils literal notranslate"><span class="pre">ssl</span></code></a> --- 套接字对象的 TLS/SSL 包装器<a class="headerlink" href="#module-ssl" title="永久链接至标题">¶</a></h1>
|
||
<p><strong>源代码:</strong> <a class="reference external" href="https://github.com/python/cpython/tree/3.8/Lib/ssl.py">Lib/ssl.py</a></p>
|
||
<span class="target" id="index-0"></span><hr class="docutils" id="index-1" />
|
||
<p>本模块保证了对传安全传输层协议"TLS"的访问 (SSL)加密,并且提供客户端和服务端层面的网络嵌套字层面的对等连接认证技术。本模块使用OpenSSL库。适用于所有现代Unix系统、Windows以及Mac OS X。只要Open SSL存在的系统,都有机会正常使用。</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">注解</p>
|
||
<p>某些行为可能具有平台依赖,因为调用是根据操作系统的嵌套字API。不同版本的Open SSL也会引起差异:例如Open SSL版本1.0.1 自带TLSv1.1 和 TLSv1.2</p>
|
||
</div>
|
||
<div class="admonition warning">
|
||
<p class="admonition-title">警告</p>
|
||
<p>在阅读 <a class="reference internal" href="#ssl-security"><span class="std std-ref">安全考量</span></a> 前不要使用此模块。 这样做可能会导致虚假的安全感,因为ssl模块的默认设置不一定适合你的应用程序。</p>
|
||
</div>
|
||
<p>文档本文档记录 <code class="docutils literal notranslate"><span class="pre">ssl</span></code> 模块的对象和函数;更多关于TLS,SSL,和证书的信息,请参阅下方的“详情”选项</p>
|
||
<p>本模块提供了一个类 <a class="reference internal" href="#ssl.SSLSocket" title="ssl.SSLSocket"><code class="xref py py-class docutils literal notranslate"><span class="pre">ssl.SSLSocket</span></code></a>,它派生自 <a class="reference internal" href="socket.html#socket.socket" title="socket.socket"><code class="xref py py-class docutils literal notranslate"><span class="pre">socket.socket</span></code></a> 类型,并提供类似套接字的包装器,也能够对通过带 SSL 套接字的数据进行加密和解密。 它支持一些额外方法例如 <code class="xref py py-meth docutils literal notranslate"><span class="pre">getpeercert()</span></code>,该方法可从连接的另一端获取证书,还有 <code class="xref py py-meth docutils literal notranslate"><span class="pre">cipher()</span></code>,该方法可获取安全连接所使用的密码。</p>
|
||
<p>对于更复杂的应用程序,<a class="reference internal" href="#ssl.SSLContext" title="ssl.SSLContext"><code class="xref py py-class docutils literal notranslate"><span class="pre">ssl.SSLContext</span></code></a> 类有助于管理设置项和证书,进而可以被使用 <a class="reference internal" href="#ssl.SSLContext.wrap_socket" title="ssl.SSLContext.wrap_socket"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLContext.wrap_socket()</span></code></a> 方法创建的 SSL 套接字继承。</p>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.5.3 版更改: </span>更新以支持和 OpenSSL 1.1.0 的链接</p>
|
||
</div>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.6 版更改: </span>OpenSSL 0.9.8、1.0.0 和 1.0.1 已过时,将不再被支持。在 ssl 模块未来的版本中,最低需要 OpenSSL 1.0.2 或 1.1.0。</p>
|
||
</div>
|
||
<section id="functions-constants-and-exceptions">
|
||
<h2>方法、常量和异常处理<a class="headerlink" href="#functions-constants-and-exceptions" title="永久链接至标题">¶</a></h2>
|
||
<section id="socket-creation">
|
||
<h3>套接字创建<a class="headerlink" href="#socket-creation" title="永久链接至标题">¶</a></h3>
|
||
<p>从 Python 3.2 和 2.7.9 开始,建议使用 <a class="reference internal" href="#ssl.SSLContext" title="ssl.SSLContext"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLContext</span></code></a> 实例的 <a class="reference internal" href="#ssl.SSLContext.wrap_socket" title="ssl.SSLContext.wrap_socket"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLContext.wrap_socket()</span></code></a> 来将套接字包装为 <a class="reference internal" href="#ssl.SSLSocket" title="ssl.SSLSocket"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLSocket</span></code></a> 对象。 辅助函数 <a class="reference internal" href="#ssl.create_default_context" title="ssl.create_default_context"><code class="xref py py-func docutils literal notranslate"><span class="pre">create_default_context()</span></code></a> 会返回一个新的带有安全默认设置的上下文。 旧的 <a class="reference internal" href="#ssl.wrap_socket" title="ssl.wrap_socket"><code class="xref py py-func docutils literal notranslate"><span class="pre">wrap_socket()</span></code></a> 函数已被弃用,因为它效率较差并且不支持服务器名称提示(SNI)和主机匹配。</p>
|
||
<p>客户端套接字实例,采用默认上下文和IPv4/IPv6双栈:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">socket</span>
|
||
<span class="kn">import</span> <span class="nn">ssl</span>
|
||
|
||
<span class="n">hostname</span> <span class="o">=</span> <span class="s1">'www.python.org'</span>
|
||
<span class="n">context</span> <span class="o">=</span> <span class="n">ssl</span><span class="o">.</span><span class="n">create_default_context</span><span class="p">()</span>
|
||
|
||
<span class="k">with</span> <span class="n">socket</span><span class="o">.</span><span class="n">create_connection</span><span class="p">((</span><span class="n">hostname</span><span class="p">,</span> <span class="mi">443</span><span class="p">))</span> <span class="k">as</span> <span class="n">sock</span><span class="p">:</span>
|
||
<span class="k">with</span> <span class="n">context</span><span class="o">.</span><span class="n">wrap_socket</span><span class="p">(</span><span class="n">sock</span><span class="p">,</span> <span class="n">server_hostname</span><span class="o">=</span><span class="n">hostname</span><span class="p">)</span> <span class="k">as</span> <span class="n">ssock</span><span class="p">:</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">ssock</span><span class="o">.</span><span class="n">version</span><span class="p">())</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>客户端套接字示例,带有自定义上下文和IPv4:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">hostname</span> <span class="o">=</span> <span class="s1">'www.python.org'</span>
|
||
<span class="c1"># PROTOCOL_TLS_CLIENT requires valid cert chain and hostname</span>
|
||
<span class="n">context</span> <span class="o">=</span> <span class="n">ssl</span><span class="o">.</span><span class="n">SSLContext</span><span class="p">(</span><span class="n">ssl</span><span class="o">.</span><span class="n">PROTOCOL_TLS_CLIENT</span><span class="p">)</span>
|
||
<span class="n">context</span><span class="o">.</span><span class="n">load_verify_locations</span><span class="p">(</span><span class="s1">'path/to/cabundle.pem'</span><span class="p">)</span>
|
||
|
||
<span class="k">with</span> <span class="n">socket</span><span class="o">.</span><span class="n">socket</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">AF_INET</span><span class="p">,</span> <span class="n">socket</span><span class="o">.</span><span class="n">SOCK_STREAM</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="k">as</span> <span class="n">sock</span><span class="p">:</span>
|
||
<span class="k">with</span> <span class="n">context</span><span class="o">.</span><span class="n">wrap_socket</span><span class="p">(</span><span class="n">sock</span><span class="p">,</span> <span class="n">server_hostname</span><span class="o">=</span><span class="n">hostname</span><span class="p">)</span> <span class="k">as</span> <span class="n">ssock</span><span class="p">:</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">ssock</span><span class="o">.</span><span class="n">version</span><span class="p">())</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>服务器套接字实例,在localhost上监听IPv4:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">context</span> <span class="o">=</span> <span class="n">ssl</span><span class="o">.</span><span class="n">SSLContext</span><span class="p">(</span><span class="n">ssl</span><span class="o">.</span><span class="n">PROTOCOL_TLS_SERVER</span><span class="p">)</span>
|
||
<span class="n">context</span><span class="o">.</span><span class="n">load_cert_chain</span><span class="p">(</span><span class="s1">'/path/to/certchain.pem'</span><span class="p">,</span> <span class="s1">'/path/to/private.key'</span><span class="p">)</span>
|
||
|
||
<span class="k">with</span> <span class="n">socket</span><span class="o">.</span><span class="n">socket</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">AF_INET</span><span class="p">,</span> <span class="n">socket</span><span class="o">.</span><span class="n">SOCK_STREAM</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="k">as</span> <span class="n">sock</span><span class="p">:</span>
|
||
<span class="n">sock</span><span class="o">.</span><span class="n">bind</span><span class="p">((</span><span class="s1">'127.0.0.1'</span><span class="p">,</span> <span class="mi">8443</span><span class="p">))</span>
|
||
<span class="n">sock</span><span class="o">.</span><span class="n">listen</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
|
||
<span class="k">with</span> <span class="n">context</span><span class="o">.</span><span class="n">wrap_socket</span><span class="p">(</span><span class="n">sock</span><span class="p">,</span> <span class="n">server_side</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span> <span class="k">as</span> <span class="n">ssock</span><span class="p">:</span>
|
||
<span class="n">conn</span><span class="p">,</span> <span class="n">addr</span> <span class="o">=</span> <span class="n">ssock</span><span class="o">.</span><span class="n">accept</span><span class="p">()</span>
|
||
<span class="o">...</span>
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
<section id="context-creation">
|
||
<h3>上下文创建<a class="headerlink" href="#context-creation" title="永久链接至标题">¶</a></h3>
|
||
<p>便捷函数,可以帮助创建 <a class="reference internal" href="#ssl.SSLContext" title="ssl.SSLContext"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLContext</span></code></a> 对象,用于常见的目的。</p>
|
||
<dl class="function">
|
||
<dt id="ssl.create_default_context">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">create_default_context</code><span class="sig-paren">(</span><em class="sig-param">purpose=Purpose.SERVER_AUTH</em>, <em class="sig-param">cafile=None</em>, <em class="sig-param">capath=None</em>, <em class="sig-param">cadata=None</em><span class="sig-paren">)</span><a class="headerlink" href="#ssl.create_default_context" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>返回一个新的 <a class="reference internal" href="#ssl.SSLContext" title="ssl.SSLContext"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLContext</span></code></a> 对象,使用给定 <em>purpose</em> 的默认设置。 该设置由 <a class="reference internal" href="#module-ssl" title="ssl: TLS/SSL wrapper for socket objects"><code class="xref py py-mod docutils literal notranslate"><span class="pre">ssl</span></code></a> 模块选择,并且通常是代表一个比直接调用 <a class="reference internal" href="#ssl.SSLContext" title="ssl.SSLContext"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLContext</span></code></a> 构造器时更高的安全等级。</p>
|
||
<p><em>cafile</em>, <em>capath</em>, <em>cadata</em> 代表用于进行证书核验的可选受信任 CA 证书,与 <a class="reference internal" href="#ssl.SSLContext.load_verify_locations" title="ssl.SSLContext.load_verify_locations"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLContext.load_verify_locations()</span></code></a> 的一致。 如果三个参数均为 <a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal notranslate"><span class="pre">None</span></code></a>,此函数可以转而选择信任系统的默认 CA 证书。</p>
|
||
<p>设置为: <a class="reference internal" href="#ssl.PROTOCOL_TLS" title="ssl.PROTOCOL_TLS"><code class="xref py py-data docutils literal notranslate"><span class="pre">PROTOCOL_TLS</span></code></a>, <a class="reference internal" href="#ssl.OP_NO_SSLv2" title="ssl.OP_NO_SSLv2"><code class="xref py py-data docutils literal notranslate"><span class="pre">OP_NO_SSLv2</span></code></a> 和 <a class="reference internal" href="#ssl.OP_NO_SSLv3" title="ssl.OP_NO_SSLv3"><code class="xref py py-data docutils literal notranslate"><span class="pre">OP_NO_SSLv3</span></code></a>,带有不含 RC4 及未认证的高强度加密密码套件。 传入 <a class="reference internal" href="#ssl.Purpose.SERVER_AUTH" title="ssl.Purpose.SERVER_AUTH"><code class="xref py py-data docutils literal notranslate"><span class="pre">SERVER_AUTH</span></code></a> 作为 <em>purpose</em> 会将 <a class="reference internal" href="#ssl.SSLContext.verify_mode" title="ssl.SSLContext.verify_mode"><code class="xref py py-data docutils literal notranslate"><span class="pre">verify_mode</span></code></a> 设为 <a class="reference internal" href="#ssl.CERT_REQUIRED" title="ssl.CERT_REQUIRED"><code class="xref py py-data docutils literal notranslate"><span class="pre">CERT_REQUIRED</span></code></a> 并加载 CA 证书 (若给出 <em>cafile</em>, <em>capath</em> 或 <em>cadata</em> 之一) 或用 <a class="reference internal" href="#ssl.SSLContext.load_default_certs" title="ssl.SSLContext.load_default_certs"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLContext.load_default_certs()</span></code></a> 加载默认 CA 证书。</p>
|
||
<p>当 <a class="reference internal" href="#ssl.SSLContext.keylog_filename" title="ssl.SSLContext.keylog_filename"><code class="xref py py-attr docutils literal notranslate"><span class="pre">keylog_filename</span></code></a> 受支持并且设置了环境变量 <span class="target" id="index-52"></span><code class="xref std std-envvar docutils literal notranslate"><span class="pre">SSLKEYLOGFILE</span></code> 时,<a class="reference internal" href="#ssl.create_default_context" title="ssl.create_default_context"><code class="xref py py-func docutils literal notranslate"><span class="pre">create_default_context()</span></code></a> 会启用密钥日志记录。</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">注解</p>
|
||
<p>协议、选项、密码和其他设置可随时更改为更具约束性的值而无须事先弃用。 这些值代表了兼容性和安全性之间的合理平衡。</p>
|
||
<p>如果你的应用需要特定的设置,你应当创建一个 <a class="reference internal" href="#ssl.SSLContext" title="ssl.SSLContext"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLContext</span></code></a> 并自行应用设置。</p>
|
||
</div>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">注解</p>
|
||
<p>如果你发现当某些较旧的客户端或服务器尝试与用此函数创建的 <a class="reference internal" href="#ssl.SSLContext" title="ssl.SSLContext"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLContext</span></code></a> 进行连接时收到了报错提示 "Protocol or cipher suite mismatch",这可能是因为它们只支持 SSL3.0 而它被此函数用 <a class="reference internal" href="#ssl.OP_NO_SSLv3" title="ssl.OP_NO_SSLv3"><code class="xref py py-data docutils literal notranslate"><span class="pre">OP_NO_SSLv3</span></code></a> 排除掉了。 SSL3.0 被广泛认为 <a class="reference external" href="https://en.wikipedia.org/wiki/POODLE">完全不可用</a>。 如果你仍希望继续使用此函数但仍允许 SSL 3.0 连接,你可以使用以下代码重新启用它们:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">ctx</span> <span class="o">=</span> <span class="n">ssl</span><span class="o">.</span><span class="n">create_default_context</span><span class="p">(</span><span class="n">Purpose</span><span class="o">.</span><span class="n">CLIENT_AUTH</span><span class="p">)</span>
|
||
<span class="n">ctx</span><span class="o">.</span><span class="n">options</span> <span class="o">&=</span> <span class="o">~</span><span class="n">ssl</span><span class="o">.</span><span class="n">OP_NO_SSLv3</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.4 新版功能.</span></p>
|
||
</div>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.4.4 版更改: </span>RC4 被从默认密码字符串中丢弃。</p>
|
||
</div>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.6 版更改: </span>ChaCha20/Poly1305 被添加到默认密码字符串中。</p>
|
||
<p>3DES 被从默认密码字符串中丢弃。</p>
|
||
</div>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.8 版更改: </span>增加了对密钥日志记录至 <span class="target" id="index-53"></span><code class="xref std std-envvar docutils literal notranslate"><span class="pre">SSLKEYLOGFILE</span></code> 的支持。</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
</section>
|
||
<section id="exceptions">
|
||
<h3>异常<a class="headerlink" href="#exceptions" title="永久链接至标题">¶</a></h3>
|
||
<dl class="exception">
|
||
<dt id="ssl.SSLError">
|
||
<em class="property">exception </em><code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">SSLError</code><a class="headerlink" href="#ssl.SSLError" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>引发此异常以提示来自下层 SSL 实现(目前由 OpenSSL 库提供)的错误。 它表示在下层网络连接之上叠加的高层级加密和验证层存在某种问题。 此错误是 <a class="reference internal" href="exceptions.html#OSError" title="OSError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">OSError</span></code></a> 的一个子类型。 <a class="reference internal" href="#ssl.SSLError" title="ssl.SSLError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SSLError</span></code></a> 实例的错误和消息是由 OpenSSL 库提供的。</p>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.3 版更改: </span><a class="reference internal" href="#ssl.SSLError" title="ssl.SSLError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SSLError</span></code></a> 曾经是 <a class="reference internal" href="socket.html#socket.error" title="socket.error"><code class="xref py py-exc docutils literal notranslate"><span class="pre">socket.error</span></code></a> 的一个子类型。</p>
|
||
</div>
|
||
<dl class="attribute">
|
||
<dt id="ssl.SSLError.library">
|
||
<code class="sig-name descname">library</code><a class="headerlink" href="#ssl.SSLError.library" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>一个字符串形式的助记符,用来指明发生错误的 OpenSSL 子模块,例如 <code class="docutils literal notranslate"><span class="pre">SSL</span></code>, <code class="docutils literal notranslate"><span class="pre">PEM</span></code> 或 <code class="docutils literal notranslate"><span class="pre">X509</span></code>。 可能的取值范围依赖于 OpenSSL 的版本。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.3 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="attribute">
|
||
<dt id="ssl.SSLError.reason">
|
||
<code class="sig-name descname">reason</code><a class="headerlink" href="#ssl.SSLError.reason" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>一个字符串形式的助记符,用来指明发生错误的原因,例如 <code class="docutils literal notranslate"><span class="pre">CERTIFICATE_VERIFY_FAILED</span></code>。 可能的取值范围依赖于 OpenSSL 的版本。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.3 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
</dd></dl>
|
||
|
||
<dl class="exception">
|
||
<dt id="ssl.SSLZeroReturnError">
|
||
<em class="property">exception </em><code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">SSLZeroReturnError</code><a class="headerlink" href="#ssl.SSLZeroReturnError" title="永久链接至目标">¶</a></dt>
|
||
<dd><p><a class="reference internal" href="#ssl.SSLError" title="ssl.SSLError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SSLError</span></code></a> 的子类,当尝试读取或写入且 SSL 连接已被完全关闭时会被引发。 请注意这并不意味着下层的传输(读取 TCP)已被关闭。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.3 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="exception">
|
||
<dt id="ssl.SSLWantReadError">
|
||
<em class="property">exception </em><code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">SSLWantReadError</code><a class="headerlink" href="#ssl.SSLWantReadError" title="永久链接至目标">¶</a></dt>
|
||
<dd><p><a class="reference internal" href="#ssl.SSLError" title="ssl.SSLError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SSLError</span></code></a> 的子类,当尝试读取或写入数据,但在请求被满足之前还需要在下层的 TCP 传输上接收更多数据时会被 <a class="reference internal" href="#ssl-nonblocking"><span class="std std-ref">非阻塞型 SSL 套接字</span></a> 引发。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.3 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="exception">
|
||
<dt id="ssl.SSLWantWriteError">
|
||
<em class="property">exception </em><code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">SSLWantWriteError</code><a class="headerlink" href="#ssl.SSLWantWriteError" title="永久链接至目标">¶</a></dt>
|
||
<dd><p><a class="reference internal" href="#ssl.SSLError" title="ssl.SSLError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SSLError</span></code></a> 的子类,当尝试读取或写入数据,但在请求被满足之前还需要在下层的 TCP 传输上发送更多数据时会被 <a class="reference internal" href="#ssl-nonblocking"><span class="std std-ref">非阻塞型 SSL 套接字</span></a> 引发。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.3 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="exception">
|
||
<dt id="ssl.SSLSyscallError">
|
||
<em class="property">exception </em><code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">SSLSyscallError</code><a class="headerlink" href="#ssl.SSLSyscallError" title="永久链接至目标">¶</a></dt>
|
||
<dd><p><a class="reference internal" href="#ssl.SSLError" title="ssl.SSLError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SSLError</span></code></a> 的子类,当尝试在 SSL 套接字上执行操作时遇到系统错误时会被引发。 不幸的是,没有简单的方式能检查原始 errno 编号。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.3 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="exception">
|
||
<dt id="ssl.SSLEOFError">
|
||
<em class="property">exception </em><code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">SSLEOFError</code><a class="headerlink" href="#ssl.SSLEOFError" title="永久链接至目标">¶</a></dt>
|
||
<dd><p><a class="reference internal" href="#ssl.SSLError" title="ssl.SSLError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SSLError</span></code></a> 的子类,当 SSL 连接被突然终止时会被引发。 通常,当遇到此错误时你不应再尝试重用下层的传输。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.3 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="exception">
|
||
<dt id="ssl.SSLCertVerificationError">
|
||
<em class="property">exception </em><code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">SSLCertVerificationError</code><a class="headerlink" href="#ssl.SSLCertVerificationError" title="永久链接至目标">¶</a></dt>
|
||
<dd><p><a class="reference internal" href="#ssl.SSLError" title="ssl.SSLError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SSLError</span></code></a> 的子类,当证书验证失败时会被引发。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.7 新版功能.</span></p>
|
||
</div>
|
||
<dl class="attribute">
|
||
<dt id="ssl.SSLCertVerificationError.verify_code">
|
||
<code class="sig-name descname">verify_code</code><a class="headerlink" href="#ssl.SSLCertVerificationError.verify_code" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>一个数字形式的错误编号,用于表示验证错误。</p>
|
||
</dd></dl>
|
||
|
||
<dl class="attribute">
|
||
<dt id="ssl.SSLCertVerificationError.verify_message">
|
||
<code class="sig-name descname">verify_message</code><a class="headerlink" href="#ssl.SSLCertVerificationError.verify_message" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>用于表示验证错误的人类可读的字符串。</p>
|
||
</dd></dl>
|
||
|
||
</dd></dl>
|
||
|
||
<dl class="exception">
|
||
<dt id="ssl.CertificateError">
|
||
<em class="property">exception </em><code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">CertificateError</code><a class="headerlink" href="#ssl.CertificateError" title="永久链接至目标">¶</a></dt>
|
||
<dd><p><a class="reference internal" href="#ssl.SSLCertVerificationError" title="ssl.SSLCertVerificationError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SSLCertVerificationError</span></code></a> 的别名。</p>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.7 版更改: </span>此异常现在是 <a class="reference internal" href="#ssl.SSLCertVerificationError" title="ssl.SSLCertVerificationError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SSLCertVerificationError</span></code></a> 的别名。</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
</section>
|
||
<section id="random-generation">
|
||
<h3>随机生成<a class="headerlink" href="#random-generation" title="永久链接至标题">¶</a></h3>
|
||
<dl class="function">
|
||
<dt id="ssl.RAND_bytes">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">RAND_bytes</code><span class="sig-paren">(</span><em class="sig-param">num</em><span class="sig-paren">)</span><a class="headerlink" href="#ssl.RAND_bytes" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>返回 <em>num</em> 个高加密强度伪随机字节数据。 如果 PRNG 未使用足够的数据作为随机种子或者如果当前 RAND 方法不支持该操作则会引发 <a class="reference internal" href="#ssl.SSLError" title="ssl.SSLError"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLError</span></code></a>。 <a class="reference internal" href="#ssl.RAND_status" title="ssl.RAND_status"><code class="xref py py-func docutils literal notranslate"><span class="pre">RAND_status()</span></code></a> 可被用来检查 PRNG 的状态而 <a class="reference internal" href="#ssl.RAND_add" title="ssl.RAND_add"><code class="xref py py-func docutils literal notranslate"><span class="pre">RAND_add()</span></code></a> 可被用来为 PRNG 设置随机种子。</p>
|
||
<p>对于几乎所有应用程序都更推荐使用 <a class="reference internal" href="os.html#os.urandom" title="os.urandom"><code class="xref py py-func docutils literal notranslate"><span class="pre">os.urandom()</span></code></a>。</p>
|
||
<p>Read the Wikipedia article, <a class="reference external" href="https://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator">Cryptographically secure pseudorandom number
|
||
generator (CSPRNG)</a>,
|
||
to get the requirements of a cryptographically generator.</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.3 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="ssl.RAND_pseudo_bytes">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">RAND_pseudo_bytes</code><span class="sig-paren">(</span><em class="sig-param">num</em><span class="sig-paren">)</span><a class="headerlink" href="#ssl.RAND_pseudo_bytes" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>返回 (bytes, is_cryptographic): bytes 是 <em>num</em> 个伪随机字节数据,如果所生成的字节数据为高加密强度则 is_cryptographic 为 <code class="docutils literal notranslate"><span class="pre">True</span></code>。 如果当前 RAND 方法不支持此操作则会引发 <a class="reference internal" href="#ssl.SSLError" title="ssl.SSLError"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLError</span></code></a>。</p>
|
||
<p>所生成的伪随机字节序列如果具有足够的长度则将会具有唯一性,并是并非不可预测。 它们可被用于非加密目的以及加密协议中的特定目的,但通常不可被用于密钥生成等目的。</p>
|
||
<p>对于几乎所有应用程序都更推荐使用 <a class="reference internal" href="os.html#os.urandom" title="os.urandom"><code class="xref py py-func docutils literal notranslate"><span class="pre">os.urandom()</span></code></a>。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.3 新版功能.</span></p>
|
||
</div>
|
||
<div class="deprecated">
|
||
<p><span class="versionmodified deprecated">3.6 版后已移除: </span>OpenSSL 已弃用了 <a class="reference internal" href="#ssl.RAND_pseudo_bytes" title="ssl.RAND_pseudo_bytes"><code class="xref py py-func docutils literal notranslate"><span class="pre">ssl.RAND_pseudo_bytes()</span></code></a>,请改用 <a class="reference internal" href="#ssl.RAND_bytes" title="ssl.RAND_bytes"><code class="xref py py-func docutils literal notranslate"><span class="pre">ssl.RAND_bytes()</span></code></a>。</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="ssl.RAND_status">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">RAND_status</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#ssl.RAND_status" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>如果 SSL 伪随机数生成器已使用‘足够的’随机性作为种子则返回 <code class="docutils literal notranslate"><span class="pre">True</span></code>,否则返回 <code class="docutils literal notranslate"><span class="pre">False</span></code>。 你可以使用 <a class="reference internal" href="#ssl.RAND_egd" title="ssl.RAND_egd"><code class="xref py py-func docutils literal notranslate"><span class="pre">ssl.RAND_egd()</span></code></a> 和 <a class="reference internal" href="#ssl.RAND_add" title="ssl.RAND_add"><code class="xref py py-func docutils literal notranslate"><span class="pre">ssl.RAND_add()</span></code></a> 来增加伪随机数生成器的随机性。</p>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="ssl.RAND_egd">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">RAND_egd</code><span class="sig-paren">(</span><em class="sig-param">path</em><span class="sig-paren">)</span><a class="headerlink" href="#ssl.RAND_egd" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>如果你在某处运行了一个熵收集守护程序(EGD),且 <em>path</em> 是向其打开的套接字连接路径名,此函数将从该套接字读取 256 个字节的随机性数据,并将其添加到 SSL 伪随机数生成器以增加所生成密钥的安全性。 此操作通常只在没有更好随机性源的系统上才是必要的。</p>
|
||
<p>请查看 <a class="reference external" href="http://egd.sourceforge.net/">http://egd.sourceforge.net/</a> 或 <a class="reference external" href="http://prngd.sourceforge.net/">http://prngd.sourceforge.net/</a> 来了解有关熵收集守护程序源的信息。</p>
|
||
<p class="availability"><a class="reference internal" href="intro.html#availability"><span class="std std-ref">可用性</span></a>: 对于 LibreSSL 和 OpenSSL > 1.1.0 不可用。</p>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="ssl.RAND_add">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">RAND_add</code><span class="sig-paren">(</span><em class="sig-param">bytes</em>, <em class="sig-param">entropy</em><span class="sig-paren">)</span><a class="headerlink" href="#ssl.RAND_add" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>将给定的 <em>bytes</em> 混合到 SSL 伪随机数生成器中。 形参 <em>entropy</em> (float 类型) 是数据所包含的熵的下界 (因此你可以总是使用 <code class="xref py py-const docutils literal notranslate"><span class="pre">0.0</span></code>)。 请查看 <span class="target" id="index-54"></span><a class="rfc reference external" href="https://tools.ietf.org/html/rfc1750.html"><strong>RFC 1750</strong></a> 了解有关熵源的更多信息。</p>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.5 版更改: </span>现在接受可写的 <a class="reference internal" href="../glossary.html#term-bytes-like-object"><span class="xref std std-term">字节类对象</span></a>。</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
</section>
|
||
<section id="certificate-handling">
|
||
<h3>证书处理<a class="headerlink" href="#certificate-handling" title="永久链接至标题">¶</a></h3>
|
||
<dl class="function">
|
||
<dt id="ssl.match_hostname">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">match_hostname</code><span class="sig-paren">(</span><em class="sig-param">cert</em>, <em class="sig-param">hostname</em><span class="sig-paren">)</span><a class="headerlink" href="#ssl.match_hostname" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>验证 <em>cert</em> (使用 <a class="reference internal" href="#ssl.SSLSocket.getpeercert" title="ssl.SSLSocket.getpeercert"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLSocket.getpeercert()</span></code></a> 所返回的已解码格式) 是否匹配给定的 <em>hostname</em>。 所应用的规则是在 <span class="target" id="index-55"></span><a class="rfc reference external" href="https://tools.ietf.org/html/rfc2818.html"><strong>RFC 2818</strong></a>, <span class="target" id="index-56"></span><a class="rfc reference external" href="https://tools.ietf.org/html/rfc5280.html"><strong>RFC 5280</strong></a> 和 <span class="target" id="index-57"></span><a class="rfc reference external" href="https://tools.ietf.org/html/rfc6125.html"><strong>RFC 6125</strong></a> 中描述的检查 HTTPS 服务器身份的规则。 除了 HTTPS,此函数还应当适用于各种基于 SSL 协议的服务器身份检查操作,例如 FTPS, IMAPS, POPS 等等。</p>
|
||
<p>失败时引发 <a class="reference internal" href="#ssl.CertificateError" title="ssl.CertificateError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">CertificateError</span></code></a>。 成功时此函数无返回值:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">cert</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'subject'</span><span class="p">:</span> <span class="p">(((</span><span class="s1">'commonName'</span><span class="p">,</span> <span class="s1">'example.com'</span><span class="p">),),)}</span>
|
||
<span class="gp">>>> </span><span class="n">ssl</span><span class="o">.</span><span class="n">match_hostname</span><span class="p">(</span><span class="n">cert</span><span class="p">,</span> <span class="s2">"example.com"</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">ssl</span><span class="o">.</span><span class="n">match_hostname</span><span class="p">(</span><span class="n">cert</span><span class="p">,</span> <span class="s2">"example.org"</span><span class="p">)</span>
|
||
<span class="gt">Traceback (most recent call last):</span>
|
||
File <span class="nb">"<stdin>"</span>, line <span class="m">1</span>, in <span class="n"><module></span>
|
||
File <span class="nb">"/home/py3k/Lib/ssl.py"</span>, line <span class="m">130</span>, in <span class="n">match_hostname</span>
|
||
<span class="gr">ssl.CertificateError</span>: <span class="n">hostname 'example.org' doesn't match 'example.com'</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.2 新版功能.</span></p>
|
||
</div>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.3.3 版更改: </span>此函数现在遵循 <span class="target" id="index-58"></span><a class="rfc reference external" href="https://tools.ietf.org/html/rfc6125.html"><strong>RFC 6125</strong></a>, 6.4.3 小节,它不会匹配多个通配符 (例如 <code class="docutils literal notranslate"><span class="pre">*.*.com</span></code> 或 <code class="docutils literal notranslate"><span class="pre">*a*.example.org</span></code>) 也不匹配国际化域名 (IDN) 片段内部的通配符。 IDN A 标签例如 <code class="docutils literal notranslate"><span class="pre">www*.xn--pthon-kva.org</span></code> 仍然受支持,但 <code class="docutils literal notranslate"><span class="pre">x*.python.org</span></code> 不再能匹配 <code class="docutils literal notranslate"><span class="pre">xn--tda.python.org</span></code>。</p>
|
||
</div>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.5 版更改: </span>现在支持匹配存在于证书的 subjectAltName 字段中的 IP 地址。</p>
|
||
</div>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.7 版更改: </span>此函数不再被用于 TLS 连接。 主机匹配现在是由 OpenSSL 执行的。</p>
|
||
<p>允许位于段的最左端且为唯一字符的通配符。 部分通配符例如 <code class="docutils literal notranslate"><span class="pre">www*.example.com</span></code> 已不再受支持。</p>
|
||
</div>
|
||
<div class="deprecated">
|
||
<p><span class="versionmodified deprecated">3.7 版后已移除.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="ssl.cert_time_to_seconds">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">cert_time_to_seconds</code><span class="sig-paren">(</span><em class="sig-param">cert_time</em><span class="sig-paren">)</span><a class="headerlink" href="#ssl.cert_time_to_seconds" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>返回距离 Unix 纪元零时的秒数,给定的 <code class="docutils literal notranslate"><span class="pre">cert_time</span></code> 字符串代表来自证书的 "notBefore" 或 "notAfter" 日期值,采用 <code class="docutils literal notranslate"><span class="pre">"%b</span> <span class="pre">%d</span> <span class="pre">%H:%M:%S</span> <span class="pre">%Y</span> <span class="pre">%Z"</span></code> strptime 格式(C 区域)。</p>
|
||
<p>以下为示例代码:</p>
|
||
<div class="highlight-pycon3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">import</span> <span class="nn">ssl</span>
|
||
<span class="gp">>>> </span><span class="n">timestamp</span> <span class="o">=</span> <span class="n">ssl</span><span class="o">.</span><span class="n">cert_time_to_seconds</span><span class="p">(</span><span class="s2">"Jan 5 09:34:43 2018 GMT"</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">timestamp</span>
|
||
<span class="go">1515144883</span>
|
||
<span class="gp">>>> </span><span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">datetime</span>
|
||
<span class="gp">>>> </span><span class="nb">print</span><span class="p">(</span><span class="n">datetime</span><span class="o">.</span><span class="n">utcfromtimestamp</span><span class="p">(</span><span class="n">timestamp</span><span class="p">))</span>
|
||
<span class="go">2018-01-05 09:34:43</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>"notBefore" 或 "notAfter" 日期值必须使用 GMT (<span class="target" id="index-59"></span><a class="rfc reference external" href="https://tools.ietf.org/html/rfc5280.html"><strong>RFC 5280</strong></a>)。</p>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.5 版更改: </span>将输入时间解读为 UTC 时间,基于输入字符串中指明的 'GMT' 时区。 在之前使用的是本地时区。 返回一个整数(不带输入格式中秒的分数部分)</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="ssl.get_server_certificate">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">get_server_certificate</code><span class="sig-paren">(</span><em class="sig-param">addr</em>, <em class="sig-param">ssl_version=PROTOCOL_TLS</em>, <em class="sig-param">ca_certs=None</em><span class="sig-paren">)</span><a class="headerlink" href="#ssl.get_server_certificate" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>带 SSL 保护的服务器的地址 <code class="docutils literal notranslate"><span class="pre">addr</span></code> 以 (<em>hostname</em>, <em>port-number</em>) 对的形式给出,获取服务器的证书,并将其以 PEM 编码字符串的形式返回。 如果指定了 <code class="docutils literal notranslate"><span class="pre">ssl_version</span></code>,则使用该版本的 SSL 协议尝试连接服务器。 如果指定了 <code class="docutils literal notranslate"><span class="pre">ca_certs</span></code>,它应当是一个包含根证书列表的文件,使用与 <a class="reference internal" href="#ssl.SSLContext.wrap_socket" title="ssl.SSLContext.wrap_socket"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLContext.wrap_socket()</span></code></a> 中同名形参一致的格式。 该调用将尝试根据指定的根证书集来验证服务器证书,如果验证失败则该调用也将失败。</p>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.3 版更改: </span>此函数现在是 IPv6 兼容的。-compatible.</p>
|
||
</div>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.5 版更改: </span>默认的 <em>ssl_version</em> 从 <a class="reference internal" href="#ssl.PROTOCOL_SSLv3" title="ssl.PROTOCOL_SSLv3"><code class="xref py py-data docutils literal notranslate"><span class="pre">PROTOCOL_SSLv3</span></code></a> 改为 <a class="reference internal" href="#ssl.PROTOCOL_TLS" title="ssl.PROTOCOL_TLS"><code class="xref py py-data docutils literal notranslate"><span class="pre">PROTOCOL_TLS</span></code></a> 以保证与现代服务器的最大兼容性。</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="ssl.DER_cert_to_PEM_cert">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">DER_cert_to_PEM_cert</code><span class="sig-paren">(</span><em class="sig-param">DER_cert_bytes</em><span class="sig-paren">)</span><a class="headerlink" href="#ssl.DER_cert_to_PEM_cert" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>根据给定的 DER 编码字节块形式的证书,返回同一证书的 PEM 编码字符串版本。</p>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="ssl.PEM_cert_to_DER_cert">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">PEM_cert_to_DER_cert</code><span class="sig-paren">(</span><em class="sig-param">PEM_cert_string</em><span class="sig-paren">)</span><a class="headerlink" href="#ssl.PEM_cert_to_DER_cert" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>根据给定的 ASCII PEM 字符串形式的证书,返回同一证书的 DER 编码字节序列。</p>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="ssl.get_default_verify_paths">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">get_default_verify_paths</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#ssl.get_default_verify_paths" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>返回包含 OpenSSL 的默认 cafile 和 capath 的路径的命名元组。 此路径与 <a class="reference internal" href="#ssl.SSLContext.set_default_verify_paths" title="ssl.SSLContext.set_default_verify_paths"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLContext.set_default_verify_paths()</span></code></a> 所使用的相同。 返回值是一个 <a class="reference internal" href="../glossary.html#term-named-tuple"><span class="xref std std-term">named tuple</span></a> <code class="docutils literal notranslate"><span class="pre">DefaultVerifyPaths</span></code>:</p>
|
||
<ul class="simple">
|
||
<li><p><code class="xref py py-attr docutils literal notranslate"><span class="pre">cafile</span></code> - 解析出的 cafile 路径或者如果文件不存在则为 <code class="docutils literal notranslate"><span class="pre">None</span></code>,</p></li>
|
||
<li><p><code class="xref py py-attr docutils literal notranslate"><span class="pre">capath</span></code> - 解析出的 capath 路径或者如果目录不存在则为 <code class="docutils literal notranslate"><span class="pre">None</span></code>,</p></li>
|
||
<li><p><code class="xref py py-attr docutils literal notranslate"><span class="pre">openssl_cafile_env</span></code> - 指向一个 cafile 的 OpenSSL 环境键,</p></li>
|
||
<li><p><code class="xref py py-attr docutils literal notranslate"><span class="pre">openssl_cafile</span></code> - 一个 cafile 的硬编码路径,</p></li>
|
||
<li><p><code class="xref py py-attr docutils literal notranslate"><span class="pre">openssl_capath_env</span></code> - 指向一个 capath 的 OpenSSL 环境键,</p></li>
|
||
<li><p><code class="xref py py-attr docutils literal notranslate"><span class="pre">openssl_capath</span></code> - 一个 capath 目录的硬编码路径</p></li>
|
||
</ul>
|
||
<p class="availability"><a class="reference internal" href="intro.html#availability"><span class="std std-ref">可用性</span></a>: LibreSSL 会忽略环境变量 <code class="xref py py-attr docutils literal notranslate"><span class="pre">openssl_cafile_env</span></code> 和 <code class="xref py py-attr docutils literal notranslate"><span class="pre">openssl_capath_env</span></code>。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.4 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="ssl.enum_certificates">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">enum_certificates</code><span class="sig-paren">(</span><em class="sig-param">store_name</em><span class="sig-paren">)</span><a class="headerlink" href="#ssl.enum_certificates" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>从 Windows 的系统证书库中检索证书。 <em>store_name</em> 可以是 <code class="docutils literal notranslate"><span class="pre">CA</span></code>, <code class="docutils literal notranslate"><span class="pre">ROOT</span></code> 或 <code class="docutils literal notranslate"><span class="pre">MY</span></code> 中的一个。 Windows 也可能会提供额外的证书库。</p>
|
||
<p>此函数返回一个包含 (cert_bytes, encoding_type, trust) 元组的列表。 encoding_type 指明 cert_bytes 的编码格式。 它可以为 <code class="xref py py-const docutils literal notranslate"><span class="pre">x509_asn</span></code> 以表示 X.509 ASN.1 数据或是 <code class="xref py py-const docutils literal notranslate"><span class="pre">pkcs_7_asn</span></code> 以表示 PKCS#7 ASN.1 数据。 trust 以 OIDS 集合的形式指明证书的目的,或者如果证书对于所有目的都可以信任则为 <code class="docutils literal notranslate"><span class="pre">True</span></code>。</p>
|
||
<p>示例:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">ssl</span><span class="o">.</span><span class="n">enum_certificates</span><span class="p">(</span><span class="s2">"CA"</span><span class="p">)</span>
|
||
<span class="go">[(b'data...', 'x509_asn', {'1.3.6.1.5.5.7.3.1', '1.3.6.1.5.5.7.3.2'}),</span>
|
||
<span class="go"> (b'data...', 'x509_asn', True)]</span>
|
||
</pre></div>
|
||
</div>
|
||
<p class="availability"><a class="reference internal" href="intro.html#availability"><span class="std std-ref">可用性</span></a>: Windows。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.4 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="ssl.enum_crls">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">enum_crls</code><span class="sig-paren">(</span><em class="sig-param">store_name</em><span class="sig-paren">)</span><a class="headerlink" href="#ssl.enum_crls" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>Windows 的系统证书库中检索 CRL。 <em>store_name</em> 可以是 <code class="docutils literal notranslate"><span class="pre">CA</span></code>, <code class="docutils literal notranslate"><span class="pre">ROOT</span></code> 或 <code class="docutils literal notranslate"><span class="pre">MY</span></code> 中的一个。 Windows 也可能会提供额外的证书库。</p>
|
||
<p>此函数返回一个包含 (cert_bytes, encoding_type, trust) 元组的列表。 encoding_type 指明 cert_bytes 的编码格式。 它可以为 <code class="xref py py-const docutils literal notranslate"><span class="pre">x509_asn</span></code> 以表示 X.509 ASN.1 数据或是 <code class="xref py py-const docutils literal notranslate"><span class="pre">pkcs_7_asn</span></code> 以表示 PKCS#7 ASN.1 数据。</p>
|
||
<p class="availability"><a class="reference internal" href="intro.html#availability"><span class="std std-ref">可用性</span></a>: Windows。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.4 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="ssl.wrap_socket">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">wrap_socket</code><span class="sig-paren">(</span><em class="sig-param">sock</em>, <em class="sig-param">keyfile=None</em>, <em class="sig-param">certfile=None</em>, <em class="sig-param">server_side=False</em>, <em class="sig-param">cert_reqs=CERT_NONE</em>, <em class="sig-param">ssl_version=PROTOCOL_TLS</em>, <em class="sig-param">ca_certs=None</em>, <em class="sig-param">do_handshake_on_connect=True</em>, <em class="sig-param">suppress_ragged_eofs=True</em>, <em class="sig-param">ciphers=None</em><span class="sig-paren">)</span><a class="headerlink" href="#ssl.wrap_socket" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>接受一个 <a class="reference internal" href="socket.html#socket.socket" title="socket.socket"><code class="xref py py-class docutils literal notranslate"><span class="pre">socket.socket</span></code></a> 的实例 <code class="docutils literal notranslate"><span class="pre">sock</span></code>,并返回一个 <a class="reference internal" href="#ssl.SSLSocket" title="ssl.SSLSocket"><code class="xref py py-class docutils literal notranslate"><span class="pre">ssl.SSLSocket</span></code></a> 的实例,该类型是 <a class="reference internal" href="socket.html#socket.socket" title="socket.socket"><code class="xref py py-class docutils literal notranslate"><span class="pre">socket.socket</span></code></a> 的子类型,它将下层的套接字包装在一个 SSL 上下文中。 <code class="docutils literal notranslate"><span class="pre">sock</span></code> 必须是一个 <a class="reference internal" href="socket.html#socket.SOCK_STREAM" title="socket.SOCK_STREAM"><code class="xref py py-data docutils literal notranslate"><span class="pre">SOCK_STREAM</span></code></a> 套接字;其他套接字类型不被支持。</p>
|
||
<p>在内部,该函数会创建一个 <a class="reference internal" href="#ssl.SSLContext" title="ssl.SSLContext"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLContext</span></code></a>,其协议版本为 <em>ssl_version</em> 且 <a class="reference internal" href="#ssl.SSLContext.options" title="ssl.SSLContext.options"><code class="xref py py-attr docutils literal notranslate"><span class="pre">SSLContext.options</span></code></a> 设为 <em>cert_reqs</em>。 如果设置了 <em>keyfile</em>, <em>certfile</em>, <em>ca_certs</em> 或 <em>ciphers</em> 等形参,则参数值会被传给 <a class="reference internal" href="#ssl.SSLContext.load_cert_chain" title="ssl.SSLContext.load_cert_chain"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLContext.load_cert_chain()</span></code></a>, <a class="reference internal" href="#ssl.SSLContext.load_verify_locations" title="ssl.SSLContext.load_verify_locations"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLContext.load_verify_locations()</span></code></a> 以及 <a class="reference internal" href="#ssl.SSLContext.set_ciphers" title="ssl.SSLContext.set_ciphers"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLContext.set_ciphers()</span></code></a>。</p>
|
||
<p>参数 <em>server_side</em>, <em>do_handshake_on_connect</em> 和 <em>suppress_ragged_eofs</em> 具有与 <a class="reference internal" href="#ssl.SSLContext.wrap_socket" title="ssl.SSLContext.wrap_socket"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLContext.wrap_socket()</span></code></a> 相同的含义。</p>
|
||
<div class="deprecated">
|
||
<p><span class="versionmodified deprecated">3.7 版后已移除: </span>从 Python 3.2 和 2.7.9 开始,建议使用 <a class="reference internal" href="#ssl.SSLContext.wrap_socket" title="ssl.SSLContext.wrap_socket"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLContext.wrap_socket()</span></code></a> 来代替 <a class="reference internal" href="#ssl.wrap_socket" title="ssl.wrap_socket"><code class="xref py py-func docutils literal notranslate"><span class="pre">wrap_socket()</span></code></a>。 模块级函数的功能受限并且将创建不安全的客户端套接字,不带服务器名称提示或主机名匹配。</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
</section>
|
||
<section id="constants">
|
||
<h3>常量<a class="headerlink" href="#constants" title="永久链接至标题">¶</a></h3>
|
||
<blockquote>
|
||
<div><p>所有常量现在都是 <a class="reference internal" href="enum.html#enum.IntEnum" title="enum.IntEnum"><code class="xref py py-class docutils literal notranslate"><span class="pre">enum.IntEnum</span></code></a> 或 <a class="reference internal" href="enum.html#enum.IntFlag" title="enum.IntFlag"><code class="xref py py-class docutils literal notranslate"><span class="pre">enum.IntFlag</span></code></a> 多项集的成员。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.6 新版功能.</span></p>
|
||
</div>
|
||
</div></blockquote>
|
||
<dl class="data">
|
||
<dt id="ssl.CERT_NONE">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">CERT_NONE</code><a class="headerlink" href="#ssl.CERT_NONE" title="永久链接至目标">¶</a></dt>
|
||
<dd><p><a class="reference internal" href="#ssl.SSLContext.verify_mode" title="ssl.SSLContext.verify_mode"><code class="xref py py-attr docutils literal notranslate"><span class="pre">SSLContext.verify_mode</span></code></a> 或 <a class="reference internal" href="#ssl.wrap_socket" title="ssl.wrap_socket"><code class="xref py py-func docutils literal notranslate"><span class="pre">wrap_socket()</span></code></a> 的 <code class="docutils literal notranslate"><span class="pre">cert_reqs</span></code> 形参可能的取值。 <a class="reference internal" href="#ssl.PROTOCOL_TLS_CLIENT" title="ssl.PROTOCOL_TLS_CLIENT"><code class="xref py py-const docutils literal notranslate"><span class="pre">PROTOCOL_TLS_CLIENT</span></code></a> 除外,这是默认的模式。 对于客户端套接字,几乎任何证书都是可接受的。 验证错误例如不受信任或过期的证书错误会被忽略并且不会中止 TLS/SSL 握手。</p>
|
||
<p>在服务器模式下,不会从客户端请求任何证书,因此客户端不会发送任何用于客户端证书身份验证的证书。</p>
|
||
<p>参见下文对于 <a class="reference internal" href="#ssl-security"><span class="std std-ref">安全考量</span></a> 的讨论。</p>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.CERT_OPTIONAL">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">CERT_OPTIONAL</code><a class="headerlink" href="#ssl.CERT_OPTIONAL" title="永久链接至目标">¶</a></dt>
|
||
<dd><p><a class="reference internal" href="#ssl.SSLContext.verify_mode" title="ssl.SSLContext.verify_mode"><code class="xref py py-attr docutils literal notranslate"><span class="pre">SSLContext.verify_mode</span></code></a> 或 <a class="reference internal" href="#ssl.wrap_socket" title="ssl.wrap_socket"><code class="xref py py-func docutils literal notranslate"><span class="pre">wrap_socket()</span></code></a> 的 <code class="docutils literal notranslate"><span class="pre">cert_reqs</span></code> 形参可能的取值。 <a class="reference internal" href="#ssl.CERT_OPTIONAL" title="ssl.CERT_OPTIONAL"><code class="xref py py-const docutils literal notranslate"><span class="pre">CERT_OPTIONAL</span></code></a> 具有与 <a class="reference internal" href="#ssl.CERT_REQUIRED" title="ssl.CERT_REQUIRED"><code class="xref py py-const docutils literal notranslate"><span class="pre">CERT_REQUIRED</span></code></a> 相同的含义。 对于客户端套接字推荐改用 <a class="reference internal" href="#ssl.CERT_REQUIRED" title="ssl.CERT_REQUIRED"><code class="xref py py-const docutils literal notranslate"><span class="pre">CERT_REQUIRED</span></code></a>。</p>
|
||
<p>在服务器模式下,客户端证书请求会被发送给客户端。 客户端可以忽略请求也可以发送一个证书以执行 TLS 客户端证书身份验证。 如果客户端选择发送证书,则将对其执行验证。 任何验证错误都将立即中止 TLS 握手。</p>
|
||
<p>使用此设置要求将一组有效的 CA 证书传递给 <a class="reference internal" href="#ssl.SSLContext.load_verify_locations" title="ssl.SSLContext.load_verify_locations"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLContext.load_verify_locations()</span></code></a> 或是作为 <a class="reference internal" href="#ssl.wrap_socket" title="ssl.wrap_socket"><code class="xref py py-func docutils literal notranslate"><span class="pre">wrap_socket()</span></code></a> 的 <code class="docutils literal notranslate"><span class="pre">ca_certs</span></code> 形参值。</p>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.CERT_REQUIRED">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">CERT_REQUIRED</code><a class="headerlink" href="#ssl.CERT_REQUIRED" title="永久链接至目标">¶</a></dt>
|
||
<dd><p><a class="reference internal" href="#ssl.SSLContext.verify_mode" title="ssl.SSLContext.verify_mode"><code class="xref py py-attr docutils literal notranslate"><span class="pre">SSLContext.verify_mode</span></code></a> 或 <a class="reference internal" href="#ssl.wrap_socket" title="ssl.wrap_socket"><code class="xref py py-func docutils literal notranslate"><span class="pre">wrap_socket()</span></code></a> 的 <code class="docutils literal notranslate"><span class="pre">cert_reqs</span></code> 形参可能的取值。 在此模式下,需要从套接字连接的另一端获取证书;如果未提供证书或验证失败则将引发 <a class="reference internal" href="#ssl.SSLError" title="ssl.SSLError"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLError</span></code></a>。 此模式 <strong>不能</strong> 在客户端模式下对证书进行验证,因为它不会匹配主机名。 <a class="reference internal" href="#ssl.SSLContext.check_hostname" title="ssl.SSLContext.check_hostname"><code class="xref py py-attr docutils literal notranslate"><span class="pre">check_hostname</span></code></a> 也必须被启用以验证证书的真实性。 <a class="reference internal" href="#ssl.PROTOCOL_TLS_CLIENT" title="ssl.PROTOCOL_TLS_CLIENT"><code class="xref py py-const docutils literal notranslate"><span class="pre">PROTOCOL_TLS_CLIENT</span></code></a> 会使用 <a class="reference internal" href="#ssl.CERT_REQUIRED" title="ssl.CERT_REQUIRED"><code class="xref py py-const docutils literal notranslate"><span class="pre">CERT_REQUIRED</span></code></a> 并默认启用 <a class="reference internal" href="#ssl.SSLContext.check_hostname" title="ssl.SSLContext.check_hostname"><code class="xref py py-attr docutils literal notranslate"><span class="pre">check_hostname</span></code></a>。</p>
|
||
<p>对于服务器套接字,此模式会提供强制性的 TLS 客户端证书验证。 客户端证书请求会被发送给客户端并且客户端必须提供有效且受信任的证书。</p>
|
||
<p>使用此设置要求将一组有效的 CA 证书传递给 <a class="reference internal" href="#ssl.SSLContext.load_verify_locations" title="ssl.SSLContext.load_verify_locations"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLContext.load_verify_locations()</span></code></a> 或是作为 <a class="reference internal" href="#ssl.wrap_socket" title="ssl.wrap_socket"><code class="xref py py-func docutils literal notranslate"><span class="pre">wrap_socket()</span></code></a> 的 <code class="docutils literal notranslate"><span class="pre">ca_certs</span></code> 形参值。</p>
|
||
</dd></dl>
|
||
|
||
<dl class="class">
|
||
<dt id="ssl.VerifyMode">
|
||
<em class="property">class </em><code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">VerifyMode</code><a class="headerlink" href="#ssl.VerifyMode" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>CERT_* 常量的 <a class="reference internal" href="enum.html#enum.IntEnum" title="enum.IntEnum"><code class="xref py py-class docutils literal notranslate"><span class="pre">enum.IntEnum</span></code></a> 多项集。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.6 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.VERIFY_DEFAULT">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">VERIFY_DEFAULT</code><a class="headerlink" href="#ssl.VERIFY_DEFAULT" title="永久链接至目标">¶</a></dt>
|
||
<dd><p><a class="reference internal" href="#ssl.SSLContext.verify_flags" title="ssl.SSLContext.verify_flags"><code class="xref py py-attr docutils literal notranslate"><span class="pre">SSLContext.verify_flags</span></code></a> 可能的取值。 在此模式下,证书吊销列表(CRL)并不会被检查。 OpenSSL 默认不要求也不验证 CRL。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.4 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.VERIFY_CRL_CHECK_LEAF">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">VERIFY_CRL_CHECK_LEAF</code><a class="headerlink" href="#ssl.VERIFY_CRL_CHECK_LEAF" title="永久链接至目标">¶</a></dt>
|
||
<dd><p><a class="reference internal" href="#ssl.SSLContext.verify_flags" title="ssl.SSLContext.verify_flags"><code class="xref py py-attr docutils literal notranslate"><span class="pre">SSLContext.verify_flags</span></code></a> 可能的取值。 在此模式下, 只会检查对等证书而不检查任何中间 CA 证书。 此模式要求提供由对等证书颁发者(其直接上级 CA)签名的有效 CRL。 如果未使用 <a class="reference internal" href="#ssl.SSLContext.load_verify_locations" title="ssl.SSLContext.load_verify_locations"><code class="xref py py-attr docutils literal notranslate"><span class="pre">SSLContext.load_verify_locations</span></code></a> 加载正确的 CRL,则验证将失败。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.4 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.VERIFY_CRL_CHECK_CHAIN">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">VERIFY_CRL_CHECK_CHAIN</code><a class="headerlink" href="#ssl.VERIFY_CRL_CHECK_CHAIN" title="永久链接至目标">¶</a></dt>
|
||
<dd><p><a class="reference internal" href="#ssl.SSLContext.verify_flags" title="ssl.SSLContext.verify_flags"><code class="xref py py-attr docutils literal notranslate"><span class="pre">SSLContext.verify_flags</span></code></a> 可能的取值。 在此模式下,会检查对等证书链中所有证书的 CRL。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.4 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.VERIFY_X509_STRICT">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">VERIFY_X509_STRICT</code><a class="headerlink" href="#ssl.VERIFY_X509_STRICT" title="永久链接至目标">¶</a></dt>
|
||
<dd><p><a class="reference internal" href="#ssl.SSLContext.verify_flags" title="ssl.SSLContext.verify_flags"><code class="xref py py-attr docutils literal notranslate"><span class="pre">SSLContext.verify_flags</span></code></a> 可能的取值,用于禁用已损坏 X.509 证书的绕过操作。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.4 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.VERIFY_X509_TRUSTED_FIRST">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">VERIFY_X509_TRUSTED_FIRST</code><a class="headerlink" href="#ssl.VERIFY_X509_TRUSTED_FIRST" title="永久链接至目标">¶</a></dt>
|
||
<dd><p><a class="reference internal" href="#ssl.SSLContext.verify_flags" title="ssl.SSLContext.verify_flags"><code class="xref py py-attr docutils literal notranslate"><span class="pre">SSLContext.verify_flags</span></code></a> 可能的取值。 它指示 OpenSSL 在构建用于验证某个证书的信任链时首选受信任的证书。 此旗标将默认被启用。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.4.4 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="class">
|
||
<dt id="ssl.VerifyFlags">
|
||
<em class="property">class </em><code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">VerifyFlags</code><a class="headerlink" href="#ssl.VerifyFlags" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>VERIFY_* 常量的 <a class="reference internal" href="enum.html#enum.IntFlag" title="enum.IntFlag"><code class="xref py py-class docutils literal notranslate"><span class="pre">enum.IntFlag</span></code></a> 多项集。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.6 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.PROTOCOL_TLS">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">PROTOCOL_TLS</code><a class="headerlink" href="#ssl.PROTOCOL_TLS" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>选择客户端和服务器均支持的最高协议版本。 此选项名称并不准确,实际上 "SSL" 和 "TLS" 协议均可被选择。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.6 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.PROTOCOL_TLS_CLIENT">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">PROTOCOL_TLS_CLIENT</code><a class="headerlink" href="#ssl.PROTOCOL_TLS_CLIENT" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>像 <a class="reference internal" href="#ssl.PROTOCOL_TLS" title="ssl.PROTOCOL_TLS"><code class="xref py py-data docutils literal notranslate"><span class="pre">PROTOCOL_TLS</span></code></a> 一样地自动协商最高协议版本,但是只支持客户端 <a class="reference internal" href="#ssl.SSLSocket" title="ssl.SSLSocket"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLSocket</span></code></a> 连接。 此协议默认会启用 <a class="reference internal" href="#ssl.CERT_REQUIRED" title="ssl.CERT_REQUIRED"><code class="xref py py-data docutils literal notranslate"><span class="pre">CERT_REQUIRED</span></code></a> 和 <a class="reference internal" href="#ssl.SSLContext.check_hostname" title="ssl.SSLContext.check_hostname"><code class="xref py py-attr docutils literal notranslate"><span class="pre">check_hostname</span></code></a>。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.6 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.PROTOCOL_TLS_SERVER">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">PROTOCOL_TLS_SERVER</code><a class="headerlink" href="#ssl.PROTOCOL_TLS_SERVER" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>像 <a class="reference internal" href="#ssl.PROTOCOL_TLS" title="ssl.PROTOCOL_TLS"><code class="xref py py-data docutils literal notranslate"><span class="pre">PROTOCOL_TLS</span></code></a> 一样地自动协商最高协议版本,但是只支持服务器 <a class="reference internal" href="#ssl.SSLSocket" title="ssl.SSLSocket"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLSocket</span></code></a> 连接。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.6 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.PROTOCOL_SSLv23">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">PROTOCOL_SSLv23</code><a class="headerlink" href="#ssl.PROTOCOL_SSLv23" title="永久链接至目标">¶</a></dt>
|
||
<dd><p><a class="reference internal" href="#ssl.PROTOCOL_TLS" title="ssl.PROTOCOL_TLS"><code class="xref py py-data docutils literal notranslate"><span class="pre">PROTOCOL_TLS</span></code></a> 的别名。</p>
|
||
<div class="deprecated">
|
||
<p><span class="versionmodified deprecated">3.6 版后已移除: </span>请改用 <a class="reference internal" href="#ssl.PROTOCOL_TLS" title="ssl.PROTOCOL_TLS"><code class="xref py py-data docutils literal notranslate"><span class="pre">PROTOCOL_TLS</span></code></a>。</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.PROTOCOL_SSLv2">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">PROTOCOL_SSLv2</code><a class="headerlink" href="#ssl.PROTOCOL_SSLv2" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>选择 SSL 版本 2 作为通道加密协议。</p>
|
||
<p>如果 OpenSSL 编译时使用了 <code class="docutils literal notranslate"><span class="pre">OPENSSL_NO_SSL2</span></code> 旗标则此协议将不可用。</p>
|
||
<div class="admonition warning">
|
||
<p class="admonition-title">警告</p>
|
||
<p>SSL 版本 2 并不安全。 极不建议使用它。</p>
|
||
</div>
|
||
<div class="deprecated">
|
||
<p><span class="versionmodified deprecated">3.6 版后已移除: </span>OpenSSL 已经移除了对 SSLv2 的支持。</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.PROTOCOL_SSLv3">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">PROTOCOL_SSLv3</code><a class="headerlink" href="#ssl.PROTOCOL_SSLv3" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>选择 SSL 版本 3 作为通道加密协议。</p>
|
||
<p>如果 OpenSSL 编译时使用了 <code class="docutils literal notranslate"><span class="pre">OPENSSL_NO_SSLv3</span></code> 旗标则此协议将不可用。</p>
|
||
<div class="admonition warning">
|
||
<p class="admonition-title">警告</p>
|
||
<p>SSL 版本 3 并不安全。 极不建议使用它。</p>
|
||
</div>
|
||
<div class="deprecated">
|
||
<p><span class="versionmodified deprecated">3.6 版后已移除: </span>OpenSSL 已经弃用了所有带有特定版本号的协议。 请改用默认协议 <a class="reference internal" href="#ssl.PROTOCOL_TLS" title="ssl.PROTOCOL_TLS"><code class="xref py py-data docutils literal notranslate"><span class="pre">PROTOCOL_TLS</span></code></a> 并附带 <a class="reference internal" href="#ssl.OP_NO_SSLv3" title="ssl.OP_NO_SSLv3"><code class="xref py py-data docutils literal notranslate"><span class="pre">OP_NO_SSLv3</span></code></a> 等旗标。</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.PROTOCOL_TLSv1">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">PROTOCOL_TLSv1</code><a class="headerlink" href="#ssl.PROTOCOL_TLSv1" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>选择 TLS 版本 1.0 作为通道加密协议。</p>
|
||
<div class="deprecated">
|
||
<p><span class="versionmodified deprecated">3.6 版后已移除: </span>OpenSSL 已经弃用了所有带有特定版本号的协议。 请改用默认协议 <a class="reference internal" href="#ssl.PROTOCOL_TLS" title="ssl.PROTOCOL_TLS"><code class="xref py py-data docutils literal notranslate"><span class="pre">PROTOCOL_TLS</span></code></a> 并附带 <a class="reference internal" href="#ssl.OP_NO_SSLv3" title="ssl.OP_NO_SSLv3"><code class="xref py py-data docutils literal notranslate"><span class="pre">OP_NO_SSLv3</span></code></a> 等旗标。</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.PROTOCOL_TLSv1_1">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">PROTOCOL_TLSv1_1</code><a class="headerlink" href="#ssl.PROTOCOL_TLSv1_1" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>选择 TLS 版本 1.1 作为通道加密协议。 仅适用于 openssl 版本 1.0.1+。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.4 新版功能.</span></p>
|
||
</div>
|
||
<div class="deprecated">
|
||
<p><span class="versionmodified deprecated">3.6 版后已移除: </span>OpenSSL 已经弃用了所有带有特定版本号的协议。 请改用默认协议 <a class="reference internal" href="#ssl.PROTOCOL_TLS" title="ssl.PROTOCOL_TLS"><code class="xref py py-data docutils literal notranslate"><span class="pre">PROTOCOL_TLS</span></code></a> 并附带 <a class="reference internal" href="#ssl.OP_NO_SSLv3" title="ssl.OP_NO_SSLv3"><code class="xref py py-data docutils literal notranslate"><span class="pre">OP_NO_SSLv3</span></code></a> 等旗标。</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.PROTOCOL_TLSv1_2">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">PROTOCOL_TLSv1_2</code><a class="headerlink" href="#ssl.PROTOCOL_TLSv1_2" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>选译 TLS 版本 1.2 作为通道加密协议。 这是最新的版本,也应是能提供最大保护的最佳选择,如果通信双方都支持它的话。 仅适用于 openssl 版本 1.0.1+。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.4 新版功能.</span></p>
|
||
</div>
|
||
<div class="deprecated">
|
||
<p><span class="versionmodified deprecated">3.6 版后已移除: </span>OpenSSL 已经弃用了所有带有特定版本号的协议。 请改用默认协议 <a class="reference internal" href="#ssl.PROTOCOL_TLS" title="ssl.PROTOCOL_TLS"><code class="xref py py-data docutils literal notranslate"><span class="pre">PROTOCOL_TLS</span></code></a> 并附带 <a class="reference internal" href="#ssl.OP_NO_SSLv3" title="ssl.OP_NO_SSLv3"><code class="xref py py-data docutils literal notranslate"><span class="pre">OP_NO_SSLv3</span></code></a> 等旗标。</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.OP_ALL">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">OP_ALL</code><a class="headerlink" href="#ssl.OP_ALL" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>对存在于其他 SSL 实现中的各种缺陷启用绕过操作。 默认会设置此选项。 没有必要设置与 OpenSSL 的 <code class="docutils literal notranslate"><span class="pre">SSL_OP_ALL</span></code> 常量同名的旗标。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.2 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.OP_NO_SSLv2">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">OP_NO_SSLv2</code><a class="headerlink" href="#ssl.OP_NO_SSLv2" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>阻止 SSLv2 连接。 此选项仅可与 <a class="reference internal" href="#ssl.PROTOCOL_TLS" title="ssl.PROTOCOL_TLS"><code class="xref py py-const docutils literal notranslate"><span class="pre">PROTOCOL_TLS</span></code></a> 结合使用。 它会阻止对等方选择 SSLv2 作为协议版本。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.2 新版功能.</span></p>
|
||
</div>
|
||
<div class="deprecated">
|
||
<p><span class="versionmodified deprecated">3.6 版后已移除: </span>SSLv2 已被弃用</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.OP_NO_SSLv3">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">OP_NO_SSLv3</code><a class="headerlink" href="#ssl.OP_NO_SSLv3" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>阻止 SSLv3 连接。 此选项仅可与 <a class="reference internal" href="#ssl.PROTOCOL_TLS" title="ssl.PROTOCOL_TLS"><code class="xref py py-const docutils literal notranslate"><span class="pre">PROTOCOL_TLS</span></code></a> 结合使用。 它会阻止对等方选择 SSLv3 作为协议版本。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.2 新版功能.</span></p>
|
||
</div>
|
||
<div class="deprecated">
|
||
<p><span class="versionmodified deprecated">3.6 版后已移除: </span>SSLv3 已被弃用</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.OP_NO_TLSv1">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">OP_NO_TLSv1</code><a class="headerlink" href="#ssl.OP_NO_TLSv1" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>阻止 TLSv1 连接。 此选项仅可与 <a class="reference internal" href="#ssl.PROTOCOL_TLS" title="ssl.PROTOCOL_TLS"><code class="xref py py-const docutils literal notranslate"><span class="pre">PROTOCOL_TLS</span></code></a> 结合使用。 它会阻止对等方选择 TLSv1 作为协议版本。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.2 新版功能.</span></p>
|
||
</div>
|
||
<div class="deprecated">
|
||
<p><span class="versionmodified deprecated">3.7 版后已移除: </span>此选项自 OpenSSL 1.1.0 起已被弃用,请改用新的 <a class="reference internal" href="#ssl.SSLContext.minimum_version" title="ssl.SSLContext.minimum_version"><code class="xref py py-attr docutils literal notranslate"><span class="pre">SSLContext.minimum_version</span></code></a> 和 <a class="reference internal" href="#ssl.SSLContext.maximum_version" title="ssl.SSLContext.maximum_version"><code class="xref py py-attr docutils literal notranslate"><span class="pre">SSLContext.maximum_version</span></code></a>。</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.OP_NO_TLSv1_1">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">OP_NO_TLSv1_1</code><a class="headerlink" href="#ssl.OP_NO_TLSv1_1" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>阻止 TLSv1.1 连接。 此选项仅可与 <a class="reference internal" href="#ssl.PROTOCOL_TLS" title="ssl.PROTOCOL_TLS"><code class="xref py py-const docutils literal notranslate"><span class="pre">PROTOCOL_TLS</span></code></a> 结合使用。 它会阻止对等方选择 TLSv1.1 作为协议版本。 仅适用于 openssl 版本 1.0.1+。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.4 新版功能.</span></p>
|
||
</div>
|
||
<div class="deprecated">
|
||
<p><span class="versionmodified deprecated">3.7 版后已移除: </span>此选项自 OpenSSL 1.1.0 起已被弃用。</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.OP_NO_TLSv1_2">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">OP_NO_TLSv1_2</code><a class="headerlink" href="#ssl.OP_NO_TLSv1_2" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>阻止 TLSv1.2 连接。 此选项仅可与 <a class="reference internal" href="#ssl.PROTOCOL_TLS" title="ssl.PROTOCOL_TLS"><code class="xref py py-const docutils literal notranslate"><span class="pre">PROTOCOL_TLS</span></code></a> 结合使用。 它会阻止对等方选择 TLSv1.2 作为协议版本。 仅适用于 openssl 版本 1.0.1+。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.4 新版功能.</span></p>
|
||
</div>
|
||
<div class="deprecated">
|
||
<p><span class="versionmodified deprecated">3.7 版后已移除: </span>此选项自 OpenSSL 1.1.0 起已被弃用。</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.OP_NO_TLSv1_3">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">OP_NO_TLSv1_3</code><a class="headerlink" href="#ssl.OP_NO_TLSv1_3" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>阻止 TLSv1.3 连接。 此选项仅可与 <a class="reference internal" href="#ssl.PROTOCOL_TLS" title="ssl.PROTOCOL_TLS"><code class="xref py py-const docutils literal notranslate"><span class="pre">PROTOCOL_TLS</span></code></a> 结合使用。 它会阻止对等方选择 TLSv1.3 作为协议版本。 TLS 1.3 适用于 OpenSSL 1.1.1 或更新的版本。 当 Python 编译是基于较旧版本的 OpenSSL 时,该旗标默认为 <em>0</em>。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.7 新版功能.</span></p>
|
||
</div>
|
||
<div class="deprecated">
|
||
<p><span class="versionmodified deprecated">3.7 版后已移除: </span>此选项自 OpenSSL 1.1.0 起已被弃用。 它被添加到 2.7.15, 3.6.3 和 3.7.0 是为了向下兼容 OpenSSL 1.0.2。</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.OP_NO_RENEGOTIATION">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">OP_NO_RENEGOTIATION</code><a class="headerlink" href="#ssl.OP_NO_RENEGOTIATION" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>禁用所有 TLSv1.2 和更早版本的重协商操作。 不发送 HelloRequest 消息,并忽略通过 ClientHello 发起的重协商请求。</p>
|
||
<p>此选项仅适用于 OpenSSL 1.1.0h 及更新的版本。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.7 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.OP_CIPHER_SERVER_PREFERENCE">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">OP_CIPHER_SERVER_PREFERENCE</code><a class="headerlink" href="#ssl.OP_CIPHER_SERVER_PREFERENCE" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>使用服务器的密码顺序首选项,而不是客户端的首选项。 此选项在客户端套接字和 SSLv2 服务器套接字上无效。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.3 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.OP_SINGLE_DH_USE">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">OP_SINGLE_DH_USE</code><a class="headerlink" href="#ssl.OP_SINGLE_DH_USE" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>阻止对于单独的 SSL 会话重用相同的 DH 密钥。 这会提升前向保密性但需要更多的计算资源。 此选项仅适用于服务器套接字。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.3 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.OP_SINGLE_ECDH_USE">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">OP_SINGLE_ECDH_USE</code><a class="headerlink" href="#ssl.OP_SINGLE_ECDH_USE" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>阻止对于单独的 SSL 会话重用相同的 ECDH 密钥。 这会提升前向保密性但需要更多的计算资源。 此选项仅适用于服务器套接字。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.3 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.OP_ENABLE_MIDDLEBOX_COMPAT">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">OP_ENABLE_MIDDLEBOX_COMPAT</code><a class="headerlink" href="#ssl.OP_ENABLE_MIDDLEBOX_COMPAT" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>在 TLS 1.3 握手中发送虚拟更改密码规格(CCS)消息以使得 TLS 1.3 连接看起来更像是 TLS 1.2 连接。</p>
|
||
<p>此选项仅适用于 OpenSSL 1.1.1 及更新的版本。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.8 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.OP_NO_COMPRESSION">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">OP_NO_COMPRESSION</code><a class="headerlink" href="#ssl.OP_NO_COMPRESSION" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>在 SSL 通道上禁用压缩。 这适用于应用协议支持自己的压缩方案的情况。</p>
|
||
<p>此选项仅适用于 OpenSSL 1.0.0 及更新的版本。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.3 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="class">
|
||
<dt id="ssl.Options">
|
||
<em class="property">class </em><code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">Options</code><a class="headerlink" href="#ssl.Options" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>OP_* 常量的 <a class="reference internal" href="enum.html#enum.IntFlag" title="enum.IntFlag"><code class="xref py py-class docutils literal notranslate"><span class="pre">enum.IntFlag</span></code></a> 多项集。</p>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.OP_NO_TICKET">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">OP_NO_TICKET</code><a class="headerlink" href="#ssl.OP_NO_TICKET" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>阻止客户端请求会话凭据。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.6 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.OP_IGNORE_UNEXPECTED_EOF">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">OP_IGNORE_UNEXPECTED_EOF</code><a class="headerlink" href="#ssl.OP_IGNORE_UNEXPECTED_EOF" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>忽略 TLS 连接的意外关闭。</p>
|
||
<p>此选项仅适用于 OpenSSL 3.0.0 及更新的版本。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.10 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.HAS_ALPN">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">HAS_ALPN</code><a class="headerlink" href="#ssl.HAS_ALPN" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>OpenSSL 库是否具有对 <span class="target" id="index-60"></span><a class="rfc reference external" href="https://tools.ietf.org/html/rfc7301.html"><strong>RFC 7301</strong></a> 中描述的 <em>应用层协议协商</em> TLS 扩展的内置支持。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.5 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.HAS_NEVER_CHECK_COMMON_NAME">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">HAS_NEVER_CHECK_COMMON_NAME</code><a class="headerlink" href="#ssl.HAS_NEVER_CHECK_COMMON_NAME" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>OpenSSL 库是否具有对不检测目标通用名称的内置支持且 <a class="reference internal" href="#ssl.SSLContext.hostname_checks_common_name" title="ssl.SSLContext.hostname_checks_common_name"><code class="xref py py-attr docutils literal notranslate"><span class="pre">SSLContext.hostname_checks_common_name</span></code></a> 为可写状态。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.7 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.HAS_ECDH">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">HAS_ECDH</code><a class="headerlink" href="#ssl.HAS_ECDH" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>OpenSSL 库是否具有对基于椭圆曲线的 Diffie-Hellman 密钥交换的内置支持。 此常量应当为真值,除非发布者明确地禁用了此功能。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.3 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.HAS_SNI">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">HAS_SNI</code><a class="headerlink" href="#ssl.HAS_SNI" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>OpenSSL 库是否具有对 <em>服务器名称提示</em> 扩展(在 <span class="target" id="index-61"></span><a class="rfc reference external" href="https://tools.ietf.org/html/rfc6066.html"><strong>RFC 6066</strong></a> 中定义)的内置支持。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.2 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.HAS_NPN">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">HAS_NPN</code><a class="headerlink" href="#ssl.HAS_NPN" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>OpenSSL 库是否具有对 <a class="reference external" href="https://en.wikipedia.org/wiki/Application-Layer_Protocol_Negotiation">应用层协议协商</a> 中描述的 <em>下一协议协商</em> 的内置支持。 当此常量为真值时,你可以使用 <a class="reference internal" href="#ssl.SSLContext.set_npn_protocols" title="ssl.SSLContext.set_npn_protocols"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLContext.set_npn_protocols()</span></code></a> 方法来公告你想要支持的协议。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.3 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.HAS_SSLv2">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">HAS_SSLv2</code><a class="headerlink" href="#ssl.HAS_SSLv2" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>OpenSSL 库是否具有对 SSL 2.0 协议的内置支持。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.7 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.HAS_SSLv3">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">HAS_SSLv3</code><a class="headerlink" href="#ssl.HAS_SSLv3" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>OpenSSL 库是否具有对 SSL 3.0 协议的内置支持。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.7 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.HAS_TLSv1">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">HAS_TLSv1</code><a class="headerlink" href="#ssl.HAS_TLSv1" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>OpenSSL 库是否具有对 TLS 1.0 协议的内置支持。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.7 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.HAS_TLSv1_1">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">HAS_TLSv1_1</code><a class="headerlink" href="#ssl.HAS_TLSv1_1" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>OpenSSL 库是否具有对 TLS 1.1 协议的内置支持。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.7 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.HAS_TLSv1_2">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">HAS_TLSv1_2</code><a class="headerlink" href="#ssl.HAS_TLSv1_2" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>OpenSSL 库是否具有对 TLS 1.2 协议的内置支持。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.7 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.HAS_TLSv1_3">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">HAS_TLSv1_3</code><a class="headerlink" href="#ssl.HAS_TLSv1_3" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>OpenSSL 库是否具有对 TLS 1.3 协议的内置支持。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.7 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.CHANNEL_BINDING_TYPES">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">CHANNEL_BINDING_TYPES</code><a class="headerlink" href="#ssl.CHANNEL_BINDING_TYPES" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>受支持的 TLS 通道绑定类型组成的列表。 此列表中的字符串可被用作传给 <a class="reference internal" href="#ssl.SSLSocket.get_channel_binding" title="ssl.SSLSocket.get_channel_binding"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLSocket.get_channel_binding()</span></code></a> 的参数。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.3 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.OPENSSL_VERSION">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">OPENSSL_VERSION</code><a class="headerlink" href="#ssl.OPENSSL_VERSION" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>解释器所加载的 OpenSSL 库的版本字符串:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">ssl</span><span class="o">.</span><span class="n">OPENSSL_VERSION</span>
|
||
<span class="go">'OpenSSL 1.0.2k 26 Jan 2017'</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.2 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.OPENSSL_VERSION_INFO">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">OPENSSL_VERSION_INFO</code><a class="headerlink" href="#ssl.OPENSSL_VERSION_INFO" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>代表 OpenSSL 库的版本信息的五个整数所组成的元组:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">ssl</span><span class="o">.</span><span class="n">OPENSSL_VERSION_INFO</span>
|
||
<span class="go">(1, 0, 2, 11, 15)</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.2 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.OPENSSL_VERSION_NUMBER">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">OPENSSL_VERSION_NUMBER</code><a class="headerlink" href="#ssl.OPENSSL_VERSION_NUMBER" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>OpenSSL 库的原始版本号,以单个整数表示:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">ssl</span><span class="o">.</span><span class="n">OPENSSL_VERSION_NUMBER</span>
|
||
<span class="go">268443839</span>
|
||
<span class="gp">>>> </span><span class="nb">hex</span><span class="p">(</span><span class="n">ssl</span><span class="o">.</span><span class="n">OPENSSL_VERSION_NUMBER</span><span class="p">)</span>
|
||
<span class="go">'0x100020bf'</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.2 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.ALERT_DESCRIPTION_HANDSHAKE_FAILURE">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">ALERT_DESCRIPTION_HANDSHAKE_FAILURE</code><a class="headerlink" href="#ssl.ALERT_DESCRIPTION_HANDSHAKE_FAILURE" title="永久链接至目标">¶</a></dt>
|
||
<dt id="ssl.ALERT_DESCRIPTION_INTERNAL_ERROR">
|
||
<code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">ALERT_DESCRIPTION_INTERNAL_ERROR</code><a class="headerlink" href="#ssl.ALERT_DESCRIPTION_INTERNAL_ERROR" title="永久链接至目标">¶</a></dt>
|
||
<dt>
|
||
<code class="sig-name descname">ALERT_DESCRIPTION_*</code></dt>
|
||
<dd><p>来自 <span class="target" id="index-62"></span><a class="rfc reference external" href="https://tools.ietf.org/html/rfc5246.html"><strong>RFC 5246</strong></a> 等文档的警报描述。 <a class="reference external" href="https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-6">IANA TLS Alert Registry</a> 中包含了这个列表及对定义其含义的 RFC 引用。</p>
|
||
<p>被用作 <a class="reference internal" href="#ssl.SSLContext.set_servername_callback" title="ssl.SSLContext.set_servername_callback"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLContext.set_servername_callback()</span></code></a> 中的回调函数的返回值。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.4 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="class">
|
||
<dt id="ssl.AlertDescription">
|
||
<em class="property">class </em><code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">AlertDescription</code><a class="headerlink" href="#ssl.AlertDescription" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>ALERT_DESCRIPTION_* 常量的 <a class="reference internal" href="enum.html#enum.IntEnum" title="enum.IntEnum"><code class="xref py py-class docutils literal notranslate"><span class="pre">enum.IntEnum</span></code></a> 多项集。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.6 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.Purpose.SERVER_AUTH">
|
||
<code class="sig-prename descclassname">Purpose.</code><code class="sig-name descname">SERVER_AUTH</code><a class="headerlink" href="#ssl.Purpose.SERVER_AUTH" title="永久链接至目标">¶</a></dt>
|
||
<dd><p><a class="reference internal" href="#ssl.create_default_context" title="ssl.create_default_context"><code class="xref py py-func docutils literal notranslate"><span class="pre">create_default_context()</span></code></a> 和 <a class="reference internal" href="#ssl.SSLContext.load_default_certs" title="ssl.SSLContext.load_default_certs"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLContext.load_default_certs()</span></code></a> 的选项值。 这个值表明此上下文可以被用来验证 Web 服务器(因此,它将被用来创建客户端套接字)。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.4 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="data">
|
||
<dt id="ssl.Purpose.CLIENT_AUTH">
|
||
<code class="sig-prename descclassname">Purpose.</code><code class="sig-name descname">CLIENT_AUTH</code><a class="headerlink" href="#ssl.Purpose.CLIENT_AUTH" title="永久链接至目标">¶</a></dt>
|
||
<dd><p><a class="reference internal" href="#ssl.create_default_context" title="ssl.create_default_context"><code class="xref py py-func docutils literal notranslate"><span class="pre">create_default_context()</span></code></a> 和 <a class="reference internal" href="#ssl.SSLContext.load_default_certs" title="ssl.SSLContext.load_default_certs"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLContext.load_default_certs()</span></code></a> 的选项值。 这个值表明此上下文可以被用来验证 Web 客户端(因此,它将被用来创建服务器端套接字)。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.4 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="class">
|
||
<dt id="ssl.SSLErrorNumber">
|
||
<em class="property">class </em><code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">SSLErrorNumber</code><a class="headerlink" href="#ssl.SSLErrorNumber" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>SSL_ERROR_* 常量的 <a class="reference internal" href="enum.html#enum.IntEnum" title="enum.IntEnum"><code class="xref py py-class docutils literal notranslate"><span class="pre">enum.IntEnum</span></code></a> 多项集。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.6 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="class">
|
||
<dt id="ssl.TLSVersion">
|
||
<em class="property">class </em><code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">TLSVersion</code><a class="headerlink" href="#ssl.TLSVersion" title="永久链接至目标">¶</a></dt>
|
||
<dd><p><a class="reference internal" href="#ssl.SSLContext.maximum_version" title="ssl.SSLContext.maximum_version"><code class="xref py py-attr docutils literal notranslate"><span class="pre">SSLContext.maximum_version</span></code></a> 和 <a class="reference internal" href="#ssl.SSLContext.minimum_version" title="ssl.SSLContext.minimum_version"><code class="xref py py-attr docutils literal notranslate"><span class="pre">SSLContext.minimum_version</span></code></a> 中的 SSL 和 TLS 版本的 <a class="reference internal" href="enum.html#enum.IntEnum" title="enum.IntEnum"><code class="xref py py-class docutils literal notranslate"><span class="pre">enum.IntEnum</span></code></a> 多项集。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.7 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="attribute">
|
||
<dt id="ssl.TLSVersion.MINIMUM_SUPPORTED">
|
||
<code class="sig-prename descclassname">TLSVersion.</code><code class="sig-name descname">MINIMUM_SUPPORTED</code><a class="headerlink" href="#ssl.TLSVersion.MINIMUM_SUPPORTED" title="永久链接至目标">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
<dl class="attribute">
|
||
<dt id="ssl.TLSVersion.MAXIMUM_SUPPORTED">
|
||
<code class="sig-prename descclassname">TLSVersion.</code><code class="sig-name descname">MAXIMUM_SUPPORTED</code><a class="headerlink" href="#ssl.TLSVersion.MAXIMUM_SUPPORTED" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>受支持的最低和最高 SSL 或 TLS 版本。 这些常量被称为魔术常量。 它们的值并不反映可用的最低和最高 TLS/SSL 版本。</p>
|
||
</dd></dl>
|
||
|
||
<dl class="attribute">
|
||
<dt id="ssl.TLSVersion.SSLv3">
|
||
<code class="sig-prename descclassname">TLSVersion.</code><code class="sig-name descname">SSLv3</code><a class="headerlink" href="#ssl.TLSVersion.SSLv3" title="永久链接至目标">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
<dl class="attribute">
|
||
<dt id="ssl.TLSVersion.TLSv1">
|
||
<code class="sig-prename descclassname">TLSVersion.</code><code class="sig-name descname">TLSv1</code><a class="headerlink" href="#ssl.TLSVersion.TLSv1" title="永久链接至目标">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
<dl class="attribute">
|
||
<dt id="ssl.TLSVersion.TLSv1_1">
|
||
<code class="sig-prename descclassname">TLSVersion.</code><code class="sig-name descname">TLSv1_1</code><a class="headerlink" href="#ssl.TLSVersion.TLSv1_1" title="永久链接至目标">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
<dl class="attribute">
|
||
<dt id="ssl.TLSVersion.TLSv1_2">
|
||
<code class="sig-prename descclassname">TLSVersion.</code><code class="sig-name descname">TLSv1_2</code><a class="headerlink" href="#ssl.TLSVersion.TLSv1_2" title="永久链接至目标">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
<dl class="attribute">
|
||
<dt id="ssl.TLSVersion.TLSv1_3">
|
||
<code class="sig-prename descclassname">TLSVersion.</code><code class="sig-name descname">TLSv1_3</code><a class="headerlink" href="#ssl.TLSVersion.TLSv1_3" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>SSL 3.0 至 TLS 1.3。</p>
|
||
</dd></dl>
|
||
|
||
</section>
|
||
</section>
|
||
<section id="ssl-sockets">
|
||
<h2>SSL 套接字<a class="headerlink" href="#ssl-sockets" title="永久链接至标题">¶</a></h2>
|
||
<dl class="class">
|
||
<dt id="ssl.SSLSocket">
|
||
<em class="property">class </em><code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">SSLSocket</code><span class="sig-paren">(</span><em class="sig-param">socket.socket</em><span class="sig-paren">)</span><a class="headerlink" href="#ssl.SSLSocket" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>SSL 套接字提供了 <a class="reference internal" href="socket.html#socket-objects"><span class="std std-ref">套接字对象</span></a> 的下列方法:</p>
|
||
<ul class="simple">
|
||
<li><p><a class="reference internal" href="socket.html#socket.socket.accept" title="socket.socket.accept"><code class="xref py py-meth docutils literal notranslate"><span class="pre">accept()</span></code></a></p></li>
|
||
<li><p><a class="reference internal" href="socket.html#socket.socket.bind" title="socket.socket.bind"><code class="xref py py-meth docutils literal notranslate"><span class="pre">bind()</span></code></a></p></li>
|
||
<li><p><a class="reference internal" href="socket.html#socket.socket.close" title="socket.socket.close"><code class="xref py py-meth docutils literal notranslate"><span class="pre">close()</span></code></a></p></li>
|
||
<li><p><a class="reference internal" href="socket.html#socket.socket.connect" title="socket.socket.connect"><code class="xref py py-meth docutils literal notranslate"><span class="pre">connect()</span></code></a></p></li>
|
||
<li><p><a class="reference internal" href="socket.html#socket.socket.detach" title="socket.socket.detach"><code class="xref py py-meth docutils literal notranslate"><span class="pre">detach()</span></code></a></p></li>
|
||
<li><p><a class="reference internal" href="socket.html#socket.socket.fileno" title="socket.socket.fileno"><code class="xref py py-meth docutils literal notranslate"><span class="pre">fileno()</span></code></a></p></li>
|
||
<li><p><a class="reference internal" href="socket.html#socket.socket.getpeername" title="socket.socket.getpeername"><code class="xref py py-meth docutils literal notranslate"><span class="pre">getpeername()</span></code></a>, <a class="reference internal" href="socket.html#socket.socket.getsockname" title="socket.socket.getsockname"><code class="xref py py-meth docutils literal notranslate"><span class="pre">getsockname()</span></code></a></p></li>
|
||
<li><p><a class="reference internal" href="socket.html#socket.socket.getsockopt" title="socket.socket.getsockopt"><code class="xref py py-meth docutils literal notranslate"><span class="pre">getsockopt()</span></code></a>, <a class="reference internal" href="socket.html#socket.socket.setsockopt" title="socket.socket.setsockopt"><code class="xref py py-meth docutils literal notranslate"><span class="pre">setsockopt()</span></code></a></p></li>
|
||
<li><p><a class="reference internal" href="socket.html#socket.socket.gettimeout" title="socket.socket.gettimeout"><code class="xref py py-meth docutils literal notranslate"><span class="pre">gettimeout()</span></code></a>, <a class="reference internal" href="socket.html#socket.socket.settimeout" title="socket.socket.settimeout"><code class="xref py py-meth docutils literal notranslate"><span class="pre">settimeout()</span></code></a>,
|
||
<a class="reference internal" href="socket.html#socket.socket.setblocking" title="socket.socket.setblocking"><code class="xref py py-meth docutils literal notranslate"><span class="pre">setblocking()</span></code></a></p></li>
|
||
<li><p><a class="reference internal" href="socket.html#socket.socket.listen" title="socket.socket.listen"><code class="xref py py-meth docutils literal notranslate"><span class="pre">listen()</span></code></a></p></li>
|
||
<li><p><a class="reference internal" href="socket.html#socket.socket.makefile" title="socket.socket.makefile"><code class="xref py py-meth docutils literal notranslate"><span class="pre">makefile()</span></code></a></p></li>
|
||
<li><p><a class="reference internal" href="socket.html#socket.socket.recv" title="socket.socket.recv"><code class="xref py py-meth docutils literal notranslate"><span class="pre">recv()</span></code></a>, <a class="reference internal" href="socket.html#socket.socket.recv_into" title="socket.socket.recv_into"><code class="xref py py-meth docutils literal notranslate"><span class="pre">recv_into()</span></code></a>
|
||
(but passing a non-zero <code class="docutils literal notranslate"><span class="pre">flags</span></code> argument is not allowed)</p></li>
|
||
<li><p><a class="reference internal" href="socket.html#socket.socket.send" title="socket.socket.send"><code class="xref py py-meth docutils literal notranslate"><span class="pre">send()</span></code></a>, <a class="reference internal" href="socket.html#socket.socket.sendall" title="socket.socket.sendall"><code class="xref py py-meth docutils literal notranslate"><span class="pre">sendall()</span></code></a> (with
|
||
the same limitation)</p></li>
|
||
<li><p><a class="reference internal" href="socket.html#socket.socket.sendfile" title="socket.socket.sendfile"><code class="xref py py-meth docutils literal notranslate"><span class="pre">sendfile()</span></code></a> (but <a class="reference internal" href="os.html#os.sendfile" title="os.sendfile"><code class="xref py py-mod docutils literal notranslate"><span class="pre">os.sendfile</span></code></a> will be used
|
||
for plain-text sockets only, else <a class="reference internal" href="socket.html#socket.socket.send" title="socket.socket.send"><code class="xref py py-meth docutils literal notranslate"><span class="pre">send()</span></code></a> will be used)</p></li>
|
||
<li><p><a class="reference internal" href="socket.html#socket.socket.shutdown" title="socket.socket.shutdown"><code class="xref py py-meth docutils literal notranslate"><span class="pre">shutdown()</span></code></a></p></li>
|
||
</ul>
|
||
<p>但是,由于 SSL(和 TLS)协议在 TCP 之上具有自己的框架,因此 SSL 套接字抽象在某些方面可能与常规的 OS 层级套接字存在差异。 特别是要查看 <a class="reference internal" href="#ssl-nonblocking"><span class="std std-ref">非阻塞型套接字说明</span></a>。</p>
|
||
<p><a class="reference internal" href="#ssl.SSLSocket" title="ssl.SSLSocket"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLSocket</span></code></a> 的实例必须使用 <a class="reference internal" href="#ssl.SSLContext.wrap_socket" title="ssl.SSLContext.wrap_socket"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLContext.wrap_socket()</span></code></a> 方法来创建。</p>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.5 版更改: </span>新增了 <code class="xref py py-meth docutils literal notranslate"><span class="pre">sendfile()</span></code> 方法。</p>
|
||
</div>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.5 版更改: </span><code class="xref py py-meth docutils literal notranslate"><span class="pre">shutdown()</span></code> 不会在每次接收或发送字节数据后重置套接字超时。 现在套接字超时为关闭的最大总持续时间。</p>
|
||
</div>
|
||
<div class="deprecated">
|
||
<p><span class="versionmodified deprecated">3.6 版后已移除: </span>直接创建 <a class="reference internal" href="#ssl.SSLSocket" title="ssl.SSLSocket"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLSocket</span></code></a> 实例的做法已被弃用,请使用 <a class="reference internal" href="#ssl.SSLContext.wrap_socket" title="ssl.SSLContext.wrap_socket"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLContext.wrap_socket()</span></code></a> 来包装套接字。</p>
|
||
</div>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.7 版更改: </span><a class="reference internal" href="#ssl.SSLSocket" title="ssl.SSLSocket"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLSocket</span></code></a> 的实例必须使用 <a class="reference internal" href="#ssl.SSLContext.wrap_socket" title="ssl.SSLContext.wrap_socket"><code class="xref py py-meth docutils literal notranslate"><span class="pre">wrap_socket()</span></code></a> 来创建。 在较早的版本中,直接创建实例是可能的。 但这从未被记入文档或是被正式支持。</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<p>SSL 套接字还具有下列方法和属性:</p>
|
||
<dl class="method">
|
||
<dt id="ssl.SSLSocket.read">
|
||
<code class="sig-prename descclassname">SSLSocket.</code><code class="sig-name descname">read</code><span class="sig-paren">(</span><em class="sig-param">len=1024</em>, <em class="sig-param">buffer=None</em><span class="sig-paren">)</span><a class="headerlink" href="#ssl.SSLSocket.read" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>从 SSL 套接字读取至多 <em>len</em> 个字节的数据并将结果作为 <code class="docutils literal notranslate"><span class="pre">bytes</span></code> 实例返回。 如果指定了 <em>buffer</em>,则改为读取到缓冲区,并返回所读取的字节数。</p>
|
||
<p>如果套接字为 <a class="reference internal" href="#ssl-nonblocking"><span class="std std-ref">非阻塞型</span></a> 则会引发 <a class="reference internal" href="#ssl.SSLWantReadError" title="ssl.SSLWantReadError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SSLWantReadError</span></code></a> 或 <a class="reference internal" href="#ssl.SSLWantWriteError" title="ssl.SSLWantWriteError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SSLWantWriteError</span></code></a> 且读取将阻塞。</p>
|
||
<p>由于在任何时候重新协商都是可能的,因此调用 <a class="reference internal" href="#ssl.SSLSocket.read" title="ssl.SSLSocket.read"><code class="xref py py-meth docutils literal notranslate"><span class="pre">read()</span></code></a> 也可能导致写入操作。</p>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.5 版更改: </span>套接字超时在每次接收或发送字节数据后不会再被重置。 现在套接字超时为读取至多 <em>len</em> 个字节数据的最大总持续时间。</p>
|
||
</div>
|
||
<div class="deprecated">
|
||
<p><span class="versionmodified deprecated">3.6 版后已移除: </span>请使用 <code class="xref py py-meth docutils literal notranslate"><span class="pre">recv()</span></code> 来代替 <a class="reference internal" href="#ssl.SSLSocket.read" title="ssl.SSLSocket.read"><code class="xref py py-meth docutils literal notranslate"><span class="pre">read()</span></code></a>。</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="method">
|
||
<dt id="ssl.SSLSocket.write">
|
||
<code class="sig-prename descclassname">SSLSocket.</code><code class="sig-name descname">write</code><span class="sig-paren">(</span><em class="sig-param">buf</em><span class="sig-paren">)</span><a class="headerlink" href="#ssl.SSLSocket.write" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>将 <em>buf</em> 写入到 SSL 套接字并返回所写入的字节数。 <em>buf</em> 参数必须为支持缓冲区接口的对象。</p>
|
||
<p>如果套接字为 <a class="reference internal" href="#ssl-nonblocking"><span class="std std-ref">非阻塞型</span></a> 则会引发 <a class="reference internal" href="#ssl.SSLWantReadError" title="ssl.SSLWantReadError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SSLWantReadError</span></code></a> 或 <a class="reference internal" href="#ssl.SSLWantWriteError" title="ssl.SSLWantWriteError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SSLWantWriteError</span></code></a> 且读取将阻塞。</p>
|
||
<p>由于在任何时候重新协商都是可能的,因此调用 <a class="reference internal" href="#ssl.SSLSocket.write" title="ssl.SSLSocket.write"><code class="xref py py-meth docutils literal notranslate"><span class="pre">write()</span></code></a> 也可能导致读取操作。</p>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.5 版更改: </span>套接字超时在每次接收或发送字节数据后不会再被重置。 现在套接字超时为写入 <em>buf</em> 的最大总持续时间。</p>
|
||
</div>
|
||
<div class="deprecated">
|
||
<p><span class="versionmodified deprecated">3.6 版后已移除: </span>请使用 <code class="xref py py-meth docutils literal notranslate"><span class="pre">send()</span></code> 来代替 <a class="reference internal" href="#ssl.SSLSocket.write" title="ssl.SSLSocket.write"><code class="xref py py-meth docutils literal notranslate"><span class="pre">write()</span></code></a>。</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<div class="admonition note">
|
||
<p class="admonition-title">注解</p>
|
||
<p><a class="reference internal" href="#ssl.SSLSocket.read" title="ssl.SSLSocket.read"><code class="xref py py-meth docutils literal notranslate"><span class="pre">read()</span></code></a> 和 <a class="reference internal" href="#ssl.SSLSocket.write" title="ssl.SSLSocket.write"><code class="xref py py-meth docutils literal notranslate"><span class="pre">write()</span></code></a> 方法是读写未加密的应用级数据,并将其解密/加密为带加密的线路级数据的低层级方法。 这些方法需要有激活的 SSL 连接,即握手已完成而 <a class="reference internal" href="#ssl.SSLSocket.unwrap" title="ssl.SSLSocket.unwrap"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLSocket.unwrap()</span></code></a> 尚未被调用。</p>
|
||
<p>通常你应当使用套接字 API 方法例如 <a class="reference internal" href="socket.html#socket.socket.recv" title="socket.socket.recv"><code class="xref py py-meth docutils literal notranslate"><span class="pre">recv()</span></code></a> 和 <a class="reference internal" href="socket.html#socket.socket.send" title="socket.socket.send"><code class="xref py py-meth docutils literal notranslate"><span class="pre">send()</span></code></a> 来代替这些方法。</p>
|
||
</div>
|
||
<dl class="method">
|
||
<dt id="ssl.SSLSocket.do_handshake">
|
||
<code class="sig-prename descclassname">SSLSocket.</code><code class="sig-name descname">do_handshake</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#ssl.SSLSocket.do_handshake" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>执行 SSL 设置握手。</p>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.4 版更改: </span>当套接字的 <a class="reference internal" href="#ssl.SSLSocket.context" title="ssl.SSLSocket.context"><code class="xref py py-attr docutils literal notranslate"><span class="pre">context</span></code></a> 的 <a class="reference internal" href="#ssl.SSLContext.check_hostname" title="ssl.SSLContext.check_hostname"><code class="xref py py-attr docutils literal notranslate"><span class="pre">check_hostname</span></code></a> 属性为真值时此握手方法还会执行 <a class="reference internal" href="#ssl.match_hostname" title="ssl.match_hostname"><code class="xref py py-func docutils literal notranslate"><span class="pre">match_hostname()</span></code></a>。</p>
|
||
</div>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.5 版更改: </span>套接字超时在每次接收或发送字节数据时不会再被重置。 现在套接字超时为握手的最大总持续时间。</p>
|
||
</div>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.7 版更改: </span>主机名或 IP 地址会在握手期间由 OpenSSL 进行匹配。 函数 <a class="reference internal" href="#ssl.match_hostname" title="ssl.match_hostname"><code class="xref py py-func docutils literal notranslate"><span class="pre">match_hostname()</span></code></a> 将不再被使用。 在 OpenSSL 拒绝主机名和 IP 地址的情况下,握手将提前被中止并向对等方发送 TLS 警告消息。</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="method">
|
||
<dt id="ssl.SSLSocket.getpeercert">
|
||
<code class="sig-prename descclassname">SSLSocket.</code><code class="sig-name descname">getpeercert</code><span class="sig-paren">(</span><em class="sig-param">binary_form=False</em><span class="sig-paren">)</span><a class="headerlink" href="#ssl.SSLSocket.getpeercert" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>如果连接另一端的对等方没有证书,则返回 <code class="docutils literal notranslate"><span class="pre">None</span></code>。 如果 SSL 握手还未完成,则会引发 <a class="reference internal" href="exceptions.html#ValueError" title="ValueError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">ValueError</span></code></a>。</p>
|
||
<p>如果 <code class="docutils literal notranslate"><span class="pre">binary_form</span></code> 形参为 <a class="reference internal" href="constants.html#False" title="False"><code class="xref py py-const docutils literal notranslate"><span class="pre">False</span></code></a>,并且从对等方接收到了证书,此方法将返回一个 <a class="reference internal" href="stdtypes.html#dict" title="dict"><code class="xref py py-class docutils literal notranslate"><span class="pre">dict</span></code></a> 实例。 如果证书未通过验证,则字典将为空。 如果证书通过验证,它将返回由多个密钥组成的字典,其中包括 <code class="docutils literal notranslate"><span class="pre">subject</span></code> (证书颁发给的主体) 和 <code class="docutils literal notranslate"><span class="pre">issuer</span></code> (颁发证书的主体)。 如果证书包含一个 <em>Subject Alternative Name</em> 扩展的实例 (see <span class="target" id="index-63"></span><a class="rfc reference external" href="https://tools.ietf.org/html/rfc3280.html"><strong>RFC 3280</strong></a>),则字典中还将有一个 <code class="docutils literal notranslate"><span class="pre">subjectAltName</span></code> 键。</p>
|
||
<p><code class="docutils literal notranslate"><span class="pre">subject</span></code> 和 <code class="docutils literal notranslate"><span class="pre">issuer</span></code> 字段都是包含在证书中相应字段的数据结构中给出的相对专有名称(RDN)序列的元组,每个 RDN 均为 name-value 对的序列。 这里是一个实际的示例:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="p">{</span><span class="s1">'issuer'</span><span class="p">:</span> <span class="p">(((</span><span class="s1">'countryName'</span><span class="p">,</span> <span class="s1">'IL'</span><span class="p">),),</span>
|
||
<span class="p">((</span><span class="s1">'organizationName'</span><span class="p">,</span> <span class="s1">'StartCom Ltd.'</span><span class="p">),),</span>
|
||
<span class="p">((</span><span class="s1">'organizationalUnitName'</span><span class="p">,</span>
|
||
<span class="s1">'Secure Digital Certificate Signing'</span><span class="p">),),</span>
|
||
<span class="p">((</span><span class="s1">'commonName'</span><span class="p">,</span>
|
||
<span class="s1">'StartCom Class 2 Primary Intermediate Server CA'</span><span class="p">),)),</span>
|
||
<span class="s1">'notAfter'</span><span class="p">:</span> <span class="s1">'Nov 22 08:15:19 2013 GMT'</span><span class="p">,</span>
|
||
<span class="s1">'notBefore'</span><span class="p">:</span> <span class="s1">'Nov 21 03:09:52 2011 GMT'</span><span class="p">,</span>
|
||
<span class="s1">'serialNumber'</span><span class="p">:</span> <span class="s1">'95F0'</span><span class="p">,</span>
|
||
<span class="s1">'subject'</span><span class="p">:</span> <span class="p">(((</span><span class="s1">'description'</span><span class="p">,</span> <span class="s1">'571208-SLe257oHY9fVQ07Z'</span><span class="p">),),</span>
|
||
<span class="p">((</span><span class="s1">'countryName'</span><span class="p">,</span> <span class="s1">'US'</span><span class="p">),),</span>
|
||
<span class="p">((</span><span class="s1">'stateOrProvinceName'</span><span class="p">,</span> <span class="s1">'California'</span><span class="p">),),</span>
|
||
<span class="p">((</span><span class="s1">'localityName'</span><span class="p">,</span> <span class="s1">'San Francisco'</span><span class="p">),),</span>
|
||
<span class="p">((</span><span class="s1">'organizationName'</span><span class="p">,</span> <span class="s1">'Electronic Frontier Foundation, Inc.'</span><span class="p">),),</span>
|
||
<span class="p">((</span><span class="s1">'commonName'</span><span class="p">,</span> <span class="s1">'*.eff.org'</span><span class="p">),),</span>
|
||
<span class="p">((</span><span class="s1">'emailAddress'</span><span class="p">,</span> <span class="s1">'hostmaster@eff.org'</span><span class="p">),)),</span>
|
||
<span class="s1">'subjectAltName'</span><span class="p">:</span> <span class="p">((</span><span class="s1">'DNS'</span><span class="p">,</span> <span class="s1">'*.eff.org'</span><span class="p">),</span> <span class="p">(</span><span class="s1">'DNS'</span><span class="p">,</span> <span class="s1">'eff.org'</span><span class="p">)),</span>
|
||
<span class="s1">'version'</span><span class="p">:</span> <span class="mi">3</span><span class="p">}</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">注解</p>
|
||
<p>要验证特定服务的证书,你可以使用 <a class="reference internal" href="#ssl.match_hostname" title="ssl.match_hostname"><code class="xref py py-func docutils literal notranslate"><span class="pre">match_hostname()</span></code></a> 函数。</p>
|
||
</div>
|
||
<p>如果 <code class="docutils literal notranslate"><span class="pre">binary_form</span></code> 形参为 <a class="reference internal" href="constants.html#True" title="True"><code class="xref py py-const docutils literal notranslate"><span class="pre">True</span></code></a>,并且提供了证书,此方法会将整个证书的 DER 编码形式作为字节序列返回,或者如果对等方未提供证书则返回 <a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal notranslate"><span class="pre">None</span></code></a>。 对等方是否提供证书取决于 SSL 套接字的角色:</p>
|
||
<ul class="simple">
|
||
<li><p>对于客户端 SSL 套接字,服务器将总是提供证书,无论是否需要进行验证;</p></li>
|
||
<li><p>对于服务器 SSL 套接字,客户端将仅在服务器要求时才提供证书;因此如果你使用了 <a class="reference internal" href="#ssl.CERT_NONE" title="ssl.CERT_NONE"><code class="xref py py-const docutils literal notranslate"><span class="pre">CERT_NONE</span></code></a> (而不是 <a class="reference internal" href="#ssl.CERT_OPTIONAL" title="ssl.CERT_OPTIONAL"><code class="xref py py-const docutils literal notranslate"><span class="pre">CERT_OPTIONAL</span></code></a> 或 <a class="reference internal" href="#ssl.CERT_REQUIRED" title="ssl.CERT_REQUIRED"><code class="xref py py-const docutils literal notranslate"><span class="pre">CERT_REQUIRED</span></code></a>) 则 <a class="reference internal" href="#ssl.SSLSocket.getpeercert" title="ssl.SSLSocket.getpeercert"><code class="xref py py-meth docutils literal notranslate"><span class="pre">getpeercert()</span></code></a> 将返回 <a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal notranslate"><span class="pre">None</span></code></a>。</p></li>
|
||
</ul>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.2 版更改: </span>返回的字典包括额外的条目例如 <code class="docutils literal notranslate"><span class="pre">issuer</span></code> 和 <code class="docutils literal notranslate"><span class="pre">notBefore</span></code>。</p>
|
||
</div>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.4 版更改: </span>如果握手未完成则会引发 <a class="reference internal" href="exceptions.html#ValueError" title="ValueError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">ValueError</span></code></a>。 返回的字典包括额外的 X509v3 扩展条目例如 <code class="docutils literal notranslate"><span class="pre">crlDistributionPoints</span></code>, <code class="docutils literal notranslate"><span class="pre">caIssuers</span></code> 和 <code class="docutils literal notranslate"><span class="pre">OCSP</span></code> URI。</p>
|
||
</div>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.8.1 版更改: </span>IPv6 地址字符串不再附带末尾换行符。</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="method">
|
||
<dt id="ssl.SSLSocket.cipher">
|
||
<code class="sig-prename descclassname">SSLSocket.</code><code class="sig-name descname">cipher</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#ssl.SSLSocket.cipher" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>返回由三个值组成的元组,其中包含所使用的密码名称,定义其使用方式的 SSL 协议版本,以及所使用的加密比特位数。 如果尚未建立连接,则返回 <code class="docutils literal notranslate"><span class="pre">None</span></code>。</p>
|
||
</dd></dl>
|
||
|
||
<dl class="method">
|
||
<dt id="ssl.SSLSocket.shared_ciphers">
|
||
<code class="sig-prename descclassname">SSLSocket.</code><code class="sig-name descname">shared_ciphers</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#ssl.SSLSocket.shared_ciphers" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>返回在握手期间由客户端共享的密码列表。 所返回列表的每个条目都是由三个值组成的元组,其中包括密码名称,定义其使用方式的 SSL 协议版本,以及密码所使用的加密比特位数。 如果尚未建立连接或套接字为客户端套接字则 <a class="reference internal" href="#ssl.SSLSocket.shared_ciphers" title="ssl.SSLSocket.shared_ciphers"><code class="xref py py-meth docutils literal notranslate"><span class="pre">shared_ciphers()</span></code></a> 将返回 <code class="docutils literal notranslate"><span class="pre">None</span></code>。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.5 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="method">
|
||
<dt id="ssl.SSLSocket.compression">
|
||
<code class="sig-prename descclassname">SSLSocket.</code><code class="sig-name descname">compression</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#ssl.SSLSocket.compression" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>以字符串形式返回所使用的压缩算法,或者如果连接没有使用压缩则返回 <code class="docutils literal notranslate"><span class="pre">None</span></code>。</p>
|
||
<p>如果高层级的协议支持自己的压缩机制,你可以使用 <a class="reference internal" href="#ssl.OP_NO_COMPRESSION" title="ssl.OP_NO_COMPRESSION"><code class="xref py py-data docutils literal notranslate"><span class="pre">OP_NO_COMPRESSION</span></code></a> 来禁用 SSL 层级的压缩。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.3 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="method">
|
||
<dt id="ssl.SSLSocket.get_channel_binding">
|
||
<code class="sig-prename descclassname">SSLSocket.</code><code class="sig-name descname">get_channel_binding</code><span class="sig-paren">(</span><em class="sig-param">cb_type="tls-unique"</em><span class="sig-paren">)</span><a class="headerlink" href="#ssl.SSLSocket.get_channel_binding" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>为当前连接获取字节串形式的通道绑定数据。 如果尚未连接或握手尚未完成则返回 <code class="docutils literal notranslate"><span class="pre">None</span></code>。</p>
|
||
<p><em>cb_type</em> 形参允许选择需要的通道绑定类型。 有效的通道绑定类型在 <a class="reference internal" href="#ssl.CHANNEL_BINDING_TYPES" title="ssl.CHANNEL_BINDING_TYPES"><code class="xref py py-data docutils literal notranslate"><span class="pre">CHANNEL_BINDING_TYPES</span></code></a> 列表中列出。 目前只支持由 <span class="target" id="index-64"></span><a class="rfc reference external" href="https://tools.ietf.org/html/rfc5929.html"><strong>RFC 5929</strong></a> 所定义的 'tls-unique' 通道绑定。 如果请求了一个不受支持的通道绑定类型则将引发 <a class="reference internal" href="exceptions.html#ValueError" title="ValueError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">ValueError</span></code></a>。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.3 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="method">
|
||
<dt id="ssl.SSLSocket.selected_alpn_protocol">
|
||
<code class="sig-prename descclassname">SSLSocket.</code><code class="sig-name descname">selected_alpn_protocol</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#ssl.SSLSocket.selected_alpn_protocol" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>返回在 TLS 握手期间所选择的协议。 如果 <a class="reference internal" href="#ssl.SSLContext.set_alpn_protocols" title="ssl.SSLContext.set_alpn_protocols"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLContext.set_alpn_protocols()</span></code></a> 未被调用,如果另一方不支持 ALPN,如果此套接字不支持任何客户端所用的协议,或者如果握手尚未发生,则将返回 <code class="docutils literal notranslate"><span class="pre">None</span></code>。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.5 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="method">
|
||
<dt id="ssl.SSLSocket.selected_npn_protocol">
|
||
<code class="sig-prename descclassname">SSLSocket.</code><code class="sig-name descname">selected_npn_protocol</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#ssl.SSLSocket.selected_npn_protocol" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>返回在Return the higher-level protocol that was selected during the TLS/SSL 握手期间所选择的高层级协议。 如果 <a class="reference internal" href="#ssl.SSLContext.set_npn_protocols" title="ssl.SSLContext.set_npn_protocols"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLContext.set_npn_protocols()</span></code></a> 未被调用,或者如果另一方不支持 NPN,或者如果握手尚未发生,则将返回 <code class="docutils literal notranslate"><span class="pre">None</span></code>。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.3 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="method">
|
||
<dt id="ssl.SSLSocket.unwrap">
|
||
<code class="sig-prename descclassname">SSLSocket.</code><code class="sig-name descname">unwrap</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#ssl.SSLSocket.unwrap" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>执行 SSL 关闭握手,这会从下层的套接字中移除 TLS 层,并返回下层的套接字对象。 这可被用来通过一个连接将加密操作转为非加密。 返回的套接字应当总是被用于同连接另一方的进一步通信,而不是原始的套接字。</p>
|
||
</dd></dl>
|
||
|
||
<dl class="method">
|
||
<dt id="ssl.SSLSocket.verify_client_post_handshake">
|
||
<code class="sig-prename descclassname">SSLSocket.</code><code class="sig-name descname">verify_client_post_handshake</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#ssl.SSLSocket.verify_client_post_handshake" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>向一个 TLS 1.3 客户端请求握手后身份验证(PHA)。 只有在初始 TLS 握手之后且双方都启用了 PHA 的情况下才能为服务器端套接字的 TLS 1.3 连接启用 PHA,参见 <a class="reference internal" href="#ssl.SSLContext.post_handshake_auth" title="ssl.SSLContext.post_handshake_auth"><code class="xref py py-attr docutils literal notranslate"><span class="pre">SSLContext.post_handshake_auth</span></code></a>。</p>
|
||
<p>此方法不会立即执行证书交换。 服务器端会在下一次写入事件期间发送 CertificateRequest 并期待客户端在下一次读取事件期间附带证书进行响应。</p>
|
||
<p>如果有任何前置条件未被满足(例如非 TLS 1.3,PHA 未启用),则会引发 <a class="reference internal" href="#ssl.SSLError" title="ssl.SSLError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SSLError</span></code></a>。</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">注解</p>
|
||
<p>仅在 OpenSSL 1.1.1 且 TLS 1.3 被启用时可用。 没有 TLS 1.3 支持,此方法将引发 <a class="reference internal" href="exceptions.html#NotImplementedError" title="NotImplementedError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">NotImplementedError</span></code></a>。</p>
|
||
</div>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.8 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="method">
|
||
<dt id="ssl.SSLSocket.version">
|
||
<code class="sig-prename descclassname">SSLSocket.</code><code class="sig-name descname">version</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#ssl.SSLSocket.version" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>以字符串形式返回由连接协商确定的实际 SSL 协议版本,或者如果未建立安全连接则返回 <code class="docutils literal notranslate"><span class="pre">None</span></code>。 在撰写本文档时,可能的返回值包括 <code class="docutils literal notranslate"><span class="pre">"SSLv2"</span></code>, <code class="docutils literal notranslate"><span class="pre">"SSLv3"</span></code>, <code class="docutils literal notranslate"><span class="pre">"TLSv1"</span></code>, <code class="docutils literal notranslate"><span class="pre">"TLSv1.1"</span></code> 和 <code class="docutils literal notranslate"><span class="pre">"TLSv1.2"</span></code>。 最新的 OpenSSL 版本可能会定义更多的返回值。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.5 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="method">
|
||
<dt id="ssl.SSLSocket.pending">
|
||
<code class="sig-prename descclassname">SSLSocket.</code><code class="sig-name descname">pending</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#ssl.SSLSocket.pending" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>返回在连接上等待被读取的已解密字节数。</p>
|
||
</dd></dl>
|
||
|
||
<dl class="attribute">
|
||
<dt id="ssl.SSLSocket.context">
|
||
<code class="sig-prename descclassname">SSLSocket.</code><code class="sig-name descname">context</code><a class="headerlink" href="#ssl.SSLSocket.context" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>此 SSL 套接字所联结的 <a class="reference internal" href="#ssl.SSLContext" title="ssl.SSLContext"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLContext</span></code></a> 对象。 如果 SSL 套接字是使用已弃用的 <a class="reference internal" href="#ssl.wrap_socket" title="ssl.wrap_socket"><code class="xref py py-func docutils literal notranslate"><span class="pre">wrap_socket()</span></code></a> 函数 (而非 <a class="reference internal" href="#ssl.SSLContext.wrap_socket" title="ssl.SSLContext.wrap_socket"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLContext.wrap_socket()</span></code></a>) 创建的,则这将是为此 SSL 套接字创建的自定义上下文对象。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.2 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="attribute">
|
||
<dt id="ssl.SSLSocket.server_side">
|
||
<code class="sig-prename descclassname">SSLSocket.</code><code class="sig-name descname">server_side</code><a class="headerlink" href="#ssl.SSLSocket.server_side" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>一个布尔值,对于服务器端套接字为 <code class="docutils literal notranslate"><span class="pre">True</span></code> 而对于客户端套接字则为 <code class="docutils literal notranslate"><span class="pre">False</span></code>。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.2 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="attribute">
|
||
<dt id="ssl.SSLSocket.server_hostname">
|
||
<code class="sig-prename descclassname">SSLSocket.</code><code class="sig-name descname">server_hostname</code><a class="headerlink" href="#ssl.SSLSocket.server_hostname" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>服务器的主机名: <a class="reference internal" href="stdtypes.html#str" title="str"><code class="xref py py-class docutils literal notranslate"><span class="pre">str</span></code></a> 类型,对于服务器端套接字或者如果构造器中未指定主机名则为 <code class="docutils literal notranslate"><span class="pre">None</span></code>。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.2 新版功能.</span></p>
|
||
</div>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.7 版更改: </span>现在该属性将始终为 ASCII 文本。 当 <code class="docutils literal notranslate"><span class="pre">server_hostname</span></code> 为一个国际化域名(IDN)时,该属性现在会保存为 A 标签形式 (<code class="docutils literal notranslate"><span class="pre">"xn--pythn-mua.org"</span></code>) 而非 U 标签形式 (<code class="docutils literal notranslate"><span class="pre">"pythön.org"</span></code>)。</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="attribute">
|
||
<dt id="ssl.SSLSocket.session">
|
||
<code class="sig-prename descclassname">SSLSocket.</code><code class="sig-name descname">session</code><a class="headerlink" href="#ssl.SSLSocket.session" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>用于 SSL 连接的 <a class="reference internal" href="#ssl.SSLSession" title="ssl.SSLSession"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLSession</span></code></a>。 该会话将在执行 TLS 握手后对客户端和服务器端套接字可用。 对于客户端套接字该会话可以在调用 <a class="reference internal" href="#ssl.SSLSocket.do_handshake" title="ssl.SSLSocket.do_handshake"><code class="xref py py-meth docutils literal notranslate"><span class="pre">do_handshake()</span></code></a> 之前被设置以重用一个会话。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.6 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="attribute">
|
||
<dt id="ssl.SSLSocket.session_reused">
|
||
<code class="sig-prename descclassname">SSLSocket.</code><code class="sig-name descname">session_reused</code><a class="headerlink" href="#ssl.SSLSocket.session_reused" title="永久链接至目标">¶</a></dt>
|
||
<dd><div class="versionadded">
|
||
<p><span class="versionmodified added">3.6 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
</section>
|
||
<section id="ssl-contexts">
|
||
<h2>SSL 上下文<a class="headerlink" href="#ssl-contexts" title="永久链接至标题">¶</a></h2>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.2 新版功能.</span></p>
|
||
</div>
|
||
<p>SSL 上下文可保存各种比单独 SSL 连接寿命更长的数据,例如 SSL 配置选项,证书和私钥等。 它还可为服务器端套接字管理缓存,以加快来自相同客户端的重复连接。</p>
|
||
<dl class="class">
|
||
<dt id="ssl.SSLContext">
|
||
<em class="property">class </em><code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">SSLContext</code><span class="sig-paren">(</span><em class="sig-param">protocol=PROTOCOL_TLS</em><span class="sig-paren">)</span><a class="headerlink" href="#ssl.SSLContext" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>创建一个新的 SSL 上下文。 你可以传入 <em>protocol</em>,它必须为此模块中定义的 <code class="docutils literal notranslate"><span class="pre">PROTOCOL_*</span></code> 常量之一。 该形参指定要使用哪个 SSL 协议版本。 通常,服务器会选择一个特定的协议版本,而客户端必须适应服务器的选择。 大多数版本都不能与其他版本互操作。 如果未指定,则默认值为 <a class="reference internal" href="#ssl.PROTOCOL_TLS" title="ssl.PROTOCOL_TLS"><code class="xref py py-data docutils literal notranslate"><span class="pre">PROTOCOL_TLS</span></code></a>;它提供了与其他版本的最大兼容性。</p>
|
||
<p>这个表显示了客户端(横向)的哪个版本能够连接服务器(纵向)的哪个版本。</p>
|
||
<blockquote>
|
||
<div><table class="docutils align-default">
|
||
<colgroup>
|
||
<col style="width: 26%" />
|
||
<col style="width: 13%" />
|
||
<col style="width: 13%" />
|
||
<col style="width: 14%" />
|
||
<col style="width: 10%" />
|
||
<col style="width: 12%" />
|
||
<col style="width: 12%" />
|
||
</colgroup>
|
||
<tbody>
|
||
<tr class="row-odd"><td><p><em>客户端</em> / <strong>服务器</strong></p></td>
|
||
<td><p><strong>SSLv2</strong></p></td>
|
||
<td><p><strong>SSLv3</strong></p></td>
|
||
<td><p><strong>TLS</strong> <a class="footnote-reference brackets" href="#id9" id="id1">3</a></p></td>
|
||
<td><p><strong>TLSv1</strong></p></td>
|
||
<td><p><strong>TLSv1.1</strong></p></td>
|
||
<td><p><strong>TLSv1.2</strong></p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p><em>SSLv2</em></p></td>
|
||
<td><p>是</p></td>
|
||
<td><p>否</p></td>
|
||
<td><p>否 <a class="footnote-reference brackets" href="#id7" id="id2">1</a></p></td>
|
||
<td><p>否</p></td>
|
||
<td><p>否</p></td>
|
||
<td><p>否</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p><em>SSLv3</em></p></td>
|
||
<td><p>否</p></td>
|
||
<td><p>是</p></td>
|
||
<td><p>否 <a class="footnote-reference brackets" href="#id8" id="id3">2</a></p></td>
|
||
<td><p>否</p></td>
|
||
<td><p>否</p></td>
|
||
<td><p>否</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p><em>TLS</em> (<em>SSLv23</em>) <a class="footnote-reference brackets" href="#id9" id="id4">3</a></p></td>
|
||
<td><p>否 <a class="footnote-reference brackets" href="#id7" id="id5">1</a></p></td>
|
||
<td><p>否 <a class="footnote-reference brackets" href="#id8" id="id6">2</a></p></td>
|
||
<td><p>是</p></td>
|
||
<td><p>是</p></td>
|
||
<td><p>是</p></td>
|
||
<td><p>是</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p><em>TLSv1</em></p></td>
|
||
<td><p>否</p></td>
|
||
<td><p>否</p></td>
|
||
<td><p>是</p></td>
|
||
<td><p>是</p></td>
|
||
<td><p>否</p></td>
|
||
<td><p>否</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p><em>TLSv1.1</em></p></td>
|
||
<td><p>否</p></td>
|
||
<td><p>否</p></td>
|
||
<td><p>是</p></td>
|
||
<td><p>否</p></td>
|
||
<td><p>是</p></td>
|
||
<td><p>否</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p><em>TLSv1.2</em></p></td>
|
||
<td><p>否</p></td>
|
||
<td><p>否</p></td>
|
||
<td><p>是</p></td>
|
||
<td><p>否</p></td>
|
||
<td><p>否</p></td>
|
||
<td><p>是</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div></blockquote>
|
||
<p class="rubric">备注</p>
|
||
<dl class="footnote brackets">
|
||
<dt class="label" id="id7"><span class="brackets">1</span><span class="fn-backref">(<a href="#id2">1</a>,<a href="#id5">2</a>)</span></dt>
|
||
<dd><p><a class="reference internal" href="#ssl.SSLContext" title="ssl.SSLContext"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLContext</span></code></a> 默认设置 <a class="reference internal" href="#ssl.OP_NO_SSLv2" title="ssl.OP_NO_SSLv2"><code class="xref py py-data docutils literal notranslate"><span class="pre">OP_NO_SSLv2</span></code></a> 以禁用 SSLv2。</p>
|
||
</dd>
|
||
<dt class="label" id="id8"><span class="brackets">2</span><span class="fn-backref">(<a href="#id3">1</a>,<a href="#id6">2</a>)</span></dt>
|
||
<dd><p><a class="reference internal" href="#ssl.SSLContext" title="ssl.SSLContext"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLContext</span></code></a> 默认设置 <a class="reference internal" href="#ssl.OP_NO_SSLv3" title="ssl.OP_NO_SSLv3"><code class="xref py py-data docutils literal notranslate"><span class="pre">OP_NO_SSLv3</span></code></a> 以禁用 SSLv3。</p>
|
||
</dd>
|
||
<dt class="label" id="id9"><span class="brackets">3</span><span class="fn-backref">(<a href="#id1">1</a>,<a href="#id4">2</a>)</span></dt>
|
||
<dd><p>TLS 1.3 协议在 OpenSSL >= 1.1.1 中设置 <a class="reference internal" href="#ssl.PROTOCOL_TLS" title="ssl.PROTOCOL_TLS"><code class="xref py py-data docutils literal notranslate"><span class="pre">PROTOCOL_TLS</span></code></a> 时可用。 没有专门针对 TLS 1.3 的 PROTOCOL 常量。</p>
|
||
</dd>
|
||
</dl>
|
||
<div class="admonition seealso">
|
||
<p class="admonition-title">参见</p>
|
||
<p><a class="reference internal" href="#ssl.create_default_context" title="ssl.create_default_context"><code class="xref py py-func docutils literal notranslate"><span class="pre">create_default_context()</span></code></a> 让 <a class="reference internal" href="#module-ssl" title="ssl: TLS/SSL wrapper for socket objects"><code class="xref py py-mod docutils literal notranslate"><span class="pre">ssl</span></code></a> 为特定目标选择安全设置。</p>
|
||
</div>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.6 版更改: </span>上下文会使用安全默认值来创建。 默认设置的选项有 <a class="reference internal" href="#ssl.OP_NO_COMPRESSION" title="ssl.OP_NO_COMPRESSION"><code class="xref py py-data docutils literal notranslate"><span class="pre">OP_NO_COMPRESSION</span></code></a>, <a class="reference internal" href="#ssl.OP_CIPHER_SERVER_PREFERENCE" title="ssl.OP_CIPHER_SERVER_PREFERENCE"><code class="xref py py-data docutils literal notranslate"><span class="pre">OP_CIPHER_SERVER_PREFERENCE</span></code></a>, <a class="reference internal" href="#ssl.OP_SINGLE_DH_USE" title="ssl.OP_SINGLE_DH_USE"><code class="xref py py-data docutils literal notranslate"><span class="pre">OP_SINGLE_DH_USE</span></code></a>, <a class="reference internal" href="#ssl.OP_SINGLE_ECDH_USE" title="ssl.OP_SINGLE_ECDH_USE"><code class="xref py py-data docutils literal notranslate"><span class="pre">OP_SINGLE_ECDH_USE</span></code></a>, <a class="reference internal" href="#ssl.OP_NO_SSLv2" title="ssl.OP_NO_SSLv2"><code class="xref py py-data docutils literal notranslate"><span class="pre">OP_NO_SSLv2</span></code></a> (except for <a class="reference internal" href="#ssl.PROTOCOL_SSLv2" title="ssl.PROTOCOL_SSLv2"><code class="xref py py-data docutils literal notranslate"><span class="pre">PROTOCOL_SSLv2</span></code></a>) 和 <a class="reference internal" href="#ssl.OP_NO_SSLv3" title="ssl.OP_NO_SSLv3"><code class="xref py py-data docutils literal notranslate"><span class="pre">OP_NO_SSLv3</span></code></a> (except for <a class="reference internal" href="#ssl.PROTOCOL_SSLv3" title="ssl.PROTOCOL_SSLv3"><code class="xref py py-data docutils literal notranslate"><span class="pre">PROTOCOL_SSLv3</span></code></a>)。 初始密码集列表只包含 <code class="docutils literal notranslate"><span class="pre">HIGH</span></code> 密码,不包含 <code class="docutils literal notranslate"><span class="pre">NULL</span></code> 密码和 <code class="docutils literal notranslate"><span class="pre">MD5</span></code> 密码 (<a class="reference internal" href="#ssl.PROTOCOL_SSLv2" title="ssl.PROTOCOL_SSLv2"><code class="xref py py-data docutils literal notranslate"><span class="pre">PROTOCOL_SSLv2</span></code></a> 除外)。</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<p><a class="reference internal" href="#ssl.SSLContext" title="ssl.SSLContext"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLContext</span></code></a> 对象具有以下方法和属性:</p>
|
||
<dl class="method">
|
||
<dt id="ssl.SSLContext.cert_store_stats">
|
||
<code class="sig-prename descclassname">SSLContext.</code><code class="sig-name descname">cert_store_stats</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#ssl.SSLContext.cert_store_stats" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>获取以字典表示的有关已加载的 X.509 证书数量,被标记为 CA 证书的 X.509 证书数量以及证书吊销列表的统计信息。</p>
|
||
<p>具有一个 CA 证书和一个其他证书的上下文示例:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">context</span><span class="o">.</span><span class="n">cert_store_stats</span><span class="p">()</span>
|
||
<span class="go">{'crl': 0, 'x509_ca': 1, 'x509': 2}</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.4 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="method">
|
||
<dt id="ssl.SSLContext.load_cert_chain">
|
||
<code class="sig-prename descclassname">SSLContext.</code><code class="sig-name descname">load_cert_chain</code><span class="sig-paren">(</span><em class="sig-param">certfile</em>, <em class="sig-param">keyfile=None</em>, <em class="sig-param">password=None</em><span class="sig-paren">)</span><a class="headerlink" href="#ssl.SSLContext.load_cert_chain" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>加载一个私钥及对应的证书。 <em>certfile</em> 字符串必须为以 PEM 格式表示的单个文件路径,该文件中包含证书以及确立证书真实性所需的任意数量的 CA 证书。 如果存在 <em>keyfile</em> 字符串,它必须指向一个包含私钥的文件。 否则私钥也将从 <em>certfile</em> 中提取。 请参阅 <a class="reference internal" href="#ssl-certificates"><span class="std std-ref">证书</span></a> 中的讨论来了解有关如何将证书存储至 <em>certfile</em> 的更多信息。</p>
|
||
<p><em>password</em> 参数可以是一个函数,调用时将得到用于解密私钥的密码。 它在私钥被加密且需要密码时才会被调用。 它调用时将不带任何参数,并且应当返回一个字符串、字节串或字节数组。 如果返回值是一个字符串,在用它解密私钥之前它将以 UTF-8 进行编码。 或者也可以直接将字符串、字节串或字节数组值作为 <em>password</em> 参数提供。 如果私钥未被加密且不需要密码则它将被忽略。</p>
|
||
<p>如果未指定 <em>password</em> 参数且需要一个密码,将会使用 OpenSSL 内置的密码提示机制来交互式地提示用户输入密码。</p>
|
||
<p>如果私钥不能匹配证书则会引发 <a class="reference internal" href="#ssl.SSLError" title="ssl.SSLError"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLError</span></code></a>。</p>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.3 版更改: </span>新增可选参数 <em>password</em>。</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="method">
|
||
<dt id="ssl.SSLContext.load_default_certs">
|
||
<code class="sig-prename descclassname">SSLContext.</code><code class="sig-name descname">load_default_certs</code><span class="sig-paren">(</span><em class="sig-param">purpose=Purpose.SERVER_AUTH</em><span class="sig-paren">)</span><a class="headerlink" href="#ssl.SSLContext.load_default_certs" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>从默认位置加载一组默认的 "证书颁发机构" (CA) 证书。 在 Windows 上它将从 <code class="docutils literal notranslate"><span class="pre">CA</span></code> 和 <code class="docutils literal notranslate"><span class="pre">ROOT</span></code> 系统存储中加载 CA 证书。 在其他系统上它会调用 <a class="reference internal" href="#ssl.SSLContext.set_default_verify_paths" title="ssl.SSLContext.set_default_verify_paths"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLContext.set_default_verify_paths()</span></code></a>。 将来该方法也可能会从其他位置加载 CA 证书。</p>
|
||
<p><em>purpose</em> 旗标指明要加载哪一类 CA 证书。 默认设置 <a class="reference internal" href="#ssl.Purpose.SERVER_AUTH" title="ssl.Purpose.SERVER_AUTH"><code class="xref py py-data docutils literal notranslate"><span class="pre">Purpose.SERVER_AUTH</span></code></a> 加载被标记且被信任用于 TLS Web 服务器验证(客户端套接字)的证书。 <a class="reference internal" href="#ssl.Purpose.CLIENT_AUTH" title="ssl.Purpose.CLIENT_AUTH"><code class="xref py py-data docutils literal notranslate"><span class="pre">Purpose.CLIENT_AUTH</span></code></a> 则加载用于在服务器端进行客户端证书验证的 CA 证书。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.4 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="method">
|
||
<dt id="ssl.SSLContext.load_verify_locations">
|
||
<code class="sig-prename descclassname">SSLContext.</code><code class="sig-name descname">load_verify_locations</code><span class="sig-paren">(</span><em class="sig-param">cafile=None</em>, <em class="sig-param">capath=None</em>, <em class="sig-param">cadata=None</em><span class="sig-paren">)</span><a class="headerlink" href="#ssl.SSLContext.load_verify_locations" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>当 <a class="reference internal" href="#ssl.SSLContext.verify_mode" title="ssl.SSLContext.verify_mode"><code class="xref py py-data docutils literal notranslate"><span class="pre">verify_mode</span></code></a> 不为 <a class="reference internal" href="#ssl.CERT_NONE" title="ssl.CERT_NONE"><code class="xref py py-data docutils literal notranslate"><span class="pre">CERT_NONE</span></code></a> 时加载一组用于验证其他对等方证书的 "证书颁发机构" (CA) 证书。 必须至少指定 <em>cafile</em> 或 <em>capath</em> 中的一个。</p>
|
||
<p>此方法还可加载 PEM 或 DER 格式的证书吊销列表 (CRL),为此必须正确配置 <a class="reference internal" href="#ssl.SSLContext.verify_flags" title="ssl.SSLContext.verify_flags"><code class="xref py py-attr docutils literal notranslate"><span class="pre">SSLContext.verify_flags</span></code></a>。</p>
|
||
<p>如果存在 <em>cafile</em> 字符串,它应为 PEM 格式的级联 CA 证书文件的路径。 请参阅 <a class="reference internal" href="#ssl-certificates"><span class="std std-ref">证书</span></a> 中的讨论来了解有关如何处理此文件中的证书的更多信息。</p>
|
||
<p>如果存在 <em>capath</em> 字符串,它应为包含多个 PEM 格式的 CA 证书的目录的路径,并遵循 <a class="reference external" href="https://www.openssl.org/docs/manmaster/man3/SSL_CTX_load_verify_locations.html">OpenSSL 专属布局</a>。</p>
|
||
<p>如果存在 <em>cadata</em> 对象,它应为一个或多个 PEM 编码的证书的 ASCII 字符串或者 DER 编码的证书的 <a class="reference internal" href="../glossary.html#term-bytes-like-object"><span class="xref std std-term">bytes-like object</span></a>。 与 <em>capath</em> 一样 PEM 编码的证书之外的多余行会被忽略,但至少要有一个证书。</p>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.4 版更改: </span>新增可选参数 <em>cadata</em></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="method">
|
||
<dt id="ssl.SSLContext.get_ca_certs">
|
||
<code class="sig-prename descclassname">SSLContext.</code><code class="sig-name descname">get_ca_certs</code><span class="sig-paren">(</span><em class="sig-param">binary_form=False</em><span class="sig-paren">)</span><a class="headerlink" href="#ssl.SSLContext.get_ca_certs" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>获取已离开法人 "证书颁发机构" (CA) 证书列表。 如果 <code class="docutils literal notranslate"><span class="pre">binary_form</span></code> 形参为 <a class="reference internal" href="constants.html#False" title="False"><code class="xref py py-const docutils literal notranslate"><span class="pre">False</span></code></a> 则每个列表条目都是一个类似于 <a class="reference internal" href="#ssl.SSLSocket.getpeercert" title="ssl.SSLSocket.getpeercert"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLSocket.getpeercert()</span></code></a> 输出的字典。 在其他情况下此方法将返回一个 DER 编码的证书的列表。 返回的列表不包含来自 <em>capath</em> 的证书,除非 SSL 连接请求并加载了一个证书。</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">注解</p>
|
||
<p>capath 目录中的证书不会被加载,除非它们已至少被使用过一次。</p>
|
||
</div>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.4 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="method">
|
||
<dt id="ssl.SSLContext.get_ciphers">
|
||
<code class="sig-prename descclassname">SSLContext.</code><code class="sig-name descname">get_ciphers</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#ssl.SSLContext.get_ciphers" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>获取已启用密码的列表。 该列表将按密码的优先级排序。 参见 <a class="reference internal" href="#ssl.SSLContext.set_ciphers" title="ssl.SSLContext.set_ciphers"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLContext.set_ciphers()</span></code></a>。</p>
|
||
<p>示例:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">ctx</span> <span class="o">=</span> <span class="n">ssl</span><span class="o">.</span><span class="n">SSLContext</span><span class="p">(</span><span class="n">ssl</span><span class="o">.</span><span class="n">PROTOCOL_SSLv23</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">ctx</span><span class="o">.</span><span class="n">set_ciphers</span><span class="p">(</span><span class="s1">'ECDHE+AESGCM:!ECDSA'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">ctx</span><span class="o">.</span><span class="n">get_ciphers</span><span class="p">()</span> <span class="c1"># OpenSSL 1.0.x</span>
|
||
<span class="go">[{'alg_bits': 256,</span>
|
||
<span class="go"> 'description': 'ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=RSA '</span>
|
||
<span class="go"> 'Enc=AESGCM(256) Mac=AEAD',</span>
|
||
<span class="go"> 'id': 50380848,</span>
|
||
<span class="go"> 'name': 'ECDHE-RSA-AES256-GCM-SHA384',</span>
|
||
<span class="go"> 'protocol': 'TLSv1/SSLv3',</span>
|
||
<span class="go"> 'strength_bits': 256},</span>
|
||
<span class="go"> {'alg_bits': 128,</span>
|
||
<span class="go"> 'description': 'ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=RSA '</span>
|
||
<span class="go"> 'Enc=AESGCM(128) Mac=AEAD',</span>
|
||
<span class="go"> 'id': 50380847,</span>
|
||
<span class="go"> 'name': 'ECDHE-RSA-AES128-GCM-SHA256',</span>
|
||
<span class="go"> 'protocol': 'TLSv1/SSLv3',</span>
|
||
<span class="go"> 'strength_bits': 128}]</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>在 OpenSSL 1.1 及更新的版本中密码字典会包含额外的字段:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">ctx</span><span class="o">.</span><span class="n">get_ciphers</span><span class="p">()</span> <span class="c1"># OpenSSL 1.1+</span>
|
||
<span class="go">[{'aead': True,</span>
|
||
<span class="go"> 'alg_bits': 256,</span>
|
||
<span class="go"> 'auth': 'auth-rsa',</span>
|
||
<span class="go"> 'description': 'ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=RSA '</span>
|
||
<span class="go"> 'Enc=AESGCM(256) Mac=AEAD',</span>
|
||
<span class="go"> 'digest': None,</span>
|
||
<span class="go"> 'id': 50380848,</span>
|
||
<span class="go"> 'kea': 'kx-ecdhe',</span>
|
||
<span class="go"> 'name': 'ECDHE-RSA-AES256-GCM-SHA384',</span>
|
||
<span class="go"> 'protocol': 'TLSv1.2',</span>
|
||
<span class="go"> 'strength_bits': 256,</span>
|
||
<span class="go"> 'symmetric': 'aes-256-gcm'},</span>
|
||
<span class="go"> {'aead': True,</span>
|
||
<span class="go"> 'alg_bits': 128,</span>
|
||
<span class="go"> 'auth': 'auth-rsa',</span>
|
||
<span class="go"> 'description': 'ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=RSA '</span>
|
||
<span class="go"> 'Enc=AESGCM(128) Mac=AEAD',</span>
|
||
<span class="go"> 'digest': None,</span>
|
||
<span class="go"> 'id': 50380847,</span>
|
||
<span class="go"> 'kea': 'kx-ecdhe',</span>
|
||
<span class="go"> 'name': 'ECDHE-RSA-AES128-GCM-SHA256',</span>
|
||
<span class="go"> 'protocol': 'TLSv1.2',</span>
|
||
<span class="go"> 'strength_bits': 128,</span>
|
||
<span class="go"> 'symmetric': 'aes-128-gcm'}]</span>
|
||
</pre></div>
|
||
</div>
|
||
<p class="availability"><a class="reference internal" href="intro.html#availability"><span class="std std-ref">可用性</span></a>: OpenSSL 1.0.2+。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.6 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="method">
|
||
<dt id="ssl.SSLContext.set_default_verify_paths">
|
||
<code class="sig-prename descclassname">SSLContext.</code><code class="sig-name descname">set_default_verify_paths</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#ssl.SSLContext.set_default_verify_paths" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>从构建 OpenSSL 库时定义的文件系统路径中加载一组默认的 "证书颁发机构" (CA) 证书。 不幸的是,没有一种简单的方式能知道此方法是否执行成功:如果未找到任何证书也不会返回错误。 不过,当 OpenSSL 库是作为操作系统的一部分被提供时,它的配置应当是正确的。</p>
|
||
</dd></dl>
|
||
|
||
<dl class="method">
|
||
<dt id="ssl.SSLContext.set_ciphers">
|
||
<code class="sig-prename descclassname">SSLContext.</code><code class="sig-name descname">set_ciphers</code><span class="sig-paren">(</span><em class="sig-param">ciphers</em><span class="sig-paren">)</span><a class="headerlink" href="#ssl.SSLContext.set_ciphers" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>为使用此上下文创建的套接字设置可用密码。 它应当为 <a class="reference external" href="https://www.openssl.org/docs/manmaster/man1/ciphers.html">OpenSSL 密码列表格式</a> 的字符串。 如果没有可被选择的密码(由于编译时选项或其他配置禁止使用所指定的任何密码),则将引发 <a class="reference internal" href="#ssl.SSLError" title="ssl.SSLError"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLError</span></code></a>。</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">注解</p>
|
||
<p>在连接后,SSL 套接字的 <a class="reference internal" href="#ssl.SSLSocket.cipher" title="ssl.SSLSocket.cipher"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLSocket.cipher()</span></code></a> 方法将给出当前所选择的密码。</p>
|
||
<p>在默认情况下 OpenSSL 1.1.1 会启用 TLS 1.3 密码套件。 该套件不能通过 <a class="reference internal" href="#ssl.SSLContext.set_ciphers" title="ssl.SSLContext.set_ciphers"><code class="xref py py-meth docutils literal notranslate"><span class="pre">set_ciphers()</span></code></a> 来禁用。</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="method">
|
||
<dt id="ssl.SSLContext.set_alpn_protocols">
|
||
<code class="sig-prename descclassname">SSLContext.</code><code class="sig-name descname">set_alpn_protocols</code><span class="sig-paren">(</span><em class="sig-param">protocols</em><span class="sig-paren">)</span><a class="headerlink" href="#ssl.SSLContext.set_alpn_protocols" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>指定在 SSL/TLS 握手期间套接字应当通告的协议。 它应为由 ASCII 字符串组成的列表,例如 <code class="docutils literal notranslate"><span class="pre">['http/1.1',</span> <span class="pre">'spdy/2']</span></code>,按首选顺序排列。 协议的选择将在握手期间发生,并依据 <span class="target" id="index-65"></span><a class="rfc reference external" href="https://tools.ietf.org/html/rfc7301.html"><strong>RFC 7301</strong></a> 来执行。 在握手成功后,<a class="reference internal" href="#ssl.SSLSocket.selected_alpn_protocol" title="ssl.SSLSocket.selected_alpn_protocol"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLSocket.selected_alpn_protocol()</span></code></a> 方法将返回已达成一致的协议。</p>
|
||
<p>如果 <a class="reference internal" href="#ssl.HAS_ALPN" title="ssl.HAS_ALPN"><code class="xref py py-data docutils literal notranslate"><span class="pre">HAS_ALPN</span></code></a> 为 <code class="docutils literal notranslate"><span class="pre">False</span></code> 则此方法将引发 <a class="reference internal" href="exceptions.html#NotImplementedError" title="NotImplementedError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">NotImplementedError</span></code></a>。</p>
|
||
<p>当双方都支持 ALPN 但不能就协议达成一致时 OpenSSL 1.1.0 至 1.1.0e 将中止并引发 <a class="reference internal" href="#ssl.SSLError" title="ssl.SSLError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SSLError</span></code></a>。 1.1.0f+ 的行为类似于 1.0.2,<a class="reference internal" href="#ssl.SSLSocket.selected_alpn_protocol" title="ssl.SSLSocket.selected_alpn_protocol"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLSocket.selected_alpn_protocol()</span></code></a> 返回 None。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.5 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="method">
|
||
<dt id="ssl.SSLContext.set_npn_protocols">
|
||
<code class="sig-prename descclassname">SSLContext.</code><code class="sig-name descname">set_npn_protocols</code><span class="sig-paren">(</span><em class="sig-param">protocols</em><span class="sig-paren">)</span><a class="headerlink" href="#ssl.SSLContext.set_npn_protocols" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>指定在Specify which protocols the socket should advertise during the SSL/TLS 握手期间套接字应当通告的协议。 它应为由字符串组成的列表,例如 <code class="docutils literal notranslate"><span class="pre">['http/1.1',</span> <span class="pre">'spdy/2']</span></code>,按首选顺序排列。 协议的选择将在握手期间发生,并将依据 <a class="reference external" href="https://en.wikipedia.org/wiki/Application-Layer_Protocol_Negotiation">应用层协议协商</a> 来执行。 在握手成功后,<a class="reference internal" href="#ssl.SSLSocket.selected_npn_protocol" title="ssl.SSLSocket.selected_npn_protocol"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLSocket.selected_npn_protocol()</span></code></a> 方法将返回已达成一致的协议。</p>
|
||
<p>如果 <a class="reference internal" href="#ssl.HAS_NPN" title="ssl.HAS_NPN"><code class="xref py py-data docutils literal notranslate"><span class="pre">HAS_NPN</span></code></a> 为 <code class="docutils literal notranslate"><span class="pre">False</span></code> 则此方法将引发 <a class="reference internal" href="exceptions.html#NotImplementedError" title="NotImplementedError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">NotImplementedError</span></code></a>。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.3 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="attribute">
|
||
<dt id="ssl.SSLContext.sni_callback">
|
||
<code class="sig-prename descclassname">SSLContext.</code><code class="sig-name descname">sni_callback</code><a class="headerlink" href="#ssl.SSLContext.sni_callback" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>注册一个回调函数,当 TLS 客户端指定了一个服务器名称提示时,该回调函数将在 SSL/TLS 服务器接收到 TLS Client Hello 握手消息后被调用。 服务器名称提示机制的定义见 <span class="target" id="index-66"></span><a class="rfc reference external" href="https://tools.ietf.org/html/rfc6066.html"><strong>RFC 6066</strong></a> section 3 - Server Name Indication。</p>
|
||
<p>每个 <code class="docutils literal notranslate"><span class="pre">SSLContext</span></code> 只能设置一个回调。 如果 <em>sni_callback</em> 被设置为 <code class="docutils literal notranslate"><span class="pre">None</span></code> 则会禁用回调。 对该函数的后续调用将禁用之前注册的回调。</p>
|
||
<p>此回调函数将附带三个参数来调用;第一个参数是 <a class="reference internal" href="#ssl.SSLSocket" title="ssl.SSLSocket"><code class="xref py py-class docutils literal notranslate"><span class="pre">ssl.SSLSocket</span></code></a>,第二个参数是代表客户端准备与之通信的服务器的字符串 (或者如果 TLS Client Hello 不包含服务器名称则为 <a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal notranslate"><span class="pre">None</span></code></a>) 而第三个参数是原来的 <a class="reference internal" href="#ssl.SSLContext" title="ssl.SSLContext"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLContext</span></code></a>。 服务器名称参数为文本形式。 对于国际化域名,服务器名称是一个 IDN A 标签 (<code class="docutils literal notranslate"><span class="pre">"xn--pythn-mua.org"</span></code>)。</p>
|
||
<p>此回调的一个典型用法是将 <a class="reference internal" href="#ssl.SSLSocket" title="ssl.SSLSocket"><code class="xref py py-class docutils literal notranslate"><span class="pre">ssl.SSLSocket</span></code></a> 的 <a class="reference internal" href="#ssl.SSLSocket.context" title="ssl.SSLSocket.context"><code class="xref py py-attr docutils literal notranslate"><span class="pre">SSLSocket.context</span></code></a> 属性修改为一个 <a class="reference internal" href="#ssl.SSLContext" title="ssl.SSLContext"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLContext</span></code></a> 类型的新对象,该对象代表与服务器相匹配的证书链。</p>
|
||
<p>由于 TLS 连接处于早期协商阶段,因此仅能使用有限的方法和属性例如 <a class="reference internal" href="#ssl.SSLSocket.selected_alpn_protocol" title="ssl.SSLSocket.selected_alpn_protocol"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLSocket.selected_alpn_protocol()</span></code></a> 和 <a class="reference internal" href="#ssl.SSLSocket.context" title="ssl.SSLSocket.context"><code class="xref py py-attr docutils literal notranslate"><span class="pre">SSLSocket.context</span></code></a>。 <a class="reference internal" href="#ssl.SSLSocket.getpeercert" title="ssl.SSLSocket.getpeercert"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLSocket.getpeercert()</span></code></a>, <a class="reference internal" href="#ssl.SSLSocket.getpeercert" title="ssl.SSLSocket.getpeercert"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLSocket.getpeercert()</span></code></a>, <a class="reference internal" href="#ssl.SSLSocket.cipher" title="ssl.SSLSocket.cipher"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLSocket.cipher()</span></code></a> 和 <code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLSocket.compress()</span></code> 方法要求 TLS 连接已经过 TLS Client Hello 因而将既不包含返回有意义的值,也不能安全地调用它们。</p>
|
||
<p><em>sni_callback</em> 函数必须返回 <code class="docutils literal notranslate"><span class="pre">None</span></code> 以允许 TLS 协商继续进行。 如果想要 TLS 失败,则可以返回常量 <a class="reference internal" href="#ssl.ALERT_DESCRIPTION_INTERNAL_ERROR" title="ssl.ALERT_DESCRIPTION_INTERNAL_ERROR"><code class="xref py py-const docutils literal notranslate"><span class="pre">ALERT_DESCRIPTION_*</span></code></a>。 其他返回值将导致 TLS 的致命错误 <a class="reference internal" href="#ssl.ALERT_DESCRIPTION_INTERNAL_ERROR" title="ssl.ALERT_DESCRIPTION_INTERNAL_ERROR"><code class="xref py py-const docutils literal notranslate"><span class="pre">ALERT_DESCRIPTION_INTERNAL_ERROR</span></code></a>。</p>
|
||
<p>如果从 <em>sni_callback</em> 函数引发了异常,则 TLS 连接将终止并发出 TLS 致命警告消息 <a class="reference internal" href="#ssl.ALERT_DESCRIPTION_HANDSHAKE_FAILURE" title="ssl.ALERT_DESCRIPTION_HANDSHAKE_FAILURE"><code class="xref py py-const docutils literal notranslate"><span class="pre">ALERT_DESCRIPTION_HANDSHAKE_FAILURE</span></code></a>。</p>
|
||
<p>如果 OpenSSL library 库在构建时定义了 OPENSSL_NO_TLSEXT 则此方法将返回 <a class="reference internal" href="exceptions.html#NotImplementedError" title="NotImplementedError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">NotImplementedError</span></code></a>。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.7 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="attribute">
|
||
<dt id="ssl.SSLContext.set_servername_callback">
|
||
<code class="sig-prename descclassname">SSLContext.</code><code class="sig-name descname">set_servername_callback</code><span class="sig-paren">(</span><em class="sig-param">server_name_callback</em><span class="sig-paren">)</span><a class="headerlink" href="#ssl.SSLContext.set_servername_callback" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>这是被保留用于向下兼容的旧式 API。 在可能的情况下,你应当改用 <a class="reference internal" href="#ssl.SSLContext.sni_callback" title="ssl.SSLContext.sni_callback"><code class="xref py py-attr docutils literal notranslate"><span class="pre">sni_callback</span></code></a>。 给出的 <em>server_name_callback</em> 类似于 <em>sni_callback</em>,不同之处在于当服务器主机名是 IDN 编码的国际化域名时,<em>server_name_callback</em> 会接收到一个已编码的 U 标签 (<code class="docutils literal notranslate"><span class="pre">"pythön.org"</span></code>)。</p>
|
||
<p>如果发生了服务器名称解码错误。 TLS 连接将终止并向客户端发出 <a class="reference internal" href="#ssl.ALERT_DESCRIPTION_INTERNAL_ERROR" title="ssl.ALERT_DESCRIPTION_INTERNAL_ERROR"><code class="xref py py-const docutils literal notranslate"><span class="pre">ALERT_DESCRIPTION_INTERNAL_ERROR</span></code></a> 最严重 TLS 警告消息。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.4 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="method">
|
||
<dt id="ssl.SSLContext.load_dh_params">
|
||
<code class="sig-prename descclassname">SSLContext.</code><code class="sig-name descname">load_dh_params</code><span class="sig-paren">(</span><em class="sig-param">dhfile</em><span class="sig-paren">)</span><a class="headerlink" href="#ssl.SSLContext.load_dh_params" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>加载密钥生成参数用于 Diffie-Hellman (DH) 密钥交换。 使用 DH 密钥交换能以消耗(服务器和客户端的)计算资源为代价提升前向保密性。 <em>dhfile</em> 参数应当为指向一个包含 PEM 格式的 DH 形参的文件的路径。</p>
|
||
<p>此设置不会应用于客户端套接字。 你还可以使用 <a class="reference internal" href="#ssl.OP_SINGLE_DH_USE" title="ssl.OP_SINGLE_DH_USE"><code class="xref py py-data docutils literal notranslate"><span class="pre">OP_SINGLE_DH_USE</span></code></a> 选项来进一步提升安全性。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.3 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="method">
|
||
<dt id="ssl.SSLContext.set_ecdh_curve">
|
||
<code class="sig-prename descclassname">SSLContext.</code><code class="sig-name descname">set_ecdh_curve</code><span class="sig-paren">(</span><em class="sig-param">curve_name</em><span class="sig-paren">)</span><a class="headerlink" href="#ssl.SSLContext.set_ecdh_curve" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>为基于椭圆曲线的 Elliptic Curve-based Diffie-Hellman (ECDH) 密钥交换设置曲线名称。 ECDH 显著快于常规 DH 同时据信同样安全。 <em>curve_name</em> 形参应为描述某个知名椭圆曲线的字符串,例如受到广泛支持的曲线 <code class="docutils literal notranslate"><span class="pre">prime256v1</span></code>。</p>
|
||
<p>此设置不会应用于客户端套接字。 你还可以使用 <a class="reference internal" href="#ssl.OP_SINGLE_ECDH_USE" title="ssl.OP_SINGLE_ECDH_USE"><code class="xref py py-data docutils literal notranslate"><span class="pre">OP_SINGLE_ECDH_USE</span></code></a> 选项来进一步提升安全性。</p>
|
||
<p>如果 <a class="reference internal" href="#ssl.HAS_ECDH" title="ssl.HAS_ECDH"><code class="xref py py-data docutils literal notranslate"><span class="pre">HAS_ECDH</span></code></a> 为 <code class="docutils literal notranslate"><span class="pre">False</span></code> 则此方法将不可用。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.3 新版功能.</span></p>
|
||
</div>
|
||
<div class="admonition seealso">
|
||
<p class="admonition-title">参见</p>
|
||
<dl class="simple">
|
||
<dt><a class="reference external" href="https://vincent.bernat.im/en/blog/2011-ssl-perfect-forward-secrecy">SSL/TLS 与完美的前向保密性</a></dt><dd><p>Vincent Bernat。</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="method">
|
||
<dt id="ssl.SSLContext.wrap_socket">
|
||
<code class="sig-prename descclassname">SSLContext.</code><code class="sig-name descname">wrap_socket</code><span class="sig-paren">(</span><em class="sig-param">sock</em>, <em class="sig-param">server_side=False</em>, <em class="sig-param">do_handshake_on_connect=True</em>, <em class="sig-param">suppress_ragged_eofs=True</em>, <em class="sig-param">server_hostname=None</em>, <em class="sig-param">session=None</em><span class="sig-paren">)</span><a class="headerlink" href="#ssl.SSLContext.wrap_socket" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>包装一个现有的 Python 套接字 <em>sock</em> 并返回一个 <a class="reference internal" href="#ssl.SSLContext.sslsocket_class" title="ssl.SSLContext.sslsocket_class"><code class="xref py py-attr docutils literal notranslate"><span class="pre">SSLContext.sslsocket_class</span></code></a> 的实例 (默认为 <a class="reference internal" href="#ssl.SSLSocket" title="ssl.SSLSocket"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLSocket</span></code></a>)。 返回的 SSL 套接字会绑定上下文、设置以及证书。 <em>sock</em> 必须是一个 <a class="reference internal" href="socket.html#socket.SOCK_STREAM" title="socket.SOCK_STREAM"><code class="xref py py-data docutils literal notranslate"><span class="pre">SOCK_STREAM</span></code></a> 套接字;其他套接字类型不被支持。</p>
|
||
<p>形参 <code class="docutils literal notranslate"><span class="pre">server_side</span></code> 是一个布尔值,它标明希望从该套接字获得服务器端行为还是客户端行为。</p>
|
||
<p>对于客户端套接字,上下文的构造会延迟执行;如果下层的套接字尚未连接,上下文的构造将在对套接字调用 <code class="xref py py-meth docutils literal notranslate"><span class="pre">connect()</span></code> 之后执行。 对于服务器端套接字,如果套接字没有远端对等方,它会被视为一个监听套接字,并且服务器端 SSL 包装操作会在通过 <code class="xref py py-meth docutils literal notranslate"><span class="pre">accept()</span></code> 方法所接受的客户端连接上自动执行。 此方法可能会引发 <a class="reference internal" href="#ssl.SSLError" title="ssl.SSLError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SSLError</span></code></a>。</p>
|
||
<p>在客户端连接上,可选形参 <em>server_hostname</em> 指定所要连接的服务的主机名。 这允许单个服务器托管具有单独证书的多个基于 SSL 的服务,很类似于 HTTP 虚拟主机。 如果 <em>server_side</em> 为真值则指定 <em>server_hostname</em> 将引发 <a class="reference internal" href="exceptions.html#ValueError" title="ValueError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">ValueError</span></code></a>。</p>
|
||
<p>形参 <code class="docutils literal notranslate"><span class="pre">do_handshake_on_connect</span></code> 指明是否要在调用 <code class="xref py py-meth docutils literal notranslate"><span class="pre">socket.connect()</span></code> 之后自动执行 SSL 握手,还是要通过发起调用 <a class="reference internal" href="#ssl.SSLSocket.do_handshake" title="ssl.SSLSocket.do_handshake"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLSocket.do_handshake()</span></code></a> 方法让应用程序显式地调用它。 显式地调用 <a class="reference internal" href="#ssl.SSLSocket.do_handshake" title="ssl.SSLSocket.do_handshake"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLSocket.do_handshake()</span></code></a> 可给予程序对握手中所涉及的套接字 I/O 阻塞行为的控制。</p>
|
||
<p>形参 <code class="docutils literal notranslate"><span class="pre">suppress_ragged_eofs</span></code> 指明 <code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLSocket.recv()</span></code> 方法应当如何从连接的另一端发送非预期的 EOF 信号。 如果指定为 <a class="reference internal" href="constants.html#True" title="True"><code class="xref py py-const docutils literal notranslate"><span class="pre">True</span></code></a> (默认值),它将返回正常的 EOF (空字节串对象) 来响应从下层套接字引发的非预期的 EOF 错误;如果指定为 <a class="reference internal" href="constants.html#False" title="False"><code class="xref py py-const docutils literal notranslate"><span class="pre">False</span></code></a>,它将向调用方引发异常。</p>
|
||
<p><em>session</em>,参见 <a class="reference internal" href="#ssl.SSLSocket.session" title="ssl.SSLSocket.session"><code class="xref py py-attr docutils literal notranslate"><span class="pre">session</span></code></a>。</p>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.5 版更改: </span>总是允许传送 server_hostname,即使 OpenSSL 没有 SNI。</p>
|
||
</div>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.6 版更改: </span>增加了 <em>session</em> 参数。</p>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.7 版更改: </span>此方法返回 <a class="reference internal" href="#ssl.SSLContext.sslsocket_class" title="ssl.SSLContext.sslsocket_class"><code class="xref py py-attr docutils literal notranslate"><span class="pre">SSLContext.sslsocket_class</span></code></a> 的实例而非硬编码的 <a class="reference internal" href="#ssl.SSLSocket" title="ssl.SSLSocket"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLSocket</span></code></a>。</p>
|
||
</div>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="attribute">
|
||
<dt id="ssl.SSLContext.sslsocket_class">
|
||
<code class="sig-prename descclassname">SSLContext.</code><code class="sig-name descname">sslsocket_class</code><a class="headerlink" href="#ssl.SSLContext.sslsocket_class" title="永久链接至目标">¶</a></dt>
|
||
<dd><p><a class="reference internal" href="#ssl.SSLContext.wrap_socket" title="ssl.SSLContext.wrap_socket"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLContext.wrap_socket()</span></code></a> 的返回类型,默认为 <a class="reference internal" href="#ssl.SSLSocket" title="ssl.SSLSocket"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLSocket</span></code></a>。 该属性可以在类实例上被重载以便返回自定义的 <a class="reference internal" href="#ssl.SSLSocket" title="ssl.SSLSocket"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLSocket</span></code></a> 的子类。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.7 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="method">
|
||
<dt id="ssl.SSLContext.wrap_bio">
|
||
<code class="sig-prename descclassname">SSLContext.</code><code class="sig-name descname">wrap_bio</code><span class="sig-paren">(</span><em class="sig-param">incoming</em>, <em class="sig-param">outgoing</em>, <em class="sig-param">server_side=False</em>, <em class="sig-param">server_hostname=None</em>, <em class="sig-param">session=None</em><span class="sig-paren">)</span><a class="headerlink" href="#ssl.SSLContext.wrap_bio" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>包装 BIO 对象 <em>incoming</em> 和 <em>outgoing</em> 并返回一个 <a class="reference internal" href="#ssl.SSLContext.sslobject_class" title="ssl.SSLContext.sslobject_class"><code class="xref py py-attr docutils literal notranslate"><span class="pre">SSLContext.sslobject_class</span></code></a> (默认为 <a class="reference internal" href="#ssl.SSLObject" title="ssl.SSLObject"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLObject</span></code></a>) 的实例。 SSL 例程将从 BIO 中读取输入数据并将数据写入到 outgoing BIO。</p>
|
||
<p><em>server_side</em>, <em>server_hostname</em> 和 <em>session</em> 形参具有与 <a class="reference internal" href="#ssl.SSLContext.wrap_socket" title="ssl.SSLContext.wrap_socket"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLContext.wrap_socket()</span></code></a> 中相同的含义。</p>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.6 版更改: </span>增加了 <em>session</em> 参数。</p>
|
||
</div>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.7 版更改: </span>此方法返回 <a class="reference internal" href="#ssl.SSLContext.sslobject_class" title="ssl.SSLContext.sslobject_class"><code class="xref py py-attr docutils literal notranslate"><span class="pre">SSLContext.sslobject_class</span></code></a> 的实例则非硬编码的 <a class="reference internal" href="#ssl.SSLObject" title="ssl.SSLObject"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLObject</span></code></a>。</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="attribute">
|
||
<dt id="ssl.SSLContext.sslobject_class">
|
||
<code class="sig-prename descclassname">SSLContext.</code><code class="sig-name descname">sslobject_class</code><a class="headerlink" href="#ssl.SSLContext.sslobject_class" title="永久链接至目标">¶</a></dt>
|
||
<dd><p><a class="reference internal" href="#ssl.SSLContext.wrap_bio" title="ssl.SSLContext.wrap_bio"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLContext.wrap_bio()</span></code></a> 的返回类型,默认为 <a class="reference internal" href="#ssl.SSLObject" title="ssl.SSLObject"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLObject</span></code></a>。 该属性可以在类实例上被重载以便返回自定义的 <a class="reference internal" href="#ssl.SSLObject" title="ssl.SSLObject"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLObject</span></code></a> 的子类。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.7 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="method">
|
||
<dt id="ssl.SSLContext.session_stats">
|
||
<code class="sig-prename descclassname">SSLContext.</code><code class="sig-name descname">session_stats</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#ssl.SSLContext.session_stats" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>获取由此上下文所创建或管理的 SSL 会话的相关统计信息。 返回将每个 <a class="reference external" href="https://www.openssl.org/docs/man1.1.0/ssl/SSL_CTX_sess_number.html">信息片</a> 的名称映射到其数字值的字典。 例如,以下是自上下文被创建以来会话缓存中命中和未命中的总数:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">stats</span> <span class="o">=</span> <span class="n">context</span><span class="o">.</span><span class="n">session_stats</span><span class="p">()</span>
|
||
<span class="gp">>>> </span><span class="n">stats</span><span class="p">[</span><span class="s1">'hits'</span><span class="p">],</span> <span class="n">stats</span><span class="p">[</span><span class="s1">'misses'</span><span class="p">]</span>
|
||
<span class="go">(0, 0)</span>
|
||
</pre></div>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="attribute">
|
||
<dt id="ssl.SSLContext.check_hostname">
|
||
<code class="sig-prename descclassname">SSLContext.</code><code class="sig-name descname">check_hostname</code><a class="headerlink" href="#ssl.SSLContext.check_hostname" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>是否要将匹配 <a class="reference internal" href="#ssl.SSLSocket.do_handshake" title="ssl.SSLSocket.do_handshake"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLSocket.do_handshake()</span></code></a> 中对等方证书的主机名。 该上下文的 <a class="reference internal" href="#ssl.SSLContext.verify_mode" title="ssl.SSLContext.verify_mode"><code class="xref py py-attr docutils literal notranslate"><span class="pre">verify_mode</span></code></a> 必须被设为 <a class="reference internal" href="#ssl.CERT_OPTIONAL" title="ssl.CERT_OPTIONAL"><code class="xref py py-data docutils literal notranslate"><span class="pre">CERT_OPTIONAL</span></code></a> 或 <a class="reference internal" href="#ssl.CERT_REQUIRED" title="ssl.CERT_REQUIRED"><code class="xref py py-data docutils literal notranslate"><span class="pre">CERT_REQUIRED</span></code></a>,并且你必须将 <em>server_hostname</em> 传给 <a class="reference internal" href="#ssl.SSLContext.wrap_socket" title="ssl.SSLContext.wrap_socket"><code class="xref py py-meth docutils literal notranslate"><span class="pre">wrap_socket()</span></code></a> 以便匹配主机名。 启用主机名检查会自动将 <a class="reference internal" href="#ssl.SSLContext.verify_mode" title="ssl.SSLContext.verify_mode"><code class="xref py py-attr docutils literal notranslate"><span class="pre">verify_mode</span></code></a> 从 <a class="reference internal" href="#ssl.CERT_NONE" title="ssl.CERT_NONE"><code class="xref py py-data docutils literal notranslate"><span class="pre">CERT_NONE</span></code></a> 设为 <a class="reference internal" href="#ssl.CERT_REQUIRED" title="ssl.CERT_REQUIRED"><code class="xref py py-data docutils literal notranslate"><span class="pre">CERT_REQUIRED</span></code></a>。 只要启用了主机名检查就无法将其设回 <a class="reference internal" href="#ssl.CERT_NONE" title="ssl.CERT_NONE"><code class="xref py py-data docutils literal notranslate"><span class="pre">CERT_NONE</span></code></a>。 <a class="reference internal" href="#ssl.PROTOCOL_TLS_CLIENT" title="ssl.PROTOCOL_TLS_CLIENT"><code class="xref py py-data docutils literal notranslate"><span class="pre">PROTOCOL_TLS_CLIENT</span></code></a> 协议默认启用主机名检查。 对于其他协议,则必须显式地启用主机名检查。</p>
|
||
<p>示例:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">socket</span><span class="o">,</span> <span class="nn">ssl</span>
|
||
|
||
<span class="n">context</span> <span class="o">=</span> <span class="n">ssl</span><span class="o">.</span><span class="n">SSLContext</span><span class="p">(</span><span class="n">ssl</span><span class="o">.</span><span class="n">PROTOCOL_TLSv1_2</span><span class="p">)</span>
|
||
<span class="n">context</span><span class="o">.</span><span class="n">verify_mode</span> <span class="o">=</span> <span class="n">ssl</span><span class="o">.</span><span class="n">CERT_REQUIRED</span>
|
||
<span class="n">context</span><span class="o">.</span><span class="n">check_hostname</span> <span class="o">=</span> <span class="kc">True</span>
|
||
<span class="n">context</span><span class="o">.</span><span class="n">load_default_certs</span><span class="p">()</span>
|
||
|
||
<span class="n">s</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">socket</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">AF_INET</span><span class="p">,</span> <span class="n">socket</span><span class="o">.</span><span class="n">SOCK_STREAM</span><span class="p">)</span>
|
||
<span class="n">ssl_sock</span> <span class="o">=</span> <span class="n">context</span><span class="o">.</span><span class="n">wrap_socket</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">server_hostname</span><span class="o">=</span><span class="s1">'www.verisign.com'</span><span class="p">)</span>
|
||
<span class="n">ssl_sock</span><span class="o">.</span><span class="n">connect</span><span class="p">((</span><span class="s1">'www.verisign.com'</span><span class="p">,</span> <span class="mi">443</span><span class="p">))</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.4 新版功能.</span></p>
|
||
</div>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.7 版更改: </span>现在当主机名检查被启用且 <a class="reference internal" href="#ssl.SSLContext.verify_mode" title="ssl.SSLContext.verify_mode"><code class="xref py py-attr docutils literal notranslate"><span class="pre">verify_mode</span></code></a> 为 <a class="reference internal" href="#ssl.CERT_NONE" title="ssl.CERT_NONE"><code class="xref py py-data docutils literal notranslate"><span class="pre">CERT_NONE</span></code></a> 时 <a class="reference internal" href="#ssl.SSLContext.verify_mode" title="ssl.SSLContext.verify_mode"><code class="xref py py-attr docutils literal notranslate"><span class="pre">verify_mode</span></code></a> 会自动更改为 <a class="reference internal" href="#ssl.CERT_REQUIRED" title="ssl.CERT_REQUIRED"><code class="xref py py-data docutils literal notranslate"><span class="pre">CERT_REQUIRED</span></code></a>。 在之前版本中同样的操作将失败并引发 <a class="reference internal" href="exceptions.html#ValueError" title="ValueError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">ValueError</span></code></a>。</p>
|
||
</div>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">注解</p>
|
||
<p>此特性要求 OpenSSL 0.9.8f 或更新的版本。</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="attribute">
|
||
<dt id="ssl.SSLContext.keylog_filename">
|
||
<code class="sig-prename descclassname">SSLContext.</code><code class="sig-name descname">keylog_filename</code><a class="headerlink" href="#ssl.SSLContext.keylog_filename" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>每当生成或接收到密钥时,将 TLS 密钥写入到一个密钥日志文件。 密钥日志文件的设计仅适用于调试目的。 文件的格式由 NSS 指明并为许多流量分析工具例如 Wireshark 所使用。 日志文件会以追加模式打开。 写入操作会在线程之间同步,但不会在进程之间同步。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.8 新版功能.</span></p>
|
||
</div>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">注解</p>
|
||
<p>此特性要求 OpenSSL 1.1.1 或更新的版本。</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="attribute">
|
||
<dt id="ssl.SSLContext.maximum_version">
|
||
<code class="sig-prename descclassname">SSLContext.</code><code class="sig-name descname">maximum_version</code><a class="headerlink" href="#ssl.SSLContext.maximum_version" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>一个代表所支持的最高 TLS 版本的 <a class="reference internal" href="#ssl.TLSVersion" title="ssl.TLSVersion"><code class="xref py py-class docutils literal notranslate"><span class="pre">TLSVersion</span></code></a> 枚举成员。 该值默认为 <a class="reference internal" href="#ssl.TLSVersion.MAXIMUM_SUPPORTED" title="ssl.TLSVersion.MAXIMUM_SUPPORTED"><code class="xref py py-attr docutils literal notranslate"><span class="pre">TLSVersion.MAXIMUM_SUPPORTED</span></code></a>。 这个属性对于 <a class="reference internal" href="#ssl.PROTOCOL_TLS" title="ssl.PROTOCOL_TLS"><code class="xref py py-attr docutils literal notranslate"><span class="pre">PROTOCOL_TLS</span></code></a>, <a class="reference internal" href="#ssl.PROTOCOL_TLS_CLIENT" title="ssl.PROTOCOL_TLS_CLIENT"><code class="xref py py-attr docutils literal notranslate"><span class="pre">PROTOCOL_TLS_CLIENT</span></code></a> 和 <a class="reference internal" href="#ssl.PROTOCOL_TLS_SERVER" title="ssl.PROTOCOL_TLS_SERVER"><code class="xref py py-attr docutils literal notranslate"><span class="pre">PROTOCOL_TLS_SERVER</span></code></a> 以外的其他协议来说都是只读的。</p>
|
||
<p><a class="reference internal" href="#ssl.SSLContext.maximum_version" title="ssl.SSLContext.maximum_version"><code class="xref py py-attr docutils literal notranslate"><span class="pre">maximum_version</span></code></a>, <a class="reference internal" href="#ssl.SSLContext.minimum_version" title="ssl.SSLContext.minimum_version"><code class="xref py py-attr docutils literal notranslate"><span class="pre">minimum_version</span></code></a> 和 <a class="reference internal" href="#ssl.SSLContext.options" title="ssl.SSLContext.options"><code class="xref py py-attr docutils literal notranslate"><span class="pre">SSLContext.options</span></code></a> 等属性都会影响上下文所支持的 SSL 和 TLS 版本。 这个实现不会阻止无效的组合。 例如一个 <a class="reference internal" href="#ssl.SSLContext.options" title="ssl.SSLContext.options"><code class="xref py py-attr docutils literal notranslate"><span class="pre">options</span></code></a> 为 <a class="reference internal" href="#ssl.OP_NO_TLSv1_2" title="ssl.OP_NO_TLSv1_2"><code class="xref py py-attr docutils literal notranslate"><span class="pre">OP_NO_TLSv1_2</span></code></a> 而 <a class="reference internal" href="#ssl.SSLContext.maximum_version" title="ssl.SSLContext.maximum_version"><code class="xref py py-attr docutils literal notranslate"><span class="pre">maximum_version</span></code></a> 设为 <a class="reference internal" href="#ssl.TLSVersion.TLSv1_2" title="ssl.TLSVersion.TLSv1_2"><code class="xref py py-attr docutils literal notranslate"><span class="pre">TLSVersion.TLSv1_2</span></code></a> 的上下文将无法建立 TLS 1.2 连接。</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">注解</p>
|
||
<p>除非 ssl 模块使用 OpenSSL 1.1.0g 或更新的版本编译否则这个属性将不可用。</p>
|
||
</div>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.7 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="attribute">
|
||
<dt id="ssl.SSLContext.minimum_version">
|
||
<code class="sig-prename descclassname">SSLContext.</code><code class="sig-name descname">minimum_version</code><a class="headerlink" href="#ssl.SSLContext.minimum_version" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>与 <a class="reference internal" href="#ssl.SSLContext.maximum_version" title="ssl.SSLContext.maximum_version"><code class="xref py py-attr docutils literal notranslate"><span class="pre">SSLContext.maximum_version</span></code></a> 类似,区别在于它是所支持的最低版本或为 <a class="reference internal" href="#ssl.TLSVersion.MINIMUM_SUPPORTED" title="ssl.TLSVersion.MINIMUM_SUPPORTED"><code class="xref py py-attr docutils literal notranslate"><span class="pre">TLSVersion.MINIMUM_SUPPORTED</span></code></a>。</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">注解</p>
|
||
<p>除非 ssl 模块使用 OpenSSL 1.1.0g 或更新的版本编译否则这个属性将不可用。</p>
|
||
</div>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.7 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="attribute">
|
||
<dt id="ssl.SSLContext.num_tickets">
|
||
<code class="sig-prename descclassname">SSLContext.</code><code class="sig-name descname">num_tickets</code><a class="headerlink" href="#ssl.SSLContext.num_tickets" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>控制 <code class="xref py py-attr docutils literal notranslate"><span class="pre">TLS_PROTOCOL_SERVER</span></code> 上下文的 TLS 1.3 会话凭据数量。 这个设置不会影响 TLS 1.0 到 1.2 连接。</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">注解</p>
|
||
<p>除非 ssl 模块使用 OpenSSL 1.1.1 或更新的版本编译否则这个属性将不可用。</p>
|
||
</div>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.8 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="attribute">
|
||
<dt id="ssl.SSLContext.options">
|
||
<code class="sig-prename descclassname">SSLContext.</code><code class="sig-name descname">options</code><a class="headerlink" href="#ssl.SSLContext.options" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>一个代表此上下文中所启用的 SSL 选项集的整数。 默认值为 <a class="reference internal" href="#ssl.OP_ALL" title="ssl.OP_ALL"><code class="xref py py-data docutils literal notranslate"><span class="pre">OP_ALL</span></code></a>,但你也可以通过在选项间进行 OR 运算来指定其他选项例如 <a class="reference internal" href="#ssl.OP_NO_SSLv2" title="ssl.OP_NO_SSLv2"><code class="xref py py-data docutils literal notranslate"><span class="pre">OP_NO_SSLv2</span></code></a>。</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">注解</p>
|
||
<p>对于 0.9.8m 之前的 OpenSSL 版本,只能设置选项,而不能清除它们。 尝试(通过重置相应比特位)清除选项将会引发 <a class="reference internal" href="exceptions.html#ValueError" title="ValueError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">ValueError</span></code></a>。</p>
|
||
</div>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.6 版更改: </span><a class="reference internal" href="#ssl.SSLContext.options" title="ssl.SSLContext.options"><code class="xref py py-attr docutils literal notranslate"><span class="pre">SSLContext.options</span></code></a> 返回 <a class="reference internal" href="#ssl.Options" title="ssl.Options"><code class="xref py py-class docutils literal notranslate"><span class="pre">Options</span></code></a> 旗标:</p>
|
||
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">ssl</span><span class="o">.</span><span class="n">create_default_context</span><span class="p">()</span><span class="o">.</span><span class="n">options</span>
|
||
<span class="go"><Options.OP_ALL|OP_NO_SSLv3|OP_NO_SSLv2|OP_NO_COMPRESSION: 2197947391></span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="attribute">
|
||
<dt id="ssl.SSLContext.post_handshake_auth">
|
||
<code class="sig-prename descclassname">SSLContext.</code><code class="sig-name descname">post_handshake_auth</code><a class="headerlink" href="#ssl.SSLContext.post_handshake_auth" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>启用 TLS 1.3 握手后客户端身份验证。 握手后验证默认是被禁用的,服务器只能在初始握手期间请求 TLS 客户端证书。 当启用时,服务器可以在握手之后的任何时候请求 TLS 客户端证书。</p>
|
||
<p>当在客户端套接字上启用时,客户端会向服务器发信号说明它支持握手后身份验证。</p>
|
||
<p>当在服务器端套接字上启用时,<a class="reference internal" href="#ssl.SSLContext.verify_mode" title="ssl.SSLContext.verify_mode"><code class="xref py py-attr docutils literal notranslate"><span class="pre">SSLContext.verify_mode</span></code></a> 也必须被设为 <a class="reference internal" href="#ssl.CERT_OPTIONAL" title="ssl.CERT_OPTIONAL"><code class="xref py py-data docutils literal notranslate"><span class="pre">CERT_OPTIONAL</span></code></a> 或 <a class="reference internal" href="#ssl.CERT_REQUIRED" title="ssl.CERT_REQUIRED"><code class="xref py py-data docutils literal notranslate"><span class="pre">CERT_REQUIRED</span></code></a>。 实际的客户端证书交换会被延迟直至 <a class="reference internal" href="#ssl.SSLSocket.verify_client_post_handshake" title="ssl.SSLSocket.verify_client_post_handshake"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLSocket.verify_client_post_handshake()</span></code></a> 被调用并执行了一些 I/O 操作后再进行。</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">注解</p>
|
||
<p>仅在 OpenSSL 1.1.1 且 TLS 1.3 被启用时可用。 如果没有 TLS 1.3 支持,该属性值将为 None 且不可被更改</p>
|
||
</div>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.8 新版功能.</span></p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="attribute">
|
||
<dt id="ssl.SSLContext.protocol">
|
||
<code class="sig-prename descclassname">SSLContext.</code><code class="sig-name descname">protocol</code><a class="headerlink" href="#ssl.SSLContext.protocol" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>构造上下文时所选择的协议版本。 这个属性是只读的。</p>
|
||
</dd></dl>
|
||
|
||
<dl class="attribute">
|
||
<dt id="ssl.SSLContext.hostname_checks_common_name">
|
||
<code class="sig-prename descclassname">SSLContext.</code><code class="sig-name descname">hostname_checks_common_name</code><a class="headerlink" href="#ssl.SSLContext.hostname_checks_common_name" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>在没有目标替代名称扩展的情况下 <a class="reference internal" href="#ssl.SSLContext.check_hostname" title="ssl.SSLContext.check_hostname"><code class="xref py py-attr docutils literal notranslate"><span class="pre">check_hostname</span></code></a> 是否要回退为验证证书的通用名称(默认为真值)。</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">注解</p>
|
||
<p>仅在 OpenSSL 1.1.0 或更新的版本上可写。</p>
|
||
</div>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.7 新版功能.</span></p>
|
||
</div>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.9.3 版更改: </span>此旗标在 OpenSSL 1.1.1k 之前的版本上不起作用。 Python 3.8.9, 3.9.3, 和 3.10 包含了针对之前版本的变通处理。</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="attribute">
|
||
<dt id="ssl.SSLContext.verify_flags">
|
||
<code class="sig-prename descclassname">SSLContext.</code><code class="sig-name descname">verify_flags</code><a class="headerlink" href="#ssl.SSLContext.verify_flags" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>证书验证操作的旗标。 你可以通过对 <a class="reference internal" href="#ssl.VERIFY_CRL_CHECK_LEAF" title="ssl.VERIFY_CRL_CHECK_LEAF"><code class="xref py py-data docutils literal notranslate"><span class="pre">VERIFY_CRL_CHECK_LEAF</span></code></a> 等值执行 OR 运算来设置组合旗标。 在默认情况下 OpenSSL 不会要求也不会验证证书吊销列表(CRL)。 仅在 openssl 版本 0.9.8+ 上可用。</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.4 新版功能.</span></p>
|
||
</div>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.6 版更改: </span><a class="reference internal" href="#ssl.SSLContext.verify_flags" title="ssl.SSLContext.verify_flags"><code class="xref py py-attr docutils literal notranslate"><span class="pre">SSLContext.verify_flags</span></code></a> 返回 <a class="reference internal" href="#ssl.VerifyFlags" title="ssl.VerifyFlags"><code class="xref py py-class docutils literal notranslate"><span class="pre">VerifyFlags</span></code></a> 旗标:</p>
|
||
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">ssl</span><span class="o">.</span><span class="n">create_default_context</span><span class="p">()</span><span class="o">.</span><span class="n">verify_flags</span>
|
||
<span class="go"><VerifyFlags.VERIFY_X509_TRUSTED_FIRST: 32768></span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="attribute">
|
||
<dt id="ssl.SSLContext.verify_mode">
|
||
<code class="sig-prename descclassname">SSLContext.</code><code class="sig-name descname">verify_mode</code><a class="headerlink" href="#ssl.SSLContext.verify_mode" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>是否要尝试验证其他对等方的证书以及如果验证失败应采取何种行为。 该属性值必须为 <a class="reference internal" href="#ssl.CERT_NONE" title="ssl.CERT_NONE"><code class="xref py py-data docutils literal notranslate"><span class="pre">CERT_NONE</span></code></a>, <a class="reference internal" href="#ssl.CERT_OPTIONAL" title="ssl.CERT_OPTIONAL"><code class="xref py py-data docutils literal notranslate"><span class="pre">CERT_OPTIONAL</span></code></a> 或 <a class="reference internal" href="#ssl.CERT_REQUIRED" title="ssl.CERT_REQUIRED"><code class="xref py py-data docutils literal notranslate"><span class="pre">CERT_REQUIRED</span></code></a> 之一。</p>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.6 版更改: </span><a class="reference internal" href="#ssl.SSLContext.verify_mode" title="ssl.SSLContext.verify_mode"><code class="xref py py-attr docutils literal notranslate"><span class="pre">SSLContext.verify_mode</span></code></a> 返回 <a class="reference internal" href="#ssl.VerifyMode" title="ssl.VerifyMode"><code class="xref py py-class docutils literal notranslate"><span class="pre">VerifyMode</span></code></a> 枚举:</p>
|
||
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">ssl</span><span class="o">.</span><span class="n">create_default_context</span><span class="p">()</span><span class="o">.</span><span class="n">verify_mode</span>
|
||
<span class="go"><VerifyMode.CERT_REQUIRED: 2></span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<span class="target" id="index-17"></span></section>
|
||
<section id="certificates">
|
||
<span id="ssl-certificates"></span><span id="index-18"></span><h2>证书<a class="headerlink" href="#certificates" title="永久链接至标题">¶</a></h2>
|
||
<p>总的来说证书是公钥/私钥系统的一个组成部分。 在这个系统中,每 个 <em>主体</em> (可能是一台机器、一个人或者一个组织) 都会分配到唯一的包含两部分的加密密钥。 一部分密钥是公开的,称为 <em>公钥</em>;另一部分密钥是保密的,称为 <em>私钥</em>。 这两个部分是互相关联的,就是说如果你用其中一个部分来加密一条消息,你将能用并且 <strong>只能</strong> 用另一个部分来解密它。</p>
|
||
<p>在一个证书中包含有两个主体的相关信息。 它包含 <em>目标方</em> 的名称和目标方的公钥。 它还包含由第二个主体 <em>颁发方</em> 所发布的声明:目标方的身份与他们所宣称的一致,包含的公钥也确实是目标方的公钥。 颁发方的声明使用颁发方的私钥进行签名,该私钥的内容只有颁发方自己才知道。 但是,任何人都可以找到颁发方的公钥,用它来解密这个声明,并将其与证书中的其他信息进行比较来验证颁发方声明的真实性。 证书还包含有关其有效期限的信息。 这被表示为两个字段,即 "notBefore" 和 "notAfter"。</p>
|
||
<p>在 Python 中应用证书时,客户端或服务器可以用证书来证明自己的身份。 还可以要求网络连接的另一方提供证书,提供的证书可以用于验证以满足客户端或服务器的验证要求。 如果验证失败,连接尝试可被设置为引发一个异常。 验证是由下层的 OpenSSL 框架来自动执行的;应用程序本身不必关注其内部的机制。 但是应用程序通常需要提供一组证书以允许此过程的发生。</p>
|
||
<p>Python 使用文件来包含证书。 它们应当采用 "PEM" 格式 (参见 <span class="target" id="index-67"></span><a class="rfc reference external" href="https://tools.ietf.org/html/rfc1422.html"><strong>RFC 1422</strong></a>),这是一种带有头部行和尾部行的 base-64 编码包装形式:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="o">-----</span><span class="n">BEGIN</span> <span class="n">CERTIFICATE</span><span class="o">-----</span>
|
||
<span class="o">...</span> <span class="p">(</span><span class="n">certificate</span> <span class="ow">in</span> <span class="n">base64</span> <span class="n">PEM</span> <span class="n">encoding</span><span class="p">)</span> <span class="o">...</span>
|
||
<span class="o">-----</span><span class="n">END</span> <span class="n">CERTIFICATE</span><span class="o">-----</span>
|
||
</pre></div>
|
||
</div>
|
||
<section id="certificate-chains">
|
||
<h3>证书链<a class="headerlink" href="#certificate-chains" title="永久链接至标题">¶</a></h3>
|
||
<p>包含证书的 Python 文件可以包含一系列的证书,有时被称为 <em>证书链</em>。 这个证书链应当以 "作为" 客户端或服务器的主体的专属证书打头,然后是证书颁发方的证书,然后是 <em>上述</em> 证书的颁发方的证书,证书链就这样不断上溯直到你得到一个 <em>自签名</em> 的证书,即具有相同目标方和颁发方的证书,有时也称为 <em>根证书</em>。 在证书文件中这些证书应当被拼接为一体。 例如,假设我们有一个包含三个证书的证书链,以我们的服务器证书打头,然后是为我们的服务器证书签名的证书颁发机构的证书,最后是为证书颁发机构的证书颁发证书的机构的根证书:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="o">-----</span><span class="n">BEGIN</span> <span class="n">CERTIFICATE</span><span class="o">-----</span>
|
||
<span class="o">...</span> <span class="p">(</span><span class="n">certificate</span> <span class="k">for</span> <span class="n">your</span> <span class="n">server</span><span class="p">)</span><span class="o">...</span>
|
||
<span class="o">-----</span><span class="n">END</span> <span class="n">CERTIFICATE</span><span class="o">-----</span>
|
||
<span class="o">-----</span><span class="n">BEGIN</span> <span class="n">CERTIFICATE</span><span class="o">-----</span>
|
||
<span class="o">...</span> <span class="p">(</span><span class="n">the</span> <span class="n">certificate</span> <span class="k">for</span> <span class="n">the</span> <span class="n">CA</span><span class="p">)</span><span class="o">...</span>
|
||
<span class="o">-----</span><span class="n">END</span> <span class="n">CERTIFICATE</span><span class="o">-----</span>
|
||
<span class="o">-----</span><span class="n">BEGIN</span> <span class="n">CERTIFICATE</span><span class="o">-----</span>
|
||
<span class="o">...</span> <span class="p">(</span><span class="n">the</span> <span class="n">root</span> <span class="n">certificate</span> <span class="k">for</span> <span class="n">the</span> <span class="n">CA</span><span class="s1">'s issuer)...</span>
|
||
<span class="o">-----</span><span class="n">END</span> <span class="n">CERTIFICATE</span><span class="o">-----</span>
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
<section id="ca-certificates">
|
||
<h3>CA 证书<a class="headerlink" href="#ca-certificates" title="永久链接至标题">¶</a></h3>
|
||
<p>如果你想要求对连接的另一方的证书进行验证,你必须提供一个 "CA 证书" 文件,其中包含了你愿意信任的每个颁发方的证书链。 同样地,这个文件的内容就是这些证书链拼接在一起的结果。 为了进行验证,Python 将使用它在文件中找到的第一个匹配的证书链。 可以通过调用 <a class="reference internal" href="#ssl.SSLContext.load_default_certs" title="ssl.SSLContext.load_default_certs"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLContext.load_default_certs()</span></code></a> 来使用系统平台的证书文件,这可以由 <a class="reference internal" href="#ssl.create_default_context" title="ssl.create_default_context"><code class="xref py py-func docutils literal notranslate"><span class="pre">create_default_context()</span></code></a> 自动完成。</p>
|
||
</section>
|
||
<section id="combined-key-and-certificate">
|
||
<h3>合并的密钥和证书<a class="headerlink" href="#combined-key-and-certificate" title="永久链接至标题">¶</a></h3>
|
||
<p>私钥往往与证书存储在相同的文件中;在此情况下,只需要将 <code class="docutils literal notranslate"><span class="pre">certfile</span></code> 形参传给 <a class="reference internal" href="#ssl.SSLContext.load_cert_chain" title="ssl.SSLContext.load_cert_chain"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLContext.load_cert_chain()</span></code></a> 和 <a class="reference internal" href="#ssl.wrap_socket" title="ssl.wrap_socket"><code class="xref py py-func docutils literal notranslate"><span class="pre">wrap_socket()</span></code></a>。 如果私钥是与证书一起存储的,则它应当放在证书链的第一个证书之前:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="o">-----</span><span class="n">BEGIN</span> <span class="n">RSA</span> <span class="n">PRIVATE</span> <span class="n">KEY</span><span class="o">-----</span>
|
||
<span class="o">...</span> <span class="p">(</span><span class="n">private</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">base64</span> <span class="n">encoding</span><span class="p">)</span> <span class="o">...</span>
|
||
<span class="o">-----</span><span class="n">END</span> <span class="n">RSA</span> <span class="n">PRIVATE</span> <span class="n">KEY</span><span class="o">-----</span>
|
||
<span class="o">-----</span><span class="n">BEGIN</span> <span class="n">CERTIFICATE</span><span class="o">-----</span>
|
||
<span class="o">...</span> <span class="p">(</span><span class="n">certificate</span> <span class="ow">in</span> <span class="n">base64</span> <span class="n">PEM</span> <span class="n">encoding</span><span class="p">)</span> <span class="o">...</span>
|
||
<span class="o">-----</span><span class="n">END</span> <span class="n">CERTIFICATE</span><span class="o">-----</span>
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
<section id="self-signed-certificates">
|
||
<h3>自签名证书<a class="headerlink" href="#self-signed-certificates" title="永久链接至标题">¶</a></h3>
|
||
<p>如果你准备创建一个提供 SSL 加密连接服务的服务器,你需要为该服务获取一份证书。 有许多方式可以获取合适的证书,例如从证书颁发机构购买。 另一种常见做法是生成自签名证书。 生成自签名证书的最简单方式是使用 OpenSSL 软件包,代码如下所示:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="o">%</span> <span class="n">openssl</span> <span class="n">req</span> <span class="o">-</span><span class="n">new</span> <span class="o">-</span><span class="n">x509</span> <span class="o">-</span><span class="n">days</span> <span class="mi">365</span> <span class="o">-</span><span class="n">nodes</span> <span class="o">-</span><span class="n">out</span> <span class="n">cert</span><span class="o">.</span><span class="n">pem</span> <span class="o">-</span><span class="n">keyout</span> <span class="n">cert</span><span class="o">.</span><span class="n">pem</span>
|
||
<span class="n">Generating</span> <span class="n">a</span> <span class="mi">1024</span> <span class="n">bit</span> <span class="n">RSA</span> <span class="n">private</span> <span class="n">key</span>
|
||
<span class="o">.......++++++</span>
|
||
<span class="o">.............................++++++</span>
|
||
<span class="n">writing</span> <span class="n">new</span> <span class="n">private</span> <span class="n">key</span> <span class="n">to</span> <span class="s1">'cert.pem'</span>
|
||
<span class="o">-----</span>
|
||
<span class="n">You</span> <span class="n">are</span> <span class="n">about</span> <span class="n">to</span> <span class="n">be</span> <span class="n">asked</span> <span class="n">to</span> <span class="n">enter</span> <span class="n">information</span> <span class="n">that</span> <span class="n">will</span> <span class="n">be</span> <span class="n">incorporated</span>
|
||
<span class="n">into</span> <span class="n">your</span> <span class="n">certificate</span> <span class="n">request</span><span class="o">.</span>
|
||
<span class="n">What</span> <span class="n">you</span> <span class="n">are</span> <span class="n">about</span> <span class="n">to</span> <span class="n">enter</span> <span class="ow">is</span> <span class="n">what</span> <span class="ow">is</span> <span class="n">called</span> <span class="n">a</span> <span class="n">Distinguished</span> <span class="n">Name</span> <span class="ow">or</span> <span class="n">a</span> <span class="n">DN</span><span class="o">.</span>
|
||
<span class="n">There</span> <span class="n">are</span> <span class="n">quite</span> <span class="n">a</span> <span class="n">few</span> <span class="n">fields</span> <span class="n">but</span> <span class="n">you</span> <span class="n">can</span> <span class="n">leave</span> <span class="n">some</span> <span class="n">blank</span>
|
||
<span class="n">For</span> <span class="n">some</span> <span class="n">fields</span> <span class="n">there</span> <span class="n">will</span> <span class="n">be</span> <span class="n">a</span> <span class="n">default</span> <span class="n">value</span><span class="p">,</span>
|
||
<span class="n">If</span> <span class="n">you</span> <span class="n">enter</span> <span class="s1">'.'</span><span class="p">,</span> <span class="n">the</span> <span class="n">field</span> <span class="n">will</span> <span class="n">be</span> <span class="n">left</span> <span class="n">blank</span><span class="o">.</span>
|
||
<span class="o">-----</span>
|
||
<span class="n">Country</span> <span class="n">Name</span> <span class="p">(</span><span class="mi">2</span> <span class="n">letter</span> <span class="n">code</span><span class="p">)</span> <span class="p">[</span><span class="n">AU</span><span class="p">]:</span><span class="n">US</span>
|
||
<span class="n">State</span> <span class="ow">or</span> <span class="n">Province</span> <span class="n">Name</span> <span class="p">(</span><span class="n">full</span> <span class="n">name</span><span class="p">)</span> <span class="p">[</span><span class="n">Some</span><span class="o">-</span><span class="n">State</span><span class="p">]:</span><span class="n">MyState</span>
|
||
<span class="n">Locality</span> <span class="n">Name</span> <span class="p">(</span><span class="n">eg</span><span class="p">,</span> <span class="n">city</span><span class="p">)</span> <span class="p">[]:</span><span class="n">Some</span> <span class="n">City</span>
|
||
<span class="n">Organization</span> <span class="n">Name</span> <span class="p">(</span><span class="n">eg</span><span class="p">,</span> <span class="n">company</span><span class="p">)</span> <span class="p">[</span><span class="n">Internet</span> <span class="n">Widgits</span> <span class="n">Pty</span> <span class="n">Ltd</span><span class="p">]:</span><span class="n">My</span> <span class="n">Organization</span><span class="p">,</span> <span class="n">Inc</span><span class="o">.</span>
|
||
<span class="n">Organizational</span> <span class="n">Unit</span> <span class="n">Name</span> <span class="p">(</span><span class="n">eg</span><span class="p">,</span> <span class="n">section</span><span class="p">)</span> <span class="p">[]:</span><span class="n">My</span> <span class="n">Group</span>
|
||
<span class="n">Common</span> <span class="n">Name</span> <span class="p">(</span><span class="n">eg</span><span class="p">,</span> <span class="n">YOUR</span> <span class="n">name</span><span class="p">)</span> <span class="p">[]:</span><span class="n">myserver</span><span class="o">.</span><span class="n">mygroup</span><span class="o">.</span><span class="n">myorganization</span><span class="o">.</span><span class="n">com</span>
|
||
<span class="n">Email</span> <span class="n">Address</span> <span class="p">[]:</span><span class="n">ops</span><span class="nd">@myserver</span><span class="o">.</span><span class="n">mygroup</span><span class="o">.</span><span class="n">myorganization</span><span class="o">.</span><span class="n">com</span>
|
||
<span class="o">%</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>自签名证书的缺点在于它是它自身的根证书,因此不会存在于别人的已知(且信任的)根证书缓存当中。</p>
|
||
</section>
|
||
</section>
|
||
<section id="examples">
|
||
<h2>例子<a class="headerlink" href="#examples" title="永久链接至标题">¶</a></h2>
|
||
<section id="testing-for-ssl-support">
|
||
<h3>检测 SSL 支持<a class="headerlink" href="#testing-for-ssl-support" title="永久链接至标题">¶</a></h3>
|
||
<p>要检测一个 Python 安装版中是否带有 SSL 支持,用户代码应当使用以下例程:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span>
|
||
<span class="kn">import</span> <span class="nn">ssl</span>
|
||
<span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span>
|
||
<span class="k">pass</span>
|
||
<span class="k">else</span><span class="p">:</span>
|
||
<span class="o">...</span> <span class="c1"># do something that requires SSL support</span>
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
<section id="client-side-operation">
|
||
<h3>客户端操作<a class="headerlink" href="#client-side-operation" title="永久链接至标题">¶</a></h3>
|
||
<p>这个例子创建了一个 SSL 上下文并使用客户端套接字的推荐安全设置,包括自动证书验证:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">context</span> <span class="o">=</span> <span class="n">ssl</span><span class="o">.</span><span class="n">create_default_context</span><span class="p">()</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>如果你喜欢自行调整安全设置,你可能需要从头创建一个上下文(但是请请注意避免不正确的设置):</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">context</span> <span class="o">=</span> <span class="n">ssl</span><span class="o">.</span><span class="n">SSLContext</span><span class="p">(</span><span class="n">ssl</span><span class="o">.</span><span class="n">PROTOCOL_TLS_CLIENT</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">context</span><span class="o">.</span><span class="n">load_verify_locations</span><span class="p">(</span><span class="s2">"/etc/ssl/certs/ca-bundle.crt"</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>(这段代码假定你的操作系统将所有 CA 证书打包存放于 <code class="docutils literal notranslate"><span class="pre">/etc/ssl/certs/ca-bundle.crt</span></code>;如果不是这样,你将收到报错信息,必须修改此位置)</p>
|
||
<p><a class="reference internal" href="#ssl.PROTOCOL_TLS_CLIENT" title="ssl.PROTOCOL_TLS_CLIENT"><code class="xref py py-data docutils literal notranslate"><span class="pre">PROTOCOL_TLS_CLIENT</span></code></a> 协议配置用于证书验证和主机名验证的上下文。 <a class="reference internal" href="#ssl.SSLContext.verify_mode" title="ssl.SSLContext.verify_mode"><code class="xref py py-attr docutils literal notranslate"><span class="pre">verify_mode</span></code></a> 设为 <a class="reference internal" href="#ssl.CERT_REQUIRED" title="ssl.CERT_REQUIRED"><code class="xref py py-data docutils literal notranslate"><span class="pre">CERT_REQUIRED</span></code></a> 而 <a class="reference internal" href="#ssl.SSLContext.check_hostname" title="ssl.SSLContext.check_hostname"><code class="xref py py-attr docutils literal notranslate"><span class="pre">check_hostname</span></code></a> 设为 <code class="docutils literal notranslate"><span class="pre">True</span></code>。 所有其他协议都会使用不安全的默认值创建 SSL 上下文。</p>
|
||
<p>当你使用此上下文去连接服务器时,<a class="reference internal" href="#ssl.CERT_REQUIRED" title="ssl.CERT_REQUIRED"><code class="xref py py-const docutils literal notranslate"><span class="pre">CERT_REQUIRED</span></code></a> 和 <a class="reference internal" href="#ssl.SSLContext.check_hostname" title="ssl.SSLContext.check_hostname"><code class="xref py py-attr docutils literal notranslate"><span class="pre">check_hostname</span></code></a> 会验证服务器证书;它将确认服务器证书使用了某个 CA 证书进行签名,检查签名是否正确,并验证其他属性例如主机名的有效性和身份真实性:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">conn</span> <span class="o">=</span> <span class="n">context</span><span class="o">.</span><span class="n">wrap_socket</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">socket</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">AF_INET</span><span class="p">),</span>
|
||
<span class="gp">... </span> <span class="n">server_hostname</span><span class="o">=</span><span class="s2">"www.python.org"</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">conn</span><span class="o">.</span><span class="n">connect</span><span class="p">((</span><span class="s2">"www.python.org"</span><span class="p">,</span> <span class="mi">443</span><span class="p">))</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>你可以随后获取该证书:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">cert</span> <span class="o">=</span> <span class="n">conn</span><span class="o">.</span><span class="n">getpeercert</span><span class="p">()</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>可视化检查显示证书能够证明目标服务 (即 HTTPS 主机 <code class="docutils literal notranslate"><span class="pre">www.python.org</span></code>) 的身份:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">pprint</span><span class="o">.</span><span class="n">pprint</span><span class="p">(</span><span class="n">cert</span><span class="p">)</span>
|
||
<span class="go">{'OCSP': ('http://ocsp.digicert.com',),</span>
|
||
<span class="go"> 'caIssuers': ('http://cacerts.digicert.com/DigiCertSHA2ExtendedValidationServerCA.crt',),</span>
|
||
<span class="go"> 'crlDistributionPoints': ('http://crl3.digicert.com/sha2-ev-server-g1.crl',</span>
|
||
<span class="go"> 'http://crl4.digicert.com/sha2-ev-server-g1.crl'),</span>
|
||
<span class="go"> 'issuer': ((('countryName', 'US'),),</span>
|
||
<span class="go"> (('organizationName', 'DigiCert Inc'),),</span>
|
||
<span class="go"> (('organizationalUnitName', 'www.digicert.com'),),</span>
|
||
<span class="go"> (('commonName', 'DigiCert SHA2 Extended Validation Server CA'),)),</span>
|
||
<span class="go"> 'notAfter': 'Sep 9 12:00:00 2016 GMT',</span>
|
||
<span class="go"> 'notBefore': 'Sep 5 00:00:00 2014 GMT',</span>
|
||
<span class="go"> 'serialNumber': '01BB6F00122B177F36CAB49CEA8B6B26',</span>
|
||
<span class="go"> 'subject': ((('businessCategory', 'Private Organization'),),</span>
|
||
<span class="go"> (('1.3.6.1.4.1.311.60.2.1.3', 'US'),),</span>
|
||
<span class="go"> (('1.3.6.1.4.1.311.60.2.1.2', 'Delaware'),),</span>
|
||
<span class="go"> (('serialNumber', '3359300'),),</span>
|
||
<span class="go"> (('streetAddress', '16 Allen Rd'),),</span>
|
||
<span class="go"> (('postalCode', '03894-4801'),),</span>
|
||
<span class="go"> (('countryName', 'US'),),</span>
|
||
<span class="go"> (('stateOrProvinceName', 'NH'),),</span>
|
||
<span class="go"> (('localityName', 'Wolfeboro'),),</span>
|
||
<span class="go"> (('organizationName', 'Python Software Foundation'),),</span>
|
||
<span class="go"> (('commonName', 'www.python.org'),)),</span>
|
||
<span class="go"> 'subjectAltName': (('DNS', 'www.python.org'),</span>
|
||
<span class="go"> ('DNS', 'python.org'),</span>
|
||
<span class="go"> ('DNS', 'pypi.org'),</span>
|
||
<span class="go"> ('DNS', 'docs.python.org'),</span>
|
||
<span class="go"> ('DNS', 'testpypi.org'),</span>
|
||
<span class="go"> ('DNS', 'bugs.python.org'),</span>
|
||
<span class="go"> ('DNS', 'wiki.python.org'),</span>
|
||
<span class="go"> ('DNS', 'hg.python.org'),</span>
|
||
<span class="go"> ('DNS', 'mail.python.org'),</span>
|
||
<span class="go"> ('DNS', 'packaging.python.org'),</span>
|
||
<span class="go"> ('DNS', 'pythonhosted.org'),</span>
|
||
<span class="go"> ('DNS', 'www.pythonhosted.org'),</span>
|
||
<span class="go"> ('DNS', 'test.pythonhosted.org'),</span>
|
||
<span class="go"> ('DNS', 'us.pycon.org'),</span>
|
||
<span class="go"> ('DNS', 'id.python.org')),</span>
|
||
<span class="go"> 'version': 3}</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>现在 SSL 通道已建立并已验证了证书,你可以继续与服务器对话了:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">conn</span><span class="o">.</span><span class="n">sendall</span><span class="p">(</span><span class="sa">b</span><span class="s2">"HEAD / HTTP/1.0</span><span class="se">\r\n</span><span class="s2">Host: linuxfr.org</span><span class="se">\r\n\r\n</span><span class="s2">"</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">pprint</span><span class="o">.</span><span class="n">pprint</span><span class="p">(</span><span class="n">conn</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">1024</span><span class="p">)</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="sa">b</span><span class="s2">"</span><span class="se">\r\n</span><span class="s2">"</span><span class="p">))</span>
|
||
<span class="go">[b'HTTP/1.1 200 OK',</span>
|
||
<span class="go"> b'Date: Sat, 18 Oct 2014 18:27:20 GMT',</span>
|
||
<span class="go"> b'Server: nginx',</span>
|
||
<span class="go"> b'Content-Type: text/html; charset=utf-8',</span>
|
||
<span class="go"> b'X-Frame-Options: SAMEORIGIN',</span>
|
||
<span class="go"> b'Content-Length: 45679',</span>
|
||
<span class="go"> b'Accept-Ranges: bytes',</span>
|
||
<span class="go"> b'Via: 1.1 varnish',</span>
|
||
<span class="go"> b'Age: 2188',</span>
|
||
<span class="go"> b'X-Served-By: cache-lcy1134-LCY',</span>
|
||
<span class="go"> b'X-Cache: HIT',</span>
|
||
<span class="go"> b'X-Cache-Hits: 11',</span>
|
||
<span class="go"> b'Vary: Cookie',</span>
|
||
<span class="go"> b'Strict-Transport-Security: max-age=63072000; includeSubDomains',</span>
|
||
<span class="go"> b'Connection: close',</span>
|
||
<span class="go"> b'',</span>
|
||
<span class="go"> b'']</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>参见下文对于 <a class="reference internal" href="#ssl-security"><span class="std std-ref">安全考量</span></a> 的讨论。</p>
|
||
</section>
|
||
<section id="server-side-operation">
|
||
<h3>服务器端操作<a class="headerlink" href="#server-side-operation" title="永久链接至标题">¶</a></h3>
|
||
<p>对于服务器操作,通常你需要在文件中存放服务器证书和私钥各一份。 你将首先创建一个包含密钥和证书的上下文,这样客户端就能检查你的身份真实性。 然后你将打开一个套接字,将其绑定到一个端口,在其上调用 <code class="xref py py-meth docutils literal notranslate"><span class="pre">listen()</span></code>,并开始等待客户端连接:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">socket</span><span class="o">,</span> <span class="nn">ssl</span>
|
||
|
||
<span class="n">context</span> <span class="o">=</span> <span class="n">ssl</span><span class="o">.</span><span class="n">create_default_context</span><span class="p">(</span><span class="n">ssl</span><span class="o">.</span><span class="n">Purpose</span><span class="o">.</span><span class="n">CLIENT_AUTH</span><span class="p">)</span>
|
||
<span class="n">context</span><span class="o">.</span><span class="n">load_cert_chain</span><span class="p">(</span><span class="n">certfile</span><span class="o">=</span><span class="s2">"mycertfile"</span><span class="p">,</span> <span class="n">keyfile</span><span class="o">=</span><span class="s2">"mykeyfile"</span><span class="p">)</span>
|
||
|
||
<span class="n">bindsocket</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">socket</span><span class="p">()</span>
|
||
<span class="n">bindsocket</span><span class="o">.</span><span class="n">bind</span><span class="p">((</span><span class="s1">'myaddr.mydomain.com'</span><span class="p">,</span> <span class="mi">10023</span><span class="p">))</span>
|
||
<span class="n">bindsocket</span><span class="o">.</span><span class="n">listen</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>当有客户端连接时,你将在套接字上调用 <code class="xref py py-meth docutils literal notranslate"><span class="pre">accept()</span></code> 以从另一端获取新的套接字,并使用上下文的 <a class="reference internal" href="#ssl.SSLContext.wrap_socket" title="ssl.SSLContext.wrap_socket"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLContext.wrap_socket()</span></code></a> 方法来为连接创建一个服务器端 SSL 套接字:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
|
||
<span class="n">newsocket</span><span class="p">,</span> <span class="n">fromaddr</span> <span class="o">=</span> <span class="n">bindsocket</span><span class="o">.</span><span class="n">accept</span><span class="p">()</span>
|
||
<span class="n">connstream</span> <span class="o">=</span> <span class="n">context</span><span class="o">.</span><span class="n">wrap_socket</span><span class="p">(</span><span class="n">newsocket</span><span class="p">,</span> <span class="n">server_side</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
||
<span class="k">try</span><span class="p">:</span>
|
||
<span class="n">deal_with_client</span><span class="p">(</span><span class="n">connstream</span><span class="p">)</span>
|
||
<span class="k">finally</span><span class="p">:</span>
|
||
<span class="n">connstream</span><span class="o">.</span><span class="n">shutdown</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">SHUT_RDWR</span><span class="p">)</span>
|
||
<span class="n">connstream</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>随后你将从 <code class="docutils literal notranslate"><span class="pre">connstream</span></code> 读取数据并对其进行处理,直至你结束与客户端的会话(或客户端结束与你的会话):</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">deal_with_client</span><span class="p">(</span><span class="n">connstream</span><span class="p">):</span>
|
||
<span class="n">data</span> <span class="o">=</span> <span class="n">connstream</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">1024</span><span class="p">)</span>
|
||
<span class="c1"># empty data means the client is finished with us</span>
|
||
<span class="k">while</span> <span class="n">data</span><span class="p">:</span>
|
||
<span class="k">if</span> <span class="ow">not</span> <span class="n">do_something</span><span class="p">(</span><span class="n">connstream</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
|
||
<span class="c1"># we'll assume do_something returns False</span>
|
||
<span class="c1"># when we're finished with client</span>
|
||
<span class="k">break</span>
|
||
<span class="n">data</span> <span class="o">=</span> <span class="n">connstream</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">1024</span><span class="p">)</span>
|
||
<span class="c1"># finished with client</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>并返回至监听新的客户端连接(当然,真正的服务器应当会在单独的线程中处理每个客户端连接,或者将套接字设为 <a class="reference internal" href="#ssl-nonblocking"><span class="std std-ref">非阻塞模式</span></a> 并使用事件循环)。</p>
|
||
</section>
|
||
</section>
|
||
<section id="notes-on-non-blocking-sockets">
|
||
<span id="ssl-nonblocking"></span><h2>关于非阻塞套接字的说明<a class="headerlink" href="#notes-on-non-blocking-sockets" title="永久链接至标题">¶</a></h2>
|
||
<p>在非阻塞模式下 SSL 套接字的行为与常规套接字略有不同。 当使用非阻塞模式时,你需要注意下面这些事情:</p>
|
||
<ul>
|
||
<li><p>如果一个 I/O 操作会阻塞,大多数 <a class="reference internal" href="#ssl.SSLSocket" title="ssl.SSLSocket"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLSocket</span></code></a> 方法都将引发 <a class="reference internal" href="#ssl.SSLWantWriteError" title="ssl.SSLWantWriteError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SSLWantWriteError</span></code></a> 或 <a class="reference internal" href="#ssl.SSLWantReadError" title="ssl.SSLWantReadError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SSLWantReadError</span></code></a> 而非 <a class="reference internal" href="exceptions.html#BlockingIOError" title="BlockingIOError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">BlockingIOError</span></code></a>。 如果有必要在下层套接字上执行读取操作将引发 <a class="reference internal" href="#ssl.SSLWantReadError" title="ssl.SSLWantReadError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SSLWantReadError</span></code></a>,在下层套接字上执行写入操作则将引发 <a class="reference internal" href="#ssl.SSLWantWriteError" title="ssl.SSLWantWriteError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SSLWantWriteError</span></code></a>。 请注意尝试 <em>写入</em> 到 SSL 套接字可能需要先从下层套接字 <em>读取</em>,而尝试从 SSL 套接字 <em>读取</em> 则可能需要先向下层套接字 <em>写入</em>。</p>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.5 版更改: </span>在较早的 Python 版本中,<code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLSocket.send()</span></code> 方法会返回零值而非引发 <a class="reference internal" href="#ssl.SSLWantWriteError" title="ssl.SSLWantWriteError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SSLWantWriteError</span></code></a> 或 <a class="reference internal" href="#ssl.SSLWantReadError" title="ssl.SSLWantReadError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SSLWantReadError</span></code></a>。</p>
|
||
</div>
|
||
</li>
|
||
<li><p>调用 <a class="reference internal" href="select.html#select.select" title="select.select"><code class="xref py py-func docutils literal notranslate"><span class="pre">select()</span></code></a> 将告诉你可以从 OS 层级的套接字读取(或向其写入),但这并不意味着在上面的 SSL 层有足够的数据。 例如,可能只有部分 SSL 帧已经到达。 因此,你必须准备好处理 <code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLSocket.recv()</span></code> 和 <code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLSocket.send()</span></code> 失败的情况,并在再次调用 <a class="reference internal" href="select.html#select.select" title="select.select"><code class="xref py py-func docutils literal notranslate"><span class="pre">select()</span></code></a> 之后重新尝试。</p></li>
|
||
<li><p>相反地,由于 SSL 层具有自己的帧机制,一个 SSL 套接字可能仍有可读取的数据而 <a class="reference internal" href="select.html#select.select" title="select.select"><code class="xref py py-func docutils literal notranslate"><span class="pre">select()</span></code></a> 并不知道这一点。 因此,你应当先调用 <code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLSocket.recv()</span></code> 取走所有潜在的可用数据,然后只在必要时对 <a class="reference internal" href="select.html#select.select" title="select.select"><code class="xref py py-func docutils literal notranslate"><span class="pre">select()</span></code></a> 调用执行阻塞。</p>
|
||
<p>(当然,类似的保留规则在使用其他原语例如 <a class="reference internal" href="select.html#select.poll" title="select.poll"><code class="xref py py-func docutils literal notranslate"><span class="pre">poll()</span></code></a>,或 <a class="reference internal" href="selectors.html#module-selectors" title="selectors: High-level I/O multiplexing."><code class="xref py py-mod docutils literal notranslate"><span class="pre">selectors</span></code></a> 模块中的原语时也适用)</p>
|
||
</li>
|
||
<li><p>SSL 握手本身将是非阻塞的: <a class="reference internal" href="#ssl.SSLSocket.do_handshake" title="ssl.SSLSocket.do_handshake"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLSocket.do_handshake()</span></code></a> 方法必须不断重试直至其成功返回。 下面是一个使用 <a class="reference internal" href="select.html#select.select" title="select.select"><code class="xref py py-func docutils literal notranslate"><span class="pre">select()</span></code></a> 来等待套接字就绪的简短例子:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
|
||
<span class="k">try</span><span class="p">:</span>
|
||
<span class="n">sock</span><span class="o">.</span><span class="n">do_handshake</span><span class="p">()</span>
|
||
<span class="k">break</span>
|
||
<span class="k">except</span> <span class="n">ssl</span><span class="o">.</span><span class="n">SSLWantReadError</span><span class="p">:</span>
|
||
<span class="n">select</span><span class="o">.</span><span class="n">select</span><span class="p">([</span><span class="n">sock</span><span class="p">],</span> <span class="p">[],</span> <span class="p">[])</span>
|
||
<span class="k">except</span> <span class="n">ssl</span><span class="o">.</span><span class="n">SSLWantWriteError</span><span class="p">:</span>
|
||
<span class="n">select</span><span class="o">.</span><span class="n">select</span><span class="p">([],</span> <span class="p">[</span><span class="n">sock</span><span class="p">],</span> <span class="p">[])</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
<div class="admonition seealso">
|
||
<p class="admonition-title">参见</p>
|
||
<p><a class="reference internal" href="asyncio.html#module-asyncio" title="asyncio: Asynchronous I/O."><code class="xref py py-mod docutils literal notranslate"><span class="pre">asyncio</span></code></a> 模块支持 <a class="reference internal" href="#ssl-nonblocking"><span class="std std-ref">非阻塞 SSL 套接字</span></a> 并提供了更高层级的 API。 它会使用 <a class="reference internal" href="selectors.html#module-selectors" title="selectors: High-level I/O multiplexing."><code class="xref py py-mod docutils literal notranslate"><span class="pre">selectors</span></code></a> 模块来轮询事件并处理 <a class="reference internal" href="#ssl.SSLWantWriteError" title="ssl.SSLWantWriteError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SSLWantWriteError</span></code></a>, <a class="reference internal" href="#ssl.SSLWantReadError" title="ssl.SSLWantReadError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SSLWantReadError</span></code></a> 和 <a class="reference internal" href="exceptions.html#BlockingIOError" title="BlockingIOError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">BlockingIOError</span></code></a> 等异常。 它还会异步地执行 SSL 握手。</p>
|
||
</div>
|
||
</section>
|
||
<section id="memory-bio-support">
|
||
<h2>内存 BIO 支持<a class="headerlink" href="#memory-bio-support" title="永久链接至标题">¶</a></h2>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.5 新版功能.</span></p>
|
||
</div>
|
||
<p>自从 SSL 模块在 Python 2.6 起被引入之后,<a class="reference internal" href="#ssl.SSLSocket" title="ssl.SSLSocket"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLSocket</span></code></a> 类提供了两个互相关联但彼此独立的功能分块:</p>
|
||
<ul class="simple">
|
||
<li><p>SSL 协议处理</p></li>
|
||
<li><p>网络 IO</p></li>
|
||
</ul>
|
||
<p>网络 IO API 与 <a class="reference internal" href="socket.html#socket.socket" title="socket.socket"><code class="xref py py-class docutils literal notranslate"><span class="pre">socket.socket</span></code></a> 所提供的功能一致,<a class="reference internal" href="#ssl.SSLSocket" title="ssl.SSLSocket"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLSocket</span></code></a> 也是从那里继承而来的。 这允许 SSL 套接字被用作常规套接字的替代,使得向现有应用程序添加 SSL 支持变得非常容易。</p>
|
||
<p>将 SSL 协议处理与网络 IO 结合使用通常都能运行良好,但在某些情况下则不能。 此情况的一个例子是 async IO 框架,该框架要使用不同的 IO 多路复用模型而非 (基于就绪状态的) "在文件描述器上执行选择/轮询" 模型,该模型是 <a class="reference internal" href="socket.html#socket.socket" title="socket.socket"><code class="xref py py-class docutils literal notranslate"><span class="pre">socket.socket</span></code></a> 和内部 OpenSSL 套接字 IO 例程正常运行的假设前提。 这种情况在该模型效率不高的 Windows 平台上最为常见。 为此还提供了一个 <a class="reference internal" href="#ssl.SSLSocket" title="ssl.SSLSocket"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLSocket</span></code></a> 的简化形式,称为 <a class="reference internal" href="#ssl.SSLObject" title="ssl.SSLObject"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLObject</span></code></a>。</p>
|
||
<dl class="class">
|
||
<dt id="ssl.SSLObject">
|
||
<em class="property">class </em><code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">SSLObject</code><a class="headerlink" href="#ssl.SSLObject" title="永久链接至目标">¶</a></dt>
|
||
<dd><p><a class="reference internal" href="#ssl.SSLSocket" title="ssl.SSLSocket"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLSocket</span></code></a> 的简化形式,表示一个不包含任何网络 IO 方法的 SSL 协议实例。 这个类通常由想要通过内存缓冲区为 SSL 实现异步 IO 的框架作者来使用。</p>
|
||
<p>这个类在低层级 SSL 对象上实现了一个接口,与 OpenSSL 所实现的类似。 此对象会捕获 SSL 连接的状态但其本身不提供任何网络 IO。 IO 需要通过单独的 "BIO" 对象来执行,该对象是 OpenSSL 的 IO 抽象层。</p>
|
||
<p>这个类没有公有构造器。 <a class="reference internal" href="#ssl.SSLObject" title="ssl.SSLObject"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLObject</span></code></a> 实例必须使用 <a class="reference internal" href="#ssl.SSLContext.wrap_bio" title="ssl.SSLContext.wrap_bio"><code class="xref py py-meth docutils literal notranslate"><span class="pre">wrap_bio()</span></code></a> 方法来创建。 此方法将创建 <a class="reference internal" href="#ssl.SSLObject" title="ssl.SSLObject"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLObject</span></code></a> 实例并将其绑定到一个 BIO 对。 其中 <em>incoming</em> BIO 用来将数据从 Python 传递到 SSL 协议实例,而 <em>outgoing</em> BIO 用来进行数据反向传递。</p>
|
||
<p>可以使用以下方法:</p>
|
||
<ul class="simple">
|
||
<li><p><a class="reference internal" href="#ssl.SSLSocket.context" title="ssl.SSLSocket.context"><code class="xref py py-attr docutils literal notranslate"><span class="pre">context</span></code></a></p></li>
|
||
<li><p><a class="reference internal" href="#ssl.SSLSocket.server_side" title="ssl.SSLSocket.server_side"><code class="xref py py-attr docutils literal notranslate"><span class="pre">server_side</span></code></a></p></li>
|
||
<li><p><a class="reference internal" href="#ssl.SSLSocket.server_hostname" title="ssl.SSLSocket.server_hostname"><code class="xref py py-attr docutils literal notranslate"><span class="pre">server_hostname</span></code></a></p></li>
|
||
<li><p><a class="reference internal" href="#ssl.SSLSocket.session" title="ssl.SSLSocket.session"><code class="xref py py-attr docutils literal notranslate"><span class="pre">session</span></code></a></p></li>
|
||
<li><p><a class="reference internal" href="#ssl.SSLSocket.session_reused" title="ssl.SSLSocket.session_reused"><code class="xref py py-attr docutils literal notranslate"><span class="pre">session_reused</span></code></a></p></li>
|
||
<li><p><a class="reference internal" href="#ssl.SSLSocket.read" title="ssl.SSLSocket.read"><code class="xref py py-meth docutils literal notranslate"><span class="pre">read()</span></code></a></p></li>
|
||
<li><p><a class="reference internal" href="#ssl.SSLSocket.write" title="ssl.SSLSocket.write"><code class="xref py py-meth docutils literal notranslate"><span class="pre">write()</span></code></a></p></li>
|
||
<li><p><a class="reference internal" href="#ssl.SSLSocket.getpeercert" title="ssl.SSLSocket.getpeercert"><code class="xref py py-meth docutils literal notranslate"><span class="pre">getpeercert()</span></code></a></p></li>
|
||
<li><p><a class="reference internal" href="#ssl.SSLSocket.selected_alpn_protocol" title="ssl.SSLSocket.selected_alpn_protocol"><code class="xref py py-meth docutils literal notranslate"><span class="pre">selected_alpn_protocol()</span></code></a></p></li>
|
||
<li><p><a class="reference internal" href="#ssl.SSLSocket.selected_npn_protocol" title="ssl.SSLSocket.selected_npn_protocol"><code class="xref py py-meth docutils literal notranslate"><span class="pre">selected_npn_protocol()</span></code></a></p></li>
|
||
<li><p><a class="reference internal" href="#ssl.SSLSocket.cipher" title="ssl.SSLSocket.cipher"><code class="xref py py-meth docutils literal notranslate"><span class="pre">cipher()</span></code></a></p></li>
|
||
<li><p><a class="reference internal" href="#ssl.SSLSocket.shared_ciphers" title="ssl.SSLSocket.shared_ciphers"><code class="xref py py-meth docutils literal notranslate"><span class="pre">shared_ciphers()</span></code></a></p></li>
|
||
<li><p><a class="reference internal" href="#ssl.SSLSocket.compression" title="ssl.SSLSocket.compression"><code class="xref py py-meth docutils literal notranslate"><span class="pre">compression()</span></code></a></p></li>
|
||
<li><p><a class="reference internal" href="#ssl.SSLSocket.pending" title="ssl.SSLSocket.pending"><code class="xref py py-meth docutils literal notranslate"><span class="pre">pending()</span></code></a></p></li>
|
||
<li><p><a class="reference internal" href="#ssl.SSLSocket.do_handshake" title="ssl.SSLSocket.do_handshake"><code class="xref py py-meth docutils literal notranslate"><span class="pre">do_handshake()</span></code></a></p></li>
|
||
<li><p><a class="reference internal" href="#ssl.SSLSocket.verify_client_post_handshake" title="ssl.SSLSocket.verify_client_post_handshake"><code class="xref py py-meth docutils literal notranslate"><span class="pre">verify_client_post_handshake()</span></code></a></p></li>
|
||
<li><p><a class="reference internal" href="#ssl.SSLSocket.unwrap" title="ssl.SSLSocket.unwrap"><code class="xref py py-meth docutils literal notranslate"><span class="pre">unwrap()</span></code></a></p></li>
|
||
<li><p><a class="reference internal" href="#ssl.SSLSocket.get_channel_binding" title="ssl.SSLSocket.get_channel_binding"><code class="xref py py-meth docutils literal notranslate"><span class="pre">get_channel_binding()</span></code></a></p></li>
|
||
<li><p><a class="reference internal" href="#ssl.SSLSocket.version" title="ssl.SSLSocket.version"><code class="xref py py-meth docutils literal notranslate"><span class="pre">version()</span></code></a></p></li>
|
||
</ul>
|
||
<p>与 <a class="reference internal" href="#ssl.SSLSocket" title="ssl.SSLSocket"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLSocket</span></code></a> 相比,此对象缺少下列特性:</p>
|
||
<ul class="simple">
|
||
<li><p>任何形式的网络 IO; <code class="docutils literal notranslate"><span class="pre">recv()</span></code> 和 <code class="docutils literal notranslate"><span class="pre">send()</span></code> 仅对下层的 <a class="reference internal" href="#ssl.MemoryBIO" title="ssl.MemoryBIO"><code class="xref py py-class docutils literal notranslate"><span class="pre">MemoryBIO</span></code></a> 缓冲区执行读取和写入。</p></li>
|
||
<li><p>不存在 <em>do_handshake_on_connect</em> 机制。 你必须总是手动调用 <a class="reference internal" href="#ssl.SSLSocket.do_handshake" title="ssl.SSLSocket.do_handshake"><code class="xref py py-meth docutils literal notranslate"><span class="pre">do_handshake()</span></code></a> 来开始握手操作。</p></li>
|
||
<li><p>不存在对 <em>suppress_ragged_eofs</em> 的处理。 所有违反协议的文件结束条件将通过 <a class="reference internal" href="#ssl.SSLEOFError" title="ssl.SSLEOFError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SSLEOFError</span></code></a> 异常来报告。</p></li>
|
||
<li><p>方法 <a class="reference internal" href="#ssl.SSLSocket.unwrap" title="ssl.SSLSocket.unwrap"><code class="xref py py-meth docutils literal notranslate"><span class="pre">unwrap()</span></code></a> 的调用不返回任何东西,不会如 SSL 套接字那样返回下层的套接字。</p></li>
|
||
<li><p><em>server_name_callback</em> 回调被传给 <a class="reference internal" href="#ssl.SSLContext.set_servername_callback" title="ssl.SSLContext.set_servername_callback"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLContext.set_servername_callback()</span></code></a> 时将获得一个 <a class="reference internal" href="#ssl.SSLObject" title="ssl.SSLObject"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLObject</span></code></a> 实例而非 <a class="reference internal" href="#ssl.SSLSocket" title="ssl.SSLSocket"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLSocket</span></code></a> 实例作为其第一个形参。</p></li>
|
||
</ul>
|
||
<p>有关 <a class="reference internal" href="#ssl.SSLObject" title="ssl.SSLObject"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLObject</span></code></a> 用法的一些说明:</p>
|
||
<ul class="simple">
|
||
<li><p>在 <a class="reference internal" href="#ssl.SSLObject" title="ssl.SSLObject"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLObject</span></code></a> 上的所有 IO 都是 <a class="reference internal" href="#ssl-nonblocking"><span class="std std-ref">非阻塞的</span></a>。 这意味着例如 <a class="reference internal" href="#ssl.SSLSocket.read" title="ssl.SSLSocket.read"><code class="xref py py-meth docutils literal notranslate"><span class="pre">read()</span></code></a> 在其需要比 incoming BIO 可用的更多数据时将会引发 <a class="reference internal" href="#ssl.SSLWantReadError" title="ssl.SSLWantReadError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SSLWantReadError</span></code></a>。</p></li>
|
||
<li><p>不存在模块层级的 <code class="docutils literal notranslate"><span class="pre">wrap_bio()</span></code> 调用,就像 <a class="reference internal" href="#ssl.SSLContext.wrap_socket" title="ssl.SSLContext.wrap_socket"><code class="xref py py-meth docutils literal notranslate"><span class="pre">wrap_socket()</span></code></a> 那样。 <a class="reference internal" href="#ssl.SSLObject" title="ssl.SSLObject"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLObject</span></code></a> 总是通过 <a class="reference internal" href="#ssl.SSLContext" title="ssl.SSLContext"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLContext</span></code></a> 来创建。</p></li>
|
||
</ul>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.7 版更改: </span><a class="reference internal" href="#ssl.SSLObject" title="ssl.SSLObject"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLObject</span></code></a> 的实例必须使用 <a class="reference internal" href="#ssl.SSLContext.wrap_bio" title="ssl.SSLContext.wrap_bio"><code class="xref py py-meth docutils literal notranslate"><span class="pre">wrap_bio()</span></code></a> 来创建。 在较早的版本中,直接创建实例是可能的。 但这从未被记入文档或是被正式支持。</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<p>SSLObject 会使用内存缓冲区与外部世界通信。 <a class="reference internal" href="#ssl.MemoryBIO" title="ssl.MemoryBIO"><code class="xref py py-class docutils literal notranslate"><span class="pre">MemoryBIO</span></code></a> 类提供了可被用于此目的的内存缓冲区。 它包装了一个 OpenSSL 内存 BIO (Basic IO) 对象:</p>
|
||
<dl class="class">
|
||
<dt id="ssl.MemoryBIO">
|
||
<em class="property">class </em><code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">MemoryBIO</code><a class="headerlink" href="#ssl.MemoryBIO" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>一个可被用来在 Python 和 SSL 协议实例之间传递数据的内存缓冲区。</p>
|
||
<dl class="attribute">
|
||
<dt id="ssl.MemoryBIO.pending">
|
||
<code class="sig-name descname">pending</code><a class="headerlink" href="#ssl.MemoryBIO.pending" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>返回当前存在于内存缓冲区的字节数。</p>
|
||
</dd></dl>
|
||
|
||
<dl class="attribute">
|
||
<dt id="ssl.MemoryBIO.eof">
|
||
<code class="sig-name descname">eof</code><a class="headerlink" href="#ssl.MemoryBIO.eof" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>一个表明内存 BIO 目前是否位于文件末尾的布尔值。</p>
|
||
</dd></dl>
|
||
|
||
<dl class="method">
|
||
<dt id="ssl.MemoryBIO.read">
|
||
<code class="sig-name descname">read</code><span class="sig-paren">(</span><em class="sig-param">n=-1</em><span class="sig-paren">)</span><a class="headerlink" href="#ssl.MemoryBIO.read" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>从内存缓冲区读取至多 <em>n</em> 个字节。 如果 <em>n</em> 未指定或为负值,则返回全部字节数据。</p>
|
||
</dd></dl>
|
||
|
||
<dl class="method">
|
||
<dt id="ssl.MemoryBIO.write">
|
||
<code class="sig-name descname">write</code><span class="sig-paren">(</span><em class="sig-param">buf</em><span class="sig-paren">)</span><a class="headerlink" href="#ssl.MemoryBIO.write" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>将字节数据从 <em>buf</em> 写入到内存 BIO。 <em>buf</em> 参数必须为支持缓冲区协议的对象。</p>
|
||
<p>返回值为写入的字节数,它总是与 <em>buf</em> 的长度相等。</p>
|
||
</dd></dl>
|
||
|
||
<dl class="method">
|
||
<dt id="ssl.MemoryBIO.write_eof">
|
||
<code class="sig-name descname">write_eof</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#ssl.MemoryBIO.write_eof" title="永久链接至目标">¶</a></dt>
|
||
<dd><p>将一个 EOF 标记写入到内存 BIO。 在此方法被调用以后,再调用 <a class="reference internal" href="#ssl.MemoryBIO.write" title="ssl.MemoryBIO.write"><code class="xref py py-meth docutils literal notranslate"><span class="pre">write()</span></code></a> 将是非法的。 属性 <a class="reference internal" href="#ssl.MemoryBIO.eof" title="ssl.MemoryBIO.eof"><code class="xref py py-attr docutils literal notranslate"><span class="pre">eof</span></code></a> will 在缓冲区当前的所有数据都被读取之后将变为真值。</p>
|
||
</dd></dl>
|
||
|
||
</dd></dl>
|
||
|
||
</section>
|
||
<section id="ssl-session">
|
||
<h2>SSL 会话<a class="headerlink" href="#ssl-session" title="永久链接至标题">¶</a></h2>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.6 新版功能.</span></p>
|
||
</div>
|
||
<dl class="class">
|
||
<dt id="ssl.SSLSession">
|
||
<em class="property">class </em><code class="sig-prename descclassname">ssl.</code><code class="sig-name descname">SSLSession</code><a class="headerlink" href="#ssl.SSLSession" title="永久链接至目标">¶</a></dt>
|
||
<dd><p><a class="reference internal" href="#ssl.SSLSocket.session" title="ssl.SSLSocket.session"><code class="xref py py-attr docutils literal notranslate"><span class="pre">session</span></code></a> 所使用的会话对象。</p>
|
||
<dl class="attribute">
|
||
<dt id="ssl.SSLSession.id">
|
||
<code class="sig-name descname">id</code><a class="headerlink" href="#ssl.SSLSession.id" title="永久链接至目标">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
<dl class="attribute">
|
||
<dt id="ssl.SSLSession.time">
|
||
<code class="sig-name descname">time</code><a class="headerlink" href="#ssl.SSLSession.time" title="永久链接至目标">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
<dl class="attribute">
|
||
<dt id="ssl.SSLSession.timeout">
|
||
<code class="sig-name descname">timeout</code><a class="headerlink" href="#ssl.SSLSession.timeout" title="永久链接至目标">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
<dl class="attribute">
|
||
<dt id="ssl.SSLSession.ticket_lifetime_hint">
|
||
<code class="sig-name descname">ticket_lifetime_hint</code><a class="headerlink" href="#ssl.SSLSession.ticket_lifetime_hint" title="永久链接至目标">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
<dl class="attribute">
|
||
<dt id="ssl.SSLSession.has_ticket">
|
||
<code class="sig-name descname">has_ticket</code><a class="headerlink" href="#ssl.SSLSession.has_ticket" title="永久链接至目标">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
</dd></dl>
|
||
|
||
</section>
|
||
<section id="security-considerations">
|
||
<span id="ssl-security"></span><h2>安全考量<a class="headerlink" href="#security-considerations" title="永久链接至标题">¶</a></h2>
|
||
<section id="best-defaults">
|
||
<h3>最佳默认值<a class="headerlink" href="#best-defaults" title="永久链接至标题">¶</a></h3>
|
||
<p>针对 <strong>客户端使用</strong>,如果你对于安全策略没有任何特殊要求,则强烈推荐你使用 <a class="reference internal" href="#ssl.create_default_context" title="ssl.create_default_context"><code class="xref py py-func docutils literal notranslate"><span class="pre">create_default_context()</span></code></a> 函数来创建你的 SSL 上下文。 它将加载系统的受信任 CA 证书,启用证书验证和主机名检查,并尝试合理地选择安全的协议和密码设置。</p>
|
||
<p>例如,以下演示了你应当如何使用 <a class="reference internal" href="smtplib.html#smtplib.SMTP" title="smtplib.SMTP"><code class="xref py py-class docutils literal notranslate"><span class="pre">smtplib.SMTP</span></code></a> 类来创建指向一个 SMTP 服务器的受信任且安全的连接:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">import</span> <span class="nn">ssl</span><span class="o">,</span> <span class="nn">smtplib</span>
|
||
<span class="gp">>>> </span><span class="n">smtp</span> <span class="o">=</span> <span class="n">smtplib</span><span class="o">.</span><span class="n">SMTP</span><span class="p">(</span><span class="s2">"mail.python.org"</span><span class="p">,</span> <span class="n">port</span><span class="o">=</span><span class="mi">587</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">context</span> <span class="o">=</span> <span class="n">ssl</span><span class="o">.</span><span class="n">create_default_context</span><span class="p">()</span>
|
||
<span class="gp">>>> </span><span class="n">smtp</span><span class="o">.</span><span class="n">starttls</span><span class="p">(</span><span class="n">context</span><span class="o">=</span><span class="n">context</span><span class="p">)</span>
|
||
<span class="go">(220, b'2.0.0 Ready to start TLS')</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>如果连接需要客户端证书,可使用 <a class="reference internal" href="#ssl.SSLContext.load_cert_chain" title="ssl.SSLContext.load_cert_chain"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLContext.load_cert_chain()</span></code></a> 来添加。</p>
|
||
<p>作为对比,如果你通过自行调用 <a class="reference internal" href="#ssl.SSLContext" title="ssl.SSLContext"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLContext</span></code></a> 构造器来创建 SSL 上下文,它默认将不会启用证书验证和主机名检查。 如果你这样做,请阅读下面的段落以达到良好的安全级别。</p>
|
||
</section>
|
||
<section id="manual-settings">
|
||
<h3>手动设置<a class="headerlink" href="#manual-settings" title="永久链接至标题">¶</a></h3>
|
||
<section id="verifying-certificates">
|
||
<h4>验证证书<a class="headerlink" href="#verifying-certificates" title="永久链接至标题">¶</a></h4>
|
||
<p>当直接调用 <a class="reference internal" href="#ssl.SSLContext" title="ssl.SSLContext"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLContext</span></code></a> 构造器时,默认会使用 <a class="reference internal" href="#ssl.CERT_NONE" title="ssl.CERT_NONE"><code class="xref py py-const docutils literal notranslate"><span class="pre">CERT_NONE</span></code></a>。 由于它不会验证对等方的身份真实性,因此是不安全的,特别是在客户端模式下,大多数时候你都希望能保证你所连接的服务器的身份真实性。 因此,当处于客户端模式时,强烈推荐使用 <a class="reference internal" href="#ssl.CERT_REQUIRED" title="ssl.CERT_REQUIRED"><code class="xref py py-const docutils literal notranslate"><span class="pre">CERT_REQUIRED</span></code></a>。 但是,光这样还不够;你还必须检查服务器证书,这可以通过调用 <a class="reference internal" href="#ssl.SSLSocket.getpeercert" title="ssl.SSLSocket.getpeercert"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLSocket.getpeercert()</span></code></a> 来获取并匹配目标服务。 对于许多协议和应用来说,服务可通过主机名来标识;在此情况下,可以使用 <a class="reference internal" href="#ssl.match_hostname" title="ssl.match_hostname"><code class="xref py py-func docutils literal notranslate"><span class="pre">match_hostname()</span></code></a> 函数。 这种通用检测会在 <a class="reference internal" href="#ssl.SSLContext.check_hostname" title="ssl.SSLContext.check_hostname"><code class="xref py py-attr docutils literal notranslate"><span class="pre">SSLContext.check_hostname</span></code></a> 被启用时自动执行。</p>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">在 3.7 版更改: </span>主机名匹配现在是由 OpenSSL 来执行的。 Python 不会再使用 <a class="reference internal" href="#ssl.match_hostname" title="ssl.match_hostname"><code class="xref py py-func docutils literal notranslate"><span class="pre">match_hostname()</span></code></a>。</p>
|
||
</div>
|
||
<p>在服务器模式下,如果你想要使用 SSL 层来验证客户端(而不是使用更高层级的验证机制),你也必须要指定 <a class="reference internal" href="#ssl.CERT_REQUIRED" title="ssl.CERT_REQUIRED"><code class="xref py py-const docutils literal notranslate"><span class="pre">CERT_REQUIRED</span></code></a> 并以类似方式检查客户端证书。</p>
|
||
</section>
|
||
<section id="protocol-versions">
|
||
<h4>协议版本<a class="headerlink" href="#protocol-versions" title="永久链接至标题">¶</a></h4>
|
||
<p>SSL 版本 2 和 3 被认为是不安全的因而使用它们会有风险。 如果你想要客户端和服务器之间有最大的兼容性,推荐使用 <a class="reference internal" href="#ssl.PROTOCOL_TLS_CLIENT" title="ssl.PROTOCOL_TLS_CLIENT"><code class="xref py py-const docutils literal notranslate"><span class="pre">PROTOCOL_TLS_CLIENT</span></code></a> 或 <a class="reference internal" href="#ssl.PROTOCOL_TLS_SERVER" title="ssl.PROTOCOL_TLS_SERVER"><code class="xref py py-const docutils literal notranslate"><span class="pre">PROTOCOL_TLS_SERVER</span></code></a> 作为协议版本。 SSLv2 和 SSLv3 默认会被禁用。</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">client_context</span> <span class="o">=</span> <span class="n">ssl</span><span class="o">.</span><span class="n">SSLContext</span><span class="p">(</span><span class="n">ssl</span><span class="o">.</span><span class="n">PROTOCOL_TLS_CLIENT</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">client_context</span><span class="o">.</span><span class="n">options</span> <span class="o">|=</span> <span class="n">ssl</span><span class="o">.</span><span class="n">OP_NO_TLSv1</span>
|
||
<span class="gp">>>> </span><span class="n">client_context</span><span class="o">.</span><span class="n">options</span> <span class="o">|=</span> <span class="n">ssl</span><span class="o">.</span><span class="n">OP_NO_TLSv1_1</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>前面创建的 SSL 上下文将只允许 TLSv1.2 及更新版本(如果你的系统支持)的服务器连接。 <a class="reference internal" href="#ssl.PROTOCOL_TLS_CLIENT" title="ssl.PROTOCOL_TLS_CLIENT"><code class="xref py py-const docutils literal notranslate"><span class="pre">PROTOCOL_TLS_CLIENT</span></code></a> 默认会使用证书验证和主机名检查。 你必须将证书加载到上下文中。</p>
|
||
</section>
|
||
<section id="cipher-selection">
|
||
<h4>密码选择<a class="headerlink" href="#cipher-selection" title="永久链接至标题">¶</a></h4>
|
||
<p>如果你有更高级的安全要求,也可以通过 <a class="reference internal" href="#ssl.SSLContext.set_ciphers" title="ssl.SSLContext.set_ciphers"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLContext.set_ciphers()</span></code></a> 方法在协商 SSL 会话时对所启用的加密进行微调。 从 Python 3.2.3 开始,ssl 默认会禁用某些较弱的加密,但你还可能希望进一步限制加密选项。 请确保仔细阅读 OpenSSL 文档中有关 <a class="reference external" href="https://www.openssl.org/docs/manmaster/man1/ciphers.html#CIPHER-LIST-FORMAT">加密列表格式</a> 的部分。 如果你想要检查给定的加密列表启用了哪些加密,可以使用 <a class="reference internal" href="#ssl.SSLContext.get_ciphers" title="ssl.SSLContext.get_ciphers"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLContext.get_ciphers()</span></code></a> 或所在系统的 <code class="docutils literal notranslate"><span class="pre">openssl</span> <span class="pre">ciphers</span></code> 命令。</p>
|
||
</section>
|
||
</section>
|
||
<section id="multi-processing">
|
||
<h3>多进程<a class="headerlink" href="#multi-processing" title="永久链接至标题">¶</a></h3>
|
||
<p>如果使用此模块作为多进程应用的一部分(例如使用 <a class="reference internal" href="multiprocessing.html#module-multiprocessing" title="multiprocessing: Process-based parallelism."><code class="xref py py-mod docutils literal notranslate"><span class="pre">multiprocessing</span></code></a> 或 <a class="reference internal" href="concurrent.futures.html#module-concurrent.futures" title="concurrent.futures: Execute computations concurrently using threads or processes."><code class="xref py py-mod docutils literal notranslate"><span class="pre">concurrent.futures</span></code></a> 模块),请注意 OpenSSL 的内部随机数字生成器并不能正确处理分支进程。 应用程序必须修改父进程的 PRNG 状态,如果它们要使用任何包含 <a class="reference internal" href="os.html#os.fork" title="os.fork"><code class="xref py py-func docutils literal notranslate"><span class="pre">os.fork()</span></code></a> 的 SSL 特性的话。 任何对 <a class="reference internal" href="#ssl.RAND_add" title="ssl.RAND_add"><code class="xref py py-func docutils literal notranslate"><span class="pre">RAND_add()</span></code></a>, <a class="reference internal" href="#ssl.RAND_bytes" title="ssl.RAND_bytes"><code class="xref py py-func docutils literal notranslate"><span class="pre">RAND_bytes()</span></code></a> 或 <a class="reference internal" href="#ssl.RAND_pseudo_bytes" title="ssl.RAND_pseudo_bytes"><code class="xref py py-func docutils literal notranslate"><span class="pre">RAND_pseudo_bytes()</span></code></a> 都可以 做到这一点。</p>
|
||
</section>
|
||
</section>
|
||
<section id="tls-1-3">
|
||
<span id="ssl-tlsv1-3"></span><h2>TLS 1.3<a class="headerlink" href="#tls-1-3" title="永久链接至标题">¶</a></h2>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">3.7 新版功能.</span></p>
|
||
</div>
|
||
<p>Python 通过 OpenSSL 1.1.1 提供了临时性和实验性的 TLS 1.3 支持。 这个新协议的行为与之前版本的 TLS/SSL 略有不同。 某些新的 TLS 1.3 特性暂时还不可用。</p>
|
||
<ul class="simple">
|
||
<li><p>TLS 1.3 使用一组不同的加密套件集。 默认情况下所有 AES-GCM 和 ChaCha20 加密套件都会被启用。 <a class="reference internal" href="#ssl.SSLContext.set_ciphers" title="ssl.SSLContext.set_ciphers"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLContext.set_ciphers()</span></code></a> 方法还不能启用或禁用任何 TLS 1.3 加密,但 <a class="reference internal" href="#ssl.SSLContext.get_ciphers" title="ssl.SSLContext.get_ciphers"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLContext.get_ciphers()</span></code></a> 会返回它们。</p></li>
|
||
<li><p>会话凭据不再会作为初始握手的组成部分被发送而是以不同的方式来处理。 <a class="reference internal" href="#ssl.SSLSocket.session" title="ssl.SSLSocket.session"><code class="xref py py-attr docutils literal notranslate"><span class="pre">SSLSocket.session</span></code></a> 和 <a class="reference internal" href="#ssl.SSLSession" title="ssl.SSLSession"><code class="xref py py-class docutils literal notranslate"><span class="pre">SSLSession</span></code></a> 与 TLS 1.3 不兼容。</p></li>
|
||
<li><p>客户端证书在初始握手期间也不会再被验证。 服务器可以在任何时候请求证书。 客户端会在它们从服务器发送或接收应用数据时处理证书请求。</p></li>
|
||
<li><p>早期数据、延迟的 TLS 客户端证书请求、签名算法配置和密钥重生成等 TLS 1.3 特性尚未被支持。</p></li>
|
||
</ul>
|
||
</section>
|
||
<section id="libressl-support">
|
||
<span id="ssl-libressl"></span><h2>LibreSSL 支持<a class="headerlink" href="#libressl-support" title="永久链接至标题">¶</a></h2>
|
||
<p>LibreSSL 是 OpenSSL 1.0.1 的一个分支。 ssl 模块包含对 LibreSSL 的有限支持。 当 ssl 模块使用 LibreSSL 进行编译时某些特性将不可用。</p>
|
||
<ul class="simple">
|
||
<li><p>LibreSSL >= 2.6.1 不再支持 NPN。 <a class="reference internal" href="#ssl.SSLContext.set_npn_protocols" title="ssl.SSLContext.set_npn_protocols"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLContext.set_npn_protocols()</span></code></a> 和 <a class="reference internal" href="#ssl.SSLSocket.selected_npn_protocol" title="ssl.SSLSocket.selected_npn_protocol"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLSocket.selected_npn_protocol()</span></code></a> 方法将不可用。</p></li>
|
||
<li><p><a class="reference internal" href="#ssl.SSLContext.set_default_verify_paths" title="ssl.SSLContext.set_default_verify_paths"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SSLContext.set_default_verify_paths()</span></code></a> 会忽略环境变量 <span class="target" id="index-68"></span><code class="xref std std-envvar docutils literal notranslate"><span class="pre">SSL_CERT_FILE</span></code> 和 <span class="target" id="index-69"></span><code class="xref std std-envvar docutils literal notranslate"><span class="pre">SSL_CERT_PATH</span></code>,虽然 <a class="reference internal" href="#ssl.get_default_verify_paths" title="ssl.get_default_verify_paths"><code class="xref py py-func docutils literal notranslate"><span class="pre">get_default_verify_paths()</span></code></a> 仍然支持它们。</p></li>
|
||
</ul>
|
||
<div class="admonition seealso">
|
||
<p class="admonition-title">参见</p>
|
||
<dl class="simple">
|
||
<dt>Class <a class="reference internal" href="socket.html#socket.socket" title="socket.socket"><code class="xref py py-class docutils literal notranslate"><span class="pre">socket.socket</span></code></a></dt><dd><p>下层 <a class="reference internal" href="socket.html#module-socket" title="socket: Low-level networking interface."><code class="xref py py-mod docutils literal notranslate"><span class="pre">socket</span></code></a> 类的文档</p>
|
||
</dd>
|
||
<dt><a class="reference external" href="https://httpd.apache.org/docs/trunk/en/ssl/ssl_intro.html">SSL/TLS 高强度加密:概述</a></dt><dd><p>Apache HTTP Server文档介绍</p>
|
||
</dd>
|
||
<dt><span class="target" id="index-70"></span><a class="rfc reference external" href="https://tools.ietf.org/html/rfc1422.html"><strong>RFC 1422: 因特网电子邮件的隐私加强:第二部分:基于证书的密钥管理</strong></a></dt><dd><p>Steve Kent</p>
|
||
</dd>
|
||
<dt><span class="target" id="index-71"></span><a class="rfc reference external" href="https://tools.ietf.org/html/rfc4086.html"><strong>RFC 4086: 确保安全的随机性要求</strong></a></dt><dd><p>Donald E., Jeffrey I. Schiller</p>
|
||
</dd>
|
||
<dt><span class="target" id="index-72"></span><a class="rfc reference external" href="https://tools.ietf.org/html/rfc5280.html"><strong>RFC 5280: 互联网 X.509 公钥基础架构证书和证书吊销列表 (CRL) 配置文件</strong></a></dt><dd><p>D. Cooper</p>
|
||
</dd>
|
||
<dt><span class="target" id="index-73"></span><a class="rfc reference external" href="https://tools.ietf.org/html/rfc5246.html"><strong>RFC 5246: 传输层安全性 (TLS) 协议版本 1.2</strong></a></dt><dd><p>T. Dierks et. al.</p>
|
||
</dd>
|
||
<dt><span class="target" id="index-74"></span><a class="rfc reference external" href="https://tools.ietf.org/html/rfc6066.html"><strong>RFC 6066: 传输层安全性 (TLS) 的扩展</strong></a></dt><dd><p>D. Eastlake</p>
|
||
</dd>
|
||
<dt><a class="reference external" href="https://www.iana.org/assignments/tls-parameters/tls-parameters.xml">IANA TLS: 传输层安全性 (TLS) 的参数</a></dt><dd><p>IANA</p>
|
||
</dd>
|
||
<dt><span class="target" id="index-75"></span><a class="rfc reference external" href="https://tools.ietf.org/html/rfc7525.html"><strong>RFC 7525: 传输层安全性 (TLS) 和数据报传输层安全性 (DTLS) 的安全使用建议</strong></a></dt><dd><p>IETF</p>
|
||
</dd>
|
||
<dt><a class="reference external" href="https://wiki.mozilla.org/Security/Server_Side_TLS">Mozilla 的服务器端 TLS 建议</a></dt><dd><p>Mozilla</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
</section>
|
||
</section>
|
||
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||
<div class="sphinxsidebarwrapper">
|
||
<h3><a href="../contents.html">目录</a></h3>
|
||
<ul>
|
||
<li><a class="reference internal" href="#"><code class="xref py py-mod docutils literal notranslate"><span class="pre">ssl</span></code> --- 套接字对象的 TLS/SSL 包装器</a><ul>
|
||
<li><a class="reference internal" href="#functions-constants-and-exceptions">方法、常量和异常处理</a><ul>
|
||
<li><a class="reference internal" href="#socket-creation">套接字创建</a></li>
|
||
<li><a class="reference internal" href="#context-creation">上下文创建</a></li>
|
||
<li><a class="reference internal" href="#exceptions">异常</a></li>
|
||
<li><a class="reference internal" href="#random-generation">随机生成</a></li>
|
||
<li><a class="reference internal" href="#certificate-handling">证书处理</a></li>
|
||
<li><a class="reference internal" href="#constants">常量</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#ssl-sockets">SSL 套接字</a></li>
|
||
<li><a class="reference internal" href="#ssl-contexts">SSL 上下文</a></li>
|
||
<li><a class="reference internal" href="#certificates">证书</a><ul>
|
||
<li><a class="reference internal" href="#certificate-chains">证书链</a></li>
|
||
<li><a class="reference internal" href="#ca-certificates">CA 证书</a></li>
|
||
<li><a class="reference internal" href="#combined-key-and-certificate">合并的密钥和证书</a></li>
|
||
<li><a class="reference internal" href="#self-signed-certificates">自签名证书</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#examples">例子</a><ul>
|
||
<li><a class="reference internal" href="#testing-for-ssl-support">检测 SSL 支持</a></li>
|
||
<li><a class="reference internal" href="#client-side-operation">客户端操作</a></li>
|
||
<li><a class="reference internal" href="#server-side-operation">服务器端操作</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#notes-on-non-blocking-sockets">关于非阻塞套接字的说明</a></li>
|
||
<li><a class="reference internal" href="#memory-bio-support">内存 BIO 支持</a></li>
|
||
<li><a class="reference internal" href="#ssl-session">SSL 会话</a></li>
|
||
<li><a class="reference internal" href="#security-considerations">安全考量</a><ul>
|
||
<li><a class="reference internal" href="#best-defaults">最佳默认值</a></li>
|
||
<li><a class="reference internal" href="#manual-settings">手动设置</a><ul>
|
||
<li><a class="reference internal" href="#verifying-certificates">验证证书</a></li>
|
||
<li><a class="reference internal" href="#protocol-versions">协议版本</a></li>
|
||
<li><a class="reference internal" href="#cipher-selection">密码选择</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#multi-processing">多进程</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#tls-1-3">TLS 1.3</a></li>
|
||
<li><a class="reference internal" href="#libressl-support">LibreSSL 支持</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
<h4>上一个主题</h4>
|
||
<p class="topless"><a href="socket.html"
|
||
title="上一章"><code class="xref py py-mod docutils literal notranslate"><span class="pre">socket</span></code> --- 底层网络接口</a></p>
|
||
<h4>下一个主题</h4>
|
||
<p class="topless"><a href="select.html"
|
||
title="下一章"><code class="xref py py-mod docutils literal notranslate"><span class="pre">select</span></code> --- 等待 I/O 完成</a></p>
|
||
<div role="note" aria-label="source link">
|
||
<h3>本页</h3>
|
||
<ul class="this-page-menu">
|
||
<li><a href="../bugs.html">报告 Bug</a></li>
|
||
<li>
|
||
<a href="https://github.com/python/cpython/blob/3.8/Doc/library/ssl.rst"
|
||
rel="nofollow">显示源代码
|
||
</a>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="clearer"></div>
|
||
</div>
|
||
<div class="related" role="navigation" aria-label="related navigation">
|
||
<h3>导航</h3>
|
||
<ul>
|
||
<li class="right" style="margin-right: 10px">
|
||
<a href="../genindex.html" title="总目录"
|
||
>索引</a></li>
|
||
<li class="right" >
|
||
<a href="../py-modindex.html" title="Python 模块索引"
|
||
>模块</a> |</li>
|
||
<li class="right" >
|
||
<a href="select.html" title="select --- 等待 I/O 完成"
|
||
>下一页</a> |</li>
|
||
<li class="right" >
|
||
<a href="socket.html" title="socket --- 底层网络接口"
|
||
>上一页</a> |</li>
|
||
|
||
<li><img src="../_static/py.svg" alt="python logo" style="vertical-align: middle; margin-top: -1px"/></li>
|
||
<li><a href="https://www.python.org/">Python</a> »</li>
|
||
<li class="switchers">
|
||
<div class="language_switcher_placeholder"></div>
|
||
<div class="version_switcher_placeholder"></div>
|
||
</li>
|
||
<li>
|
||
|
||
</li>
|
||
<li id="cpython-language-and-version">
|
||
<a href="../index.html">3.8.20 Documentation</a> »
|
||
</li>
|
||
|
||
<li class="nav-item nav-item-1"><a href="index.html" >Python 标准库</a> »</li>
|
||
<li class="nav-item nav-item-2"><a href="ipc.html" >网络和进程间通信</a> »</li>
|
||
<li class="right">
|
||
|
||
|
||
<div class="inline-search" role="search">
|
||
<form class="inline-search" action="../search.html" method="get">
|
||
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
|
||
<input type="submit" value="转向" />
|
||
<input type="hidden" name="check_keywords" value="yes" />
|
||
<input type="hidden" name="area" value="default" />
|
||
</form>
|
||
</div>
|
||
|
|
||
</li>
|
||
|
||
</ul>
|
||
</div>
|
||
<div class="footer">
|
||
© <a href="../copyright.html">版权所有</a> 2001-2024, Python Software Foundation.
|
||
<br />
|
||
This page is licensed under the Python Software Foundation License Version 2.
|
||
<br />
|
||
Examples, recipes, and other code in the documentation are additionally licensed under the Zero Clause BSD License.
|
||
<br />
|
||
|
||
<br />
|
||
|
||
The Python Software Foundation is a non-profit corporation.
|
||
<a href="https://www.python.org/psf/donations/">Please donate.</a>
|
||
<br />
|
||
<br />
|
||
|
||
最后更新于 12月 09, 2024.
|
||
<a href="https://docs.python.org/3/bugs.html">Found a bug</a>?
|
||
<br />
|
||
|
||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 2.4.4.
|
||
</div>
|
||
|
||
</body>
|
||
</html> |