2019-04-21 11:50:48 +08:00

22 lines
12 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-crypt"><h1><span class="yiyi-st" id="yiyi-10">35.5. <a class="reference internal" href="#module-crypt" title="crypt: The crypt() function used to check Unix passwords. (Unix)"><code class="xref py py-mod docutils literal"><span class="pre">crypt</span></code></a> - 检查Unix密码的功能</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/crypt.py">Lib / crypt.py</a></span></p><p><span class="yiyi-st" id="yiyi-12">该模块实现到<em class="manpage">crypt3</em>例程的接口其是基于修改的DES算法的单向散列函数有关更多详细信息请参阅Unix手册页。</span><span class="yiyi-st" id="yiyi-13">可能的用途包括存储散列密码以便您可以在不存储实际密码的情况下检查密码或尝试使用字典破解Unix密码。</span></p><p id="index-1"><span class="yiyi-st" id="yiyi-14">请注意,此模块的行为取决于运行系统中<em class="manpage">crypt3</em>例程的实际实现。</span><span class="yiyi-st" id="yiyi-15">因此,当前实现中可用的任何扩展也将在此模块上可用。</span></p><div class="section" id="hashing-methods"><h2><span class="yiyi-st" id="yiyi-16">35.5.1. </span><span class="yiyi-st" id="yiyi-17">散列方法</span></h2><div class="versionadded"><p><span class="yiyi-st" id="yiyi-18"><span class="versionmodified">版本3.3中的新功能。</span></span></p></div><p><span class="yiyi-st" id="yiyi-19"><a class="reference internal" href="#module-crypt" title="crypt: The crypt() function used to check Unix passwords. (Unix)"><code class="xref py py-mod docutils literal"><span class="pre">crypt</span></code></a>模块定义了散列方法列表(并非所有平台上的所有方法都可用):</span></p><dl class="data"><dt id="crypt.METHOD_SHA512"><span class="yiyi-st" id="yiyi-20"> <code class="descclassname">crypt.</code><code class="descname">METHOD_SHA512</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-21">一个16字符盐和86字符散列的模块化地址格式方法。</span><span class="yiyi-st" id="yiyi-22">这是最强的方法。</span></p></dd></dl><dl class="data"><dt id="crypt.METHOD_SHA256"><span class="yiyi-st" id="yiyi-23"> <code class="descclassname">crypt.</code><code class="descname">METHOD_SHA256</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-24">另一个模块化地址格式方法具有16个字符的盐和43个字符的哈希。</span></p></dd></dl><dl class="data"><dt id="crypt.METHOD_MD5"><span class="yiyi-st" id="yiyi-25"> <code class="descclassname">crypt.</code><code class="descname">METHOD_MD5</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-26">另一个模块化地址格式方法具有8个字符的盐和22个字符的哈希。</span></p></dd></dl><dl class="data"><dt id="crypt.METHOD_CRYPT"><span class="yiyi-st" id="yiyi-27"> <code class="descclassname">crypt.</code><code class="descname">METHOD_CRYPT</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-28">传统方法使用2个字符的盐和13个字符的哈希。</span><span class="yiyi-st" id="yiyi-29">这是最弱的方法。</span></p></dd></dl></div><div class="section" id="module-attributes"><h2><span class="yiyi-st" id="yiyi-30">35.5.2. </span><span class="yiyi-st" id="yiyi-31">模块属性</span></h2><div class="versionadded"><p><span class="yiyi-st" id="yiyi-32"><span class="versionmodified">版本3.3中的新功能。</span></span></p></div><dl class="attribute"><dt id="crypt.methods"><span class="yiyi-st" id="yiyi-33"> <code class="descclassname">crypt.</code><code class="descname">methods</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-34">可用密码散列算法的列表,如<code class="docutils literal"><span class="pre">crypt.METHOD_*</span></code>对象。</span><span class="yiyi-st" id="yiyi-35">该列表从最强到最弱排序,并且保证至少具有<code class="docutils literal"><span class="pre">crypt.METHOD_CRYPT</span></code></span></p></dd></dl></div><div class="section" id="module-functions"><h2><span class="yiyi-st" id="yiyi-36">35.5.3. </span><span class="yiyi-st" id="yiyi-37">模块功能</span></h2><p><span class="yiyi-st" id="yiyi-38"><a class="reference internal" href="#module-crypt" title="crypt: The crypt() function used to check Unix passwords. (Unix)"><code class="xref py py-mod docutils literal"><span class="pre">crypt</span></code></a>模块定义以下函数:</span></p><dl class="function"><dt id="crypt.crypt"><span class="yiyi-st" id="yiyi-39"> <code class="descclassname">crypt.</code><code class="descname">crypt</code><span class="sig-paren">(</span><em>word</em>, <em>salt=None</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-40"><em></em>通常是在提示或图形界面中输入的用户密码。</span><span class="yiyi-st" id="yiyi-41">可选的<em>salt</em>是从<a class="reference internal" href="#crypt.mksalt" title="crypt.mksalt"><code class="xref py py-func docutils literal"><span class="pre">mksalt()</span></code></a>返回的字符串,<code class="docutils literal"><span class="pre">crypt.METHOD_*</span></code>值之一(虽然不是全部可用在所有平台上),或完整加密的密码,包括盐,由此函数返回。</span><span class="yiyi-st" id="yiyi-42">如果未提供<em>salt</em>,将使用最强的方法(由<a class="reference internal" href="#crypt.methods" title="crypt.methods"><code class="xref py py-func docutils literal"><span class="pre">methods()</span></code></a>返回)。</span></p><p><span class="yiyi-st" id="yiyi-43">检查密码通常是通过传递明文密码作为<em></em>和上一个<a class="reference internal" href="#module-crypt" title="crypt: The crypt() function used to check Unix passwords. (Unix)"><code class="xref py py-func docutils literal"><span class="pre">crypt()</span></code></a>调用的完整结果,这应该与结果相同这个调用。</span></p><p><span class="yiyi-st" id="yiyi-44"><em>salt</em>随机的2或16个字符的字符串可能带有<code class="docutils literal"><span class="pre">$digit$</span></code>前缀,表示该方法),用于扰乱加密算法。</span><span class="yiyi-st" id="yiyi-45"><em>salt</em>中的字符必须在集合<code class="docutils literal"><span class="pre">[./a-zA-Z0-9]</span></code>中,除了前缀为<code class="docutils literal"><span class="pre">$digit$</span></code></span></p><p><span class="yiyi-st" id="yiyi-46">以字符串形式返回散列的密码,它将由与盐相同的字母表中的字符组成。</span></p><p id="index-2"><span class="yiyi-st" id="yiyi-47">由于少数<em class="manpage">crypt3</em>扩展允许在<em></em>中使用不同的大小,因此建议在检查密码时使用完全加密的密码作为盐。</span></p><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-48"><span class="versionmodified">在版本3.3中更改:</span>除了<em>salt</em>的字符串,接受<code class="docutils literal"><span class="pre">crypt.METHOD_*</span></code>值。</span></p></div></dd></dl><dl class="function"><dt id="crypt.mksalt"><span class="yiyi-st" id="yiyi-49"> <code class="descclassname">crypt.</code><code class="descname">mksalt</code><span class="sig-paren">(</span><em>method=None</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-50">返回指定方法的随机生成的盐。</span><span class="yiyi-st" id="yiyi-51">如果未给出<em>方法</em>,则使用由<a class="reference internal" href="#crypt.methods" title="crypt.methods"><code class="xref py py-func docutils literal"><span class="pre">methods()</span></code></a>返回的最强的方法。</span></p><p><span class="yiyi-st" id="yiyi-52">返回值是<code class="docutils literal"><span class="pre">crypt.METHOD_CRYPT</span></code>的长度为2个字符的字符串或者以<code class="docutils literal"><span class="pre">$digit$</span></code>开头的19个字符和来自集合的16个随机字符<code class="docutils literal"><span class="pre">[./a-zA-Z0-9]</span></code>,适合作为<em>salt</em>参数传递给<a class="reference internal" href="#module-crypt" title="crypt: The crypt() function used to check Unix passwords. (Unix)"><code class="xref py py-func docutils literal"><span class="pre">crypt()</span></code></a></span></p><div class="versionadded"><p><span class="yiyi-st" id="yiyi-53"><span class="versionmodified">版本3.3中的新功能。</span></span></p></div></dd></dl></div><div class="section" id="examples"><h2><span class="yiyi-st" id="yiyi-54">35.5.4. </span><span class="yiyi-st" id="yiyi-55">实例</span></h2><p><span class="yiyi-st" id="yiyi-56">一个简单的例子说明了典型的使用(恒定时间比较操作需要限制暴露于定时攻击。</span><span class="yiyi-st" id="yiyi-57"><a class="reference internal" href="hmac.html#hmac.compare_digest" title="hmac.compare_digest"><code class="xref py py-func docutils literal"><span class="pre">hmac.compare_digest()</span></code></a>适用于此目的):</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">pwd</span>
<span class="kn">import</span> <span class="nn">crypt</span>
<span class="kn">import</span> <span class="nn">getpass</span>
<span class="kn">from</span> <span class="nn">hmac</span> <span class="k">import</span> <span class="n">compare_digest</span> <span class="k">as</span> <span class="n">compare_hash</span>
<span class="k">def</span> <span class="nf">login</span><span class="p">():</span>
<span class="n">username</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s1">'Python login: '</span><span class="p">)</span>
<span class="n">cryptedpasswd</span> <span class="o">=</span> <span class="n">pwd</span><span class="o">.</span><span class="n">getpwnam</span><span class="p">(</span><span class="n">username</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span>
<span class="k">if</span> <span class="n">cryptedpasswd</span><span class="p">:</span>
<span class="k">if</span> <span class="n">cryptedpasswd</span> <span class="o">==</span> <span class="s1">'x'</span> <span class="ow">or</span> <span class="n">cryptedpasswd</span> <span class="o">==</span> <span class="s1">'*'</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">'no support for shadow passwords'</span><span class="p">)</span>
<span class="n">cleartext</span> <span class="o">=</span> <span class="n">getpass</span><span class="o">.</span><span class="n">getpass</span><span class="p">()</span>
<span class="k">return</span> <span class="n">compare_hash</span><span class="p">(</span><span class="n">crypt</span><span class="o">.</span><span class="n">crypt</span><span class="p">(</span><span class="n">cleartext</span><span class="p">,</span> <span class="n">cryptedpasswd</span><span class="p">),</span> <span class="n">cryptedpasswd</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">True</span>
</code></pre><p><span class="yiyi-st" id="yiyi-58">使用最强的可用方法生成密码的哈希值,并对照原始值进行检查:</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">crypt</span>
<span class="kn">from</span> <span class="nn">hmac</span> <span class="k">import</span> <span class="n">compare_digest</span> <span class="k">as</span> <span class="n">compare_hash</span>
<span class="n">hashed</span> <span class="o">=</span> <span class="n">crypt</span><span class="o">.</span><span class="n">crypt</span><span class="p">(</span><span class="n">plaintext</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">compare_hash</span><span class="p">(</span><span class="n">hashed</span><span class="p">,</span> <span class="n">crypt</span><span class="o">.</span><span class="n">crypt</span><span class="p">(</span><span class="n">plaintext</span><span class="p">,</span> <span class="n">hashed</span><span class="p">)):</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">"hashed version doesn't validate against original"</span><span class="p">)</span>
</code></pre></div></div></div>