mirror of
https://github.com/fofolee/uTools-Manuals.git
synced 2025-06-08 23:14:06 +08:00
21 lines
21 KiB
HTML
21 lines
21 KiB
HTML
<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安全散列算法SHA1,SHA224,SHA256,SHA384和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">>>> </span><span class="kn">import</span> <span class="nn">hashlib</span>
|
||
<span class="gp">>>> </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">>>> </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">>>> </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">>>> </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">>>> </span><span class="n">m</span><span class="o">.</span><span class="n">digest_size</span>
|
||
<span class="go">16</span>
|
||
<span class="gp">>>> </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">>>> </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">>>> </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">>>> </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">>>> </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">>>> </span><span class="kn">import</span> <span class="nn">hashlib</span><span class="o">,</span> <span class="nn">binascii</span>
|
||
<span class="gp">>>> </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">>>> </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></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></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></a></span></dt><dd><span class="yiyi-st" id="yiyi-109">PKCS#5:基于密码的加密规范2.0版</span></dd></dl></div></div></div></div> |