uTools-Manuals/docs/python/hashlib.html
2019-04-21 11:50:48 +08:00

21 lines
21 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<div class="body" role="main"><div class="section" id="module-hashlib"><h1><span class="yiyi-st" id="yiyi-10">15.1. <a class="reference internal" href="#module-hashlib" title="hashlib: Secure hash and message digest algorithms."><code class="xref py py-mod docutils literal"><span class="pre">hashlib</span></code></a> — 安全散列和消息摘要</span></h1><p><span class="yiyi-st" id="yiyi-11"><strong>源代码:</strong> <a class="reference external" href="https://hg.python.org/cpython/file/3.5/Lib/hashlib.py">Lib/hashlib.py</a></span></p><p><span class="yiyi-st" id="yiyi-12">该模块实现了许多不同 Secure Hash 和 message digest 算法的通用接口。</span><span class="yiyi-st" id="yiyi-13">包括FIPS安全散列算法SHA1SHA224SHA256SHA384和SHA512在FIPS 180-2中定义以及RSA的MD5算法在因特网<span class="target" id="index-1"></span> <a class="rfc reference external" href="https://tools.ietf.org/html/rfc1321.html"><strong>RFC 1321</strong></a></span><span class="yiyi-st" id="yiyi-14">术语“安全散列”和“消息摘要”是可互换的。</span><span class="yiyi-st" id="yiyi-15">较旧的算法被称为消息摘要。</span><span class="yiyi-st" id="yiyi-16">现代术语是安全哈希。</span></p><div class="admonition note"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-17"></span></p><p class="last"><span class="yiyi-st" id="yiyi-18">如果你想要adler32或crc32哈希函数它们在<a class="reference internal" href="zlib.html#module-zlib" title="zlib: Low-level interface to compression and decompression routines compatible with gzip."><code class="xref py py-mod docutils literal"><span class="pre">zlib</span></code></a>模块中可用。</span></p></div><div class="admonition warning"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-19">警告</span></p><p class="last"><span class="yiyi-st" id="yiyi-20">一些算法具有已知的哈希冲突弱点,请参阅末尾的"另请参见"一节。</span></p></div><div class="section" id="hash-algorithms"><h2><span class="yiyi-st" id="yiyi-21">15.1.1.</span><span class="yiyi-st" id="yiyi-22">Hash 算法</span></h2><p><span class="yiyi-st" id="yiyi-23">对于每种类型的<em class="dfn">hash</em>,都有一个构造函数方法 . </span><span class="yiyi-st" id="yiyi-24">它们都返回一个具有相同的简单接口的哈希对象。</span><span class="yiyi-st" id="yiyi-25">例如:使用<code class="xref py py-func docutils literal"><span class="pre">sha1()</span></code>创建SHA1哈希对象。</span><span class="yiyi-st" id="yiyi-26">现在,你可以使用<code class="xref py py-meth docutils literal"><span class="pre">update()</span></code>方法以<a class="reference internal" href="../glossary.html#term-bytes-like-object"><span class="xref std std-term">类字节对象</span></a>填充这个对象(通常为<a class="reference internal" href="functions.html#bytes" title="bytes"><code class="xref py py-class docutils literal"><span class="pre">字节</span></code></a>)。</span><span class="yiyi-st" id="yiyi-27">在连接数据的任何时候,你都可以使用<code class="xref py py-meth docutils literal"><span class="pre">digest()</span></code><code class="xref py py-meth docutils literal"><span class="pre">hexdigest()</span></code>方法来向它请求<em class="dfn">摘要</em></span></p><div class="admonition note"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-28"></span></p><p class="last"><span class="yiyi-st" id="yiyi-29">为了更好的多线程性能在对象创建或更新时针对大于2047字节的数据发布Python <a class="reference internal" href="../glossary.html#term-gil"><span class="xref std std-term">GIL</span></a></span></p></div><div class="admonition note"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-30"></span></p><p class="last"><span class="yiyi-st" id="yiyi-31">不支持将字符串对象添加到<code class="xref py py-meth docutils literal"><span class="pre">update()</span></code>中,因为哈希在字节上工作,而不是字符。</span></p></div><p id="index-2"><span class="yiyi-st" id="yiyi-32">此模块中始终存在的散列算法的构造函数为<code class="xref py py-func docutils literal"><span class="pre">md5()</span></code><code class="xref py py-func docutils literal"><span class="pre">sha1()</span></code><code class="xref py py-func docutils literal"><span class="pre">sha224()</span></code><code class="xref py py-func docutils literal"><span class="pre">sha256()</span></code><code class="xref py py-func docutils literal"><span class="pre">sha384()</span></code><code class="xref py py-func docutils literal"><span class="pre">sha512()</span></code></span><span class="yiyi-st" id="yiyi-33">可能还有其它算法这取决于在你的平台上Python 使用的 OpenSSL 库。</span></p><p><span class="yiyi-st" id="yiyi-34">例如,获取字节字符串<code class="docutils literal"><span class="pre">b'Nobody</span> <span class="pre">inspects</span> <span class="pre">the</span> <span class="pre">spammish</span> <span class="pre">repetition'</span></code>的摘要:</span></p><pre><code class="language-python"><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">hashlib</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">m</span> <span class="o">=</span> <span class="n">hashlib</span><span class="o">.</span><span class="n">md5</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">m</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">b</span><span class="s2">"Nobody inspects"</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">m</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">b</span><span class="s2">" the spammish repetition"</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">m</span><span class="o">.</span><span class="n">digest</span><span class="p">()</span>
<span class="go">b'\xbbd\x9c\x83\xdd\x1e\xa5\xc9\xd9\xde\xc9\xa1\x8d\xf0\xff\xe9'</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">m</span><span class="o">.</span><span class="n">digest_size</span>
<span class="go">16</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">m</span><span class="o">.</span><span class="n">block_size</span>
<span class="go">64</span>
</code></pre><p><span class="yiyi-st" id="yiyi-35">更精炼的版本:</span></p><pre><code class="language-python"><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">hashlib</span><span class="o">.</span><span class="n">sha224</span><span class="p">(</span><span class="n">b</span><span class="s2">"Nobody inspects the spammish repetition"</span><span class="p">)</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span>
<span class="go">'a4337bc45a8fc544c03f52dc550cd6e1e87021bc896588bd79e901e2'</span>
</code></pre><dl class="function"><dt id="hashlib.new"><span class="yiyi-st" id="yiyi-36"><code class="descclassname">hashlib.</code><code class="descname">new</code><span class="sig-paren">(</span><em>name</em><span class="optional">[</span>, <em>data</em><span class="optional">]</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-37">是一个通用构造函数,它接受所需算法的字符串名称作为其第一个参数。</span><span class="yiyi-st" id="yiyi-38">它也存在允许访问上面列出的哈希以及您的OpenSSL库可能提供的任何其他算法。</span><span class="yiyi-st" id="yiyi-39">命名的构造函数比<a class="reference internal" href="#hashlib.new" title="hashlib.new"><code class="xref py py-func docutils literal"><span class="pre">new()</span></code></a>快得多,应该是首选。</span></p></dd></dl><p><span class="yiyi-st" id="yiyi-40">使用OpenSSL提供的算法使用<a class="reference internal" href="#hashlib.new" title="hashlib.new"><code class="xref py py-func docutils literal"><span class="pre">new()</span></code></a></span></p><pre><code class="language-python"><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">h</span> <span class="o">=</span> <span class="n">hashlib</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s1">'ripemd160'</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">h</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">b</span><span class="s2">"Nobody inspects the spammish repetition"</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">h</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span>
<span class="go">'cc4a5ce1b3df48aec5d22d1f16b894a0b894eccc'</span>
</code></pre><p><span class="yiyi-st" id="yiyi-41">Hashlib提供以下常量属性</span></p><dl class="data"><dt id="hashlib.algorithms_guaranteed"><span class="yiyi-st" id="yiyi-42"><code class="descclassname">hashlib.</code><code class="descname">algorithms_guaranteed</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-43">包含保证在所有平台上此模块支持的哈希算法的名称的集合。</span></p><div class="versionadded"><p><span class="yiyi-st" id="yiyi-44"><span class="versionmodified">版本3.2中的新功能。</span></span></p></div></dd></dl><dl class="data"><dt id="hashlib.algorithms_available"><span class="yiyi-st" id="yiyi-45"><code class="descclassname">hashlib.</code><code class="descname">algorithms_available</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-46">一组包含在运行的Python解释器中可用的哈希算法的名称。</span><span class="yiyi-st" id="yiyi-47">当传递到<a class="reference internal" href="#hashlib.new" title="hashlib.new"><code class="xref py py-func docutils literal"><span class="pre">new()</span></code></a>时,这些名称将被识别。</span><span class="yiyi-st" id="yiyi-48"><a class="reference internal" href="#hashlib.algorithms_guaranteed" title="hashlib.algorithms_guaranteed"><code class="xref py py-attr docutils literal"><span class="pre">algorithms_guaranteed</span></code></a>将始终是子集。</span><span class="yiyi-st" id="yiyi-49">相同的算法可能出现多次在此集中不同的名称感谢OpenSSL</span></p><div class="versionadded"><p><span class="yiyi-st" id="yiyi-50"><span class="versionmodified">版本3.2中的新功能。</span></span></p></div></dd></dl><p><span class="yiyi-st" id="yiyi-51">构造函数返回的哈希对象提供以下值作为常量属性:</span></p><dl class="data"><dt id="hashlib.hash.digest_size"><span class="yiyi-st" id="yiyi-52"><code class="descclassname">hash.</code><code class="descname">digest_size</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-53">以字节为单位的哈希结果的大小。</span></p></dd></dl><dl class="data"><dt id="hashlib.hash.block_size"><span class="yiyi-st" id="yiyi-54"><code class="descclassname">hash.</code><code class="descname">block_size</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-55">以字节为单位的哈希算法的内部块的大小。</span></p></dd></dl><p><span class="yiyi-st" id="yiyi-56">哈希对象具有以下属性:</span></p><dl class="attribute"><dt id="hashlib.hash.name"><span class="yiyi-st" id="yiyi-57"><code class="descclassname">hash.</code><code class="descname">name</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-58">此哈希的规范名称,始终小写,始终适合作为<a class="reference internal" href="#hashlib.new" title="hashlib.new"><code class="xref py py-func docutils literal"><span class="pre">new()</span></code></a>的参数,以创建此类型的另一个哈希。</span></p><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-59"><span class="versionmodified">在版本3.4中更改:</span> CPython自启动以来就存在name属性但直到Python 3.4未正式指定,因此在某些平台上可能不存在。</span></p></div></dd></dl><p><span class="yiyi-st" id="yiyi-60">哈希对象都具有以下方法:</span></p><dl class="method"><dt id="hashlib.hash.update"><span class="yiyi-st" id="yiyi-61"><code class="descclassname">hash.</code><code class="descname">update</code><span class="sig-paren">(</span><em>arg</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-62">使用对象<em>arg</em>更新哈希对象,该对象必须可解释为字节缓冲区。</span><span class="yiyi-st" id="yiyi-63">重复调用等效于具有所有参数串联的单个调用:<code class="docutils literal"><span class="pre">m.update(a);</span> <span class="pre">m.update(b)</span></code>相当于<code class="docutils literal"><span class="pre">m.update(ab)</span></code></span></p><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-64"><span class="versionmodified">在版本3.1中已更改:</span>发布Python GIL以允许其他线程在使用OpenSSL提供的哈希算法时对大于2047字节的数据进行哈希更新时运行。</span></p></div></dd></dl><dl class="method"><dt id="hashlib.hash.digest"><span class="yiyi-st" id="yiyi-65"><code class="descclassname">hash.</code><code class="descname">digest</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-66">返回传递给<a class="reference internal" href="#hashlib.hash.update" title="hashlib.hash.update"><code class="xref py py-meth docutils literal"><span class="pre">update()</span></code></a>方法的数据的摘要。</span><span class="yiyi-st" id="yiyi-67">它是一个大小为<a class="reference internal" href="#hashlib.hash.digest_size" title="hashlib.hash.digest_size"><code class="xref py py-attr docutils literal"><span class="pre">digest_size</span></code></a>的字节对象包含的字节可以在0到255整个范围。</span></p></dd></dl><dl class="method"><dt id="hashlib.hash.hexdigest"><span class="yiyi-st" id="yiyi-68"><code class="descclassname">hash.</code><code class="descname">hexdigest</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-69">类似<a class="reference internal" href="#hashlib.hash.digest" title="hashlib.hash.digest"><code class="xref py py-meth docutils literal"><span class="pre">digest()</span></code></a>但是摘要以2倍长度的字符串对象返回只包含十六进制数字。</span><span class="yiyi-st" id="yiyi-70">这可用于在电子邮件或其它非二进制环境中安全交换数据。</span></p></dd></dl><dl class="method"><dt id="hashlib.hash.copy"><span class="yiyi-st" id="yiyi-71"><code class="descclassname">hash.</code><code class="descname">copy</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-72">返回哈希对象的一个副本("克隆")。</span><span class="yiyi-st" id="yiyi-73">这可以用于有效地计算共享公共初始子串的数据的摘要。</span></p></dd></dl></div><div class="section" id="key-derivation"><h2><span class="yiyi-st" id="yiyi-74">15.1.2.</span><span class="yiyi-st" id="yiyi-75">密钥导出</span></h2><p><span class="yiyi-st" id="yiyi-76">密钥派生和密钥stretching 设计用于安全的密码哈希。</span><span class="yiyi-st" id="yiyi-77">诸如<code class="docutils literal"><span class="pre">sha1(password)</span></code>的朴素算法不能抵抗暴力攻击。</span><span class="yiyi-st" id="yiyi-78">一个好的密码哈希函数必须是可调谐、 速度慢,并且包括一个<a class="reference external" href="https://en.wikipedia.org/wiki/Salt_%28cryptography%29">salt</a></span></p><dl class="function"><dt id="hashlib.pbkdf2_hmac"><span class="yiyi-st" id="yiyi-79"><code class="descclassname">hashlib.</code><code class="descname">pbkdf2_hmac</code><span class="sig-paren">(</span><em>hash_name</em>, <em>password</em>, <em>salt</em>, <em>iterations</em>, <em>dklen=None</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-80">该函数提供 PKCS #5 基于密码的密钥派生函数 2。</span><span class="yiyi-st" id="yiyi-81">它使用 HMAC 作为伪随机函数。</span></p><p><span class="yiyi-st" id="yiyi-82">字符串<em>hash_name</em>是HMAC的所需的哈希摘要算法的名称例如。</span><span class="yiyi-st" id="yiyi-83">'sha1'或'sha256'。</span><span class="yiyi-st" id="yiyi-84"><em>password</em><em>salt</em>被解释为缓冲区的字节数。</span><span class="yiyi-st" id="yiyi-85">应用程式和程式库应将<em>密码</em>限制为明智的长度(例如</span><span class="yiyi-st" id="yiyi-86">1024</span><span class="yiyi-st" id="yiyi-87"><em>salt</em>应该是来自适当源的大约16个或更多个字节例如</span><span class="yiyi-st" id="yiyi-88"><a class="reference internal" href="os.html#os.urandom" title="os.urandom"><code class="xref py py-func docutils literal"><span class="pre">os.urandom()</span></code></a></span></p><p><span class="yiyi-st" id="yiyi-89"><em>迭代次数</em>应基于散列算法和计算能力来选择。</span><span class="yiyi-st" id="yiyi-90">截至2013年建议至少100,000次迭代的SHA-256。</span></p><p><span class="yiyi-st" id="yiyi-91"><em>dklen</em>是派生密钥的长度。</span><span class="yiyi-st" id="yiyi-92">如果<em>dklen</em><code class="docutils literal"><span class="pre">None</span></code>,则使用散列算法的摘要大小<em>hash_name</em></span><span class="yiyi-st" id="yiyi-93">64用于SHA-512。</span></p><pre><code class="language-python"><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">hashlib</span><span class="o">,</span> <span class="nn">binascii</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">dk</span> <span class="o">=</span> <span class="n">hashlib</span><span class="o">.</span><span class="n">pbkdf2_hmac</span><span class="p">(</span><span class="s1">'sha256'</span><span class="p">,</span> <span class="n">b</span><span class="s1">'password'</span><span class="p">,</span> <span class="n">b</span><span class="s1">'salt'</span><span class="p">,</span> <span class="mi">100000</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">binascii</span><span class="o">.</span><span class="n">hexlify</span><span class="p">(</span><span class="n">dk</span><span class="p">)</span>
<span class="go">b'0394a2ede332c9a13eb82e9b24631604c31df978b4e2f0fbd2c549944f9d79a5'</span>
</code></pre><div class="versionadded"><p><span class="yiyi-st" id="yiyi-94"><span class="versionmodified">新版本3.4。</span></span></p></div><div class="admonition note"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-95"></span></p><p class="last"><span class="yiyi-st" id="yiyi-96">OpenSSL 中实现的<em>pbkdf2_hmac</em> 更加快速。</span><span class="yiyi-st" id="yiyi-97">Python实现使用<a class="reference internal" href="hmac.html#module-hmac" title="hmac: Keyed-Hashing for Message Authentication (HMAC) implementation"><code class="xref py py-mod docutils literal"><span class="pre">hmac</span></code></a>的内联版本。</span><span class="yiyi-st" id="yiyi-98">它慢了约三倍且不释放 GIL。</span></p></div></dd></dl><div class="admonition seealso"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-99">请参见</span></p><dl class="last docutils"><dt><span class="yiyi-st" id="yiyi-100">模块<a class="reference internal" href="hmac.html#module-hmac" title="hmac: Keyed-Hashing for Message Authentication (HMAC) implementation"><code class="xref py py-mod docutils literal"><span class="pre">hmac</span></code></a></span></dt><dd><span class="yiyi-st" id="yiyi-101">使用哈希生成消息认证码的一个模块</span></dd><dt><span class="yiyi-st" id="yiyi-102">模块<a class="reference internal" href="base64.html#module-base64" title="base64: RFC 3548: Base16, Base32, Base64 Data Encodings; Base85 and Ascii85"><code class="xref py py-mod docutils literal"><span class="pre">base64</span></code></a></span></dt><dd><span class="yiyi-st" id="yiyi-103">用于非二进制环境的编码二进制哈希的另外一种方式</span></dd><dt><span class="yiyi-st" id="yiyi-104"><a class="reference external" href="http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf"> http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf T0&gt;</a></span></dt><dd><span class="yiyi-st" id="yiyi-105">关于安全哈希算法的 FIPS 180-2 的公开发行</span></dd><dt><span class="yiyi-st" id="yiyi-106"><a class="reference external" href="https://en.wikipedia.org/wiki/Cryptographic_hash_function#Cryptographic_hash_algorithms"> https://en.wikipedia.org/wiki/Cryptographic_hash_function#Cryptographic_hash_algorithms T0&gt;</a></span></dt><dd><span class="yiyi-st" id="yiyi-107">维基百科的文章,关于哪些算法有已知问题和使用中的含义</span></dd><dt><span class="yiyi-st" id="yiyi-108"><a class="reference external" href="https://www.ietf.org/rfc/rfc2898.txt"> https://www.ietf.org/rfc/rfc2898.txt T0&gt;</a></span></dt><dd><span class="yiyi-st" id="yiyi-109">PKCS5基于密码的加密规范2.0版</span></dd></dl></div></div></div></div>