[code.view]

[top] / python / PyMOTW / docs / hmac / index.html


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
    <title>hmac – Cryptographic signature and verification of messages. &mdash; Python Module of the Week</title>
    <link rel="stylesheet" href="../_static/sphinxdoc.css" type="text/css" />
    <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    '../',
        VERSION:     '1.132',
        COLLAPSE_INDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  true
      };
    </script>
    <script type="text/javascript" src="../_static/jquery.js"></script>
    <script type="text/javascript" src="../_static/underscore.js"></script>
    <script type="text/javascript" src="../_static/doctools.js"></script>
    <link rel="author" title="About these documents" href="../about.html" />
    <link rel="top" title="Python Module of the Week" href="../index.html" />
    <link rel="up" title="Cryptographic Services" href="../cryptographic.html" />
    <link rel="next" title="File and Directory Access" href="../file_access.html" />
    <link rel="prev" title="hashlib – Cryptographic hashes and message digests" href="../hashlib/index.html" /> 
  </head>
  <body>
    <div class="related">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../genindex.html" title="General Index"
             accesskey="I">index</a></li>
        <li class="right" >
          <a href="../py-modindex.html" title="Python Module Index"
             >modules</a> |</li>
        <li class="right" >
          <a href="../file_access.html" title="File and Directory Access"
             accesskey="N">next</a> |</li>
        <li class="right" >
          <a href="../hashlib/index.html" title="hashlib – Cryptographic hashes and message digests"
             accesskey="P">previous</a> |</li>
        <li><a href="../contents.html">PyMOTW</a> &raquo;</li>
          <li><a href="../cryptographic.html" accesskey="U">Cryptographic Services</a> &raquo;</li> 
      </ul>
    </div>
      <div class="sphinxsidebar">
        <div class="sphinxsidebarwrapper">
  <h3><a href="../contents.html">Table Of Contents</a></h3>
  <ul>
<li><a class="reference internal" href="#">hmac &#8211; Cryptographic signature and verification of messages.</a><ul>
<li><a class="reference internal" href="#example">Example</a></li>
<li><a class="reference internal" href="#sha-vs-md5">SHA vs. MD5</a></li>
<li><a class="reference internal" href="#binary-digests">Binary Digests</a></li>
<li><a class="reference internal" href="#applications">Applications</a></li>
</ul>
</li>
</ul>

  <h4>Previous topic</h4>
  <p class="topless"><a href="../hashlib/index.html"
                        title="previous chapter">hashlib &#8211; Cryptographic hashes and message digests</a></p>
  <h4>Next topic</h4>
  <p class="topless"><a href="../file_access.html"
                        title="next chapter">File and Directory Access</a></p>
  <h3>This Page</h3>
  <ul class="this-page-menu">
    <li><a href="../_sources/hmac/index.txt"
           rel="nofollow">Show Source</a></li>
  </ul>
<div id="searchbox" style="display: none">
  <h3>Quick search</h3>
    <form class="search" action="../search.html" method="get">
      <input type="text" name="q" size="18" />
      <input type="submit" value="Go" />
      <input type="hidden" name="check_keywords" value="yes" />
      <input type="hidden" name="area" value="default" />
    </form>
    <p class="searchtip" style="font-size: 90%">
    Enter search terms or a module, class or function name.
    </p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body">
            
  <div class="section" id="module-hmac">
<span id="hmac-cryptographic-signature-and-verification-of-messages"></span><h1>hmac &#8211; Cryptographic signature and verification of messages.<a class="headerlink" href="#module-hmac" title="Permalink to this headline">¶</a></h1>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Purpose:</th><td class="field-body">The hmac module implements keyed-hashing for message authentication, as
described in <span class="target" id="index-0"></span><a class="rfc reference external" href="http://tools.ietf.org/html/rfc2104.html"><strong>RFC 2104</strong></a>.</td>
</tr>
<tr class="field"><th class="field-name">Python Version:</th><td class="field-body">2.2</td>
</tr>
</tbody>
</table>
<p>The HMAC algorithm can be used to verify the integrity of information
passed between applications or stored in a potentially vulnerable
location. The basic idea is to generate a cryptographic hash of the
actual data combined with a shared secret key. The resulting hash can
then be used to check the transmitted or stored message to determine a
level of trust, without transmitting the secret key.</p>
<p>Disclaimer: I&#8217;m not a security expert. For the full details on HMAC,
check out <span class="target" id="index-1"></span><a class="rfc reference external" href="http://tools.ietf.org/html/rfc2104.html"><strong>RFC 2104</strong></a>.</p>
<div class="section" id="example">
<h2>Example<a class="headerlink" href="#example" title="Permalink to this headline">¶</a></h2>
<p>Creating the hash is not complex. Here&#8217;s a simple example which uses
the default MD5 hash algorithm:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">hmac</span>

<span class="n">digest_maker</span> <span class="o">=</span> <span class="n">hmac</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s">&#39;secret-shared-key-goes-here&#39;</span><span class="p">)</span>

<span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s">&#39;lorem.txt&#39;</span><span class="p">,</span> <span class="s">&#39;rb&#39;</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
    <span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
        <span class="n">block</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">1024</span><span class="p">)</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="n">block</span><span class="p">:</span>
            <span class="k">break</span>
        <span class="n">digest_maker</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">block</span><span class="p">)</span>
<span class="k">finally</span><span class="p">:</span>
    <span class="n">f</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>

<span class="n">digest</span> <span class="o">=</span> <span class="n">digest_maker</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span>
<span class="k">print</span> <span class="n">digest</span>
</pre></div>
</div>
<p>When run, the code reads its source file and computes an HMAC
signature for it:</p>
<div class="highlight-python"><pre>$ python hmac_simple.py

4bcb287e284f8c21e87e14ba2dc40b16</pre>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">If I haven&#8217;t changed the file by the time I release the example
source for this week, the copy you download should produce the same
hash.</p>
</div>
</div>
<div class="section" id="sha-vs-md5">
<h2>SHA vs. MD5<a class="headerlink" href="#sha-vs-md5" title="Permalink to this headline">¶</a></h2>
<p>Although the default cryptographic algorithm for <a class="reference internal" href="#module-hmac" title="hmac: Cryptographic signature and verification of messages."><tt class="xref py py-mod docutils literal"><span class="pre">hmac</span></tt></a> is MD5,
that is not the most secure method to use. MD5 hashes have some
weaknesses, such as collisions (where two different messages produce
the same hash). The SHA-1 algorithm is considered to be stronger, and
should be used instead.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">hmac</span>
<span class="kn">import</span> <span class="nn">hashlib</span>

<span class="n">digest_maker</span> <span class="o">=</span> <span class="n">hmac</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s">&#39;secret-shared-key-goes-here&#39;</span><span class="p">,</span> <span class="s">&#39;&#39;</span><span class="p">,</span> <span class="n">hashlib</span><span class="o">.</span><span class="n">sha1</span><span class="p">)</span>

<span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s">&#39;hmac_sha.py&#39;</span><span class="p">,</span> <span class="s">&#39;rb&#39;</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
    <span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
        <span class="n">block</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">1024</span><span class="p">)</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="n">block</span><span class="p">:</span>
            <span class="k">break</span>
        <span class="n">digest_maker</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">block</span><span class="p">)</span>
<span class="k">finally</span><span class="p">:</span>
    <span class="n">f</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>

<span class="n">digest</span> <span class="o">=</span> <span class="n">digest_maker</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span>
<span class="k">print</span> <span class="n">digest</span>
</pre></div>
</div>
<p><tt class="docutils literal"><span class="pre">hmac.new()</span></tt> takes 3 arguments. The first is the secret key, which
should be shared between the two endpoints which are communicating so
both ends can use the same value. The second value is an initial
message. If the message content that needs to be authenticated is
small, such as a timestamp or HTTP POST, the entire body of the
message can be passed to <tt class="docutils literal"><span class="pre">new()</span></tt> instead of using the update()
method. The last argument is the digest module to be used. The default
is <tt class="docutils literal"><span class="pre">hashlib.md5</span></tt>. The previous example substitutes <tt class="docutils literal"><span class="pre">hashlib.sha1</span></tt>.</p>
<div class="highlight-python"><pre>$ python hmac_sha.py

69b26d1731a0a5f0fc7a92fc6c540823ec210759</pre>
</div>
</div>
<div class="section" id="binary-digests">
<h2>Binary Digests<a class="headerlink" href="#binary-digests" title="Permalink to this headline">¶</a></h2>
<p>The first few examples used the <tt class="docutils literal"><span class="pre">hexdigest()</span></tt> method to produce
printable digests. The hexdigest is is a different representation of
the value calculated by the <tt class="docutils literal"><span class="pre">digest()</span></tt> method, which is a binary
value that may include unprintable or non-ASCII characters, including
NULs. Some web services (Google checkout, Amazon S3) use the
<tt class="docutils literal"><span class="pre">base64</span></tt> encoded version of the binary digest instead of the
hexdigest.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">base64</span>
<span class="kn">import</span> <span class="nn">hmac</span>
<span class="kn">import</span> <span class="nn">hashlib</span>

<span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s">&#39;lorem.txt&#39;</span><span class="p">,</span> <span class="s">&#39;rb&#39;</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
    <span class="n">body</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<span class="k">finally</span><span class="p">:</span>
    <span class="n">f</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>

<span class="n">digest</span> <span class="o">=</span> <span class="n">hmac</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s">&#39;secret-shared-key-goes-here&#39;</span><span class="p">,</span> <span class="n">body</span><span class="p">,</span> <span class="n">hashlib</span><span class="o">.</span><span class="n">sha1</span><span class="p">)</span><span class="o">.</span><span class="n">digest</span><span class="p">()</span>
<span class="k">print</span> <span class="n">base64</span><span class="o">.</span><span class="n">encodestring</span><span class="p">(</span><span class="n">digest</span><span class="p">)</span>
</pre></div>
</div>
<p>The base64 encoded string ends in a newline, which frequently needs to be
stripped off when embedding the string in HTTP headers or other
formatting-sensitive contexts.</p>
<div class="highlight-python"><pre>$ python hmac_base64.py

olW2DoXHGJEKGU0aE9fOwSVE/o4=</pre>
</div>
</div>
<div class="section" id="applications">
<h2>Applications<a class="headerlink" href="#applications" title="Permalink to this headline">¶</a></h2>
<p>HMAC authentication should be used for any public network service, and
any time data is stored where security is important. For example, when
sending data through a pipe or socket, that data should be signed and
then the signature should be tested before the data is used. The
extended example below is available in the <tt class="docutils literal"><span class="pre">hmac_pickle.py</span></tt> file as
part of the PyMOTW source package.</p>
<p>First, let&#8217;s establish a function to calculate a digest for a string,
and a simple class to be instantiated and passed through a
communication channel.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">hashlib</span>
<span class="kn">import</span> <span class="nn">hmac</span>
<span class="k">try</span><span class="p">:</span>
    <span class="kn">import</span> <span class="nn">cPickle</span> <span class="kn">as</span> <span class="nn">pickle</span>
<span class="k">except</span><span class="p">:</span>
    <span class="kn">import</span> <span class="nn">pickle</span>
<span class="kn">import</span> <span class="nn">pprint</span>
<span class="kn">from</span> <span class="nn">StringIO</span> <span class="kn">import</span> <span class="n">StringIO</span>


<span class="k">def</span> <span class="nf">make_digest</span><span class="p">(</span><span class="n">message</span><span class="p">):</span>
    <span class="s">&quot;Return a digest for the message.&quot;</span>
    <span class="k">return</span> <span class="n">hmac</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s">&#39;secret-shared-key-goes-here&#39;</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="n">hashlib</span><span class="o">.</span><span class="n">sha1</span><span class="p">)</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span>


<span class="k">class</span> <span class="nc">SimpleObject</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="s">&quot;A very simple class to demonstrate checking digests before unpickling.&quot;</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span>
    <span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span>
</pre></div>
</div>
<p>Next, create a <a class="reference internal" href="../StringIO/index.html#module-StringIO" title="StringIO: Work with text buffers using file-like API"><tt class="xref py py-mod docutils literal"><span class="pre">StringIO</span></tt></a> buffer to represent the socket or
pipe. We will using a naive, but easy to parse, format for the data
stream. The digest and length of the data are written, followed by a
new line. The serialized representation of the object, generated by
<a class="reference internal" href="../pickle/index.html#module-pickle" title="pickle: Python object serialization"><tt class="xref py py-mod docutils literal"><span class="pre">pickle</span></tt></a>, follows. In a real system, we would not want to depend
on a length value, since if the digest is wrong the length is probably
wrong as well. Some sort of terminator sequence not likely to appear
in the real data would be more appropriate.</p>
<p>For this example, we will write two objects to the stream. The first is
written using the correct digest value.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c"># Simulate a writable socket or pipe with StringIO</span>
<span class="n">out_s</span> <span class="o">=</span> <span class="n">StringIO</span><span class="p">()</span>

<span class="c"># Write a valid object to the stream:</span>
<span class="c">#  digest\nlength\npickle</span>
<span class="n">o</span> <span class="o">=</span> <span class="n">SimpleObject</span><span class="p">(</span><span class="s">&#39;digest matches&#39;</span><span class="p">)</span>
<span class="n">pickled_data</span> <span class="o">=</span> <span class="n">pickle</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">o</span><span class="p">)</span>
<span class="n">digest</span> <span class="o">=</span> <span class="n">make_digest</span><span class="p">(</span><span class="n">pickled_data</span><span class="p">)</span>
<span class="n">header</span> <span class="o">=</span> <span class="s">&#39;</span><span class="si">%s</span><span class="s"> </span><span class="si">%s</span><span class="s">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">digest</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">pickled_data</span><span class="p">))</span>
<span class="k">print</span> <span class="s">&#39;</span><span class="se">\n</span><span class="s">WRITING:&#39;</span><span class="p">,</span> <span class="n">header</span>
<span class="n">out_s</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">header</span> <span class="o">+</span> <span class="s">&#39;</span><span class="se">\n</span><span class="s">&#39;</span><span class="p">)</span>
<span class="n">out_s</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">pickled_data</span><span class="p">)</span>
</pre></div>
</div>
<p>The second object is written to the stream with an invalid digest, produced by
calculating the digest for some other data instead of the pickle.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c"># Write an invalid object to the stream</span>
<span class="n">o</span> <span class="o">=</span> <span class="n">SimpleObject</span><span class="p">(</span><span class="s">&#39;digest does not match&#39;</span><span class="p">)</span>
<span class="n">pickled_data</span> <span class="o">=</span> <span class="n">pickle</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">o</span><span class="p">)</span>
<span class="n">digest</span> <span class="o">=</span> <span class="n">make_digest</span><span class="p">(</span><span class="s">&#39;not the pickled data at all&#39;</span><span class="p">)</span>
<span class="n">header</span> <span class="o">=</span> <span class="s">&#39;</span><span class="si">%s</span><span class="s"> </span><span class="si">%s</span><span class="s">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">digest</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">pickled_data</span><span class="p">))</span>
<span class="k">print</span> <span class="s">&#39;</span><span class="se">\n</span><span class="s">WRITING:&#39;</span><span class="p">,</span> <span class="n">header</span>
<span class="n">out_s</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">header</span> <span class="o">+</span> <span class="s">&#39;</span><span class="se">\n</span><span class="s">&#39;</span><span class="p">)</span>
<span class="n">out_s</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">pickled_data</span><span class="p">)</span>

<span class="n">out_s</span><span class="o">.</span><span class="n">flush</span><span class="p">()</span>
</pre></div>
</div>
<p>Now that the data is in the <a class="reference internal" href="../StringIO/index.html#module-StringIO" title="StringIO: Work with text buffers using file-like API"><tt class="xref py py-mod docutils literal"><span class="pre">StringIO</span></tt></a> buffer, we can read it
back out again.  The first step is to read the line of data with the
digest and data length.  Then the remaining data is read (using the
length value). We could use <tt class="docutils literal"><span class="pre">pickle.load()</span></tt> to read directly from
the stream, but that assumes a trusted data stream and we do not yet
trust the data enough to unpickle it. Reading the pickle as a string
collect the data from the stream, without actually unpickling the
object.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c"># Simulate a readable socket or pipe with StringIO</span>
<span class="n">in_s</span> <span class="o">=</span> <span class="n">StringIO</span><span class="p">(</span><span class="n">out_s</span><span class="o">.</span><span class="n">getvalue</span><span class="p">())</span>

<span class="c"># Read the data</span>
<span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
    <span class="n">first_line</span> <span class="o">=</span> <span class="n">in_s</span><span class="o">.</span><span class="n">readline</span><span class="p">()</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="n">first_line</span><span class="p">:</span>
        <span class="k">break</span>
    <span class="n">incoming_digest</span><span class="p">,</span> <span class="n">incoming_length</span> <span class="o">=</span> <span class="n">first_line</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&#39; &#39;</span><span class="p">)</span>
    <span class="n">incoming_length</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">incoming_length</span><span class="p">)</span>
    <span class="k">print</span> <span class="s">&#39;</span><span class="se">\n</span><span class="s">READ:&#39;</span><span class="p">,</span> <span class="n">incoming_digest</span><span class="p">,</span> <span class="n">incoming_length</span>
    <span class="n">incoming_pickled_data</span> <span class="o">=</span> <span class="n">in_s</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">incoming_length</span><span class="p">)</span>
</pre></div>
</div>
<p>Once we have the pickled data, we can recalculate the digest value and
compare it against what we read. If the digests match, we know it is
safe to trust the data and unpickle it.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">actual_digest</span> <span class="o">=</span> <span class="n">make_digest</span><span class="p">(</span><span class="n">incoming_pickled_data</span><span class="p">)</span>
<span class="k">print</span> <span class="s">&#39;ACTUAL:&#39;</span><span class="p">,</span> <span class="n">actual_digest</span>

<span class="k">if</span> <span class="n">incoming_digest</span> <span class="o">!=</span> <span class="n">actual_digest</span><span class="p">:</span>
    <span class="k">print</span> <span class="s">&#39;WARNING: Data corruption&#39;</span>
<span class="k">else</span><span class="p">:</span>
    <span class="n">obj</span> <span class="o">=</span> <span class="n">pickle</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">incoming_pickled_data</span><span class="p">)</span>
    <span class="k">print</span> <span class="s">&#39;OK:&#39;</span><span class="p">,</span> <span class="n">obj</span>
</pre></div>
</div>
<p>The output shows that the first object is verified and the second is deemed
&#8220;corrupted&#8221;, as expected:</p>
<div class="highlight-python"><pre>$ python hmac_pickle.py


WRITING: 387632cfa3d18cd19bdfe72b61ac395dfcdc87c9 124

WRITING: b01b209e28d7e053408ebe23b90fe5c33bc6a0ec 131

READ: 387632cfa3d18cd19bdfe72b61ac395dfcdc87c9 124
ACTUAL: 387632cfa3d18cd19bdfe72b61ac395dfcdc87c9
OK: digest matches

READ: b01b209e28d7e053408ebe23b90fe5c33bc6a0ec 131
ACTUAL: dec53ca1ad3f4b657dd81d514f17f735628b6828
WARNING: Data corruption</pre>
</div>
<div class="admonition-see-also admonition seealso">
<p class="first admonition-title">See also</p>
<dl class="last docutils">
<dt><a class="reference external" href="http://docs.python.org/library/hmac.html">hmac</a></dt>
<dd>The standard library documentation for this module.</dd>
<dt><span class="target" id="index-2"></span><a class="rfc reference external" href="http://tools.ietf.org/html/rfc2104.html"><strong>RFC 2104</strong></a></dt>
<dd>HMAC: Keyed-Hashing for Message Authentication</dd>
<dt><a class="reference internal" href="../hashlib/index.html#module-hashlib" title="hashlib: Cryptographic hashes and message digests"><tt class="xref py py-mod docutils literal"><span class="pre">hashlib</span></tt></a></dt>
<dd>The <a class="reference internal" href="../hashlib/index.html#module-hashlib" title="hashlib: Cryptographic hashes and message digests"><tt class="xref py py-mod docutils literal"><span class="pre">hashlib</span></tt></a> module.</dd>
<dt><a class="reference internal" href="../pickle/index.html#module-pickle" title="pickle: Python object serialization"><tt class="xref py py-mod docutils literal"><span class="pre">pickle</span></tt></a></dt>
<dd>Serialization library.</dd>
<dt><a class="reference external" href="http://en.wikipedia.org/wiki/MD5">WikiPedia: MD5</a></dt>
<dd>Description of the MD5 hashing algorithm.</dd>
<dt><a class="reference external" href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?S3_Authentication.html">Authenticating to Amazon S3 Web Service</a></dt>
<dd>Instructions for authenticating to S3 using HMAC-SHA1 signed credentials.</dd>
</dl>
</div>
</div>
</div>


          </div>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../genindex.html" title="General Index"
             >index</a></li>
        <li class="right" >
          <a href="../py-modindex.html" title="Python Module Index"
             >modules</a> |</li>
        <li class="right" >
          <a href="../file_access.html" title="File and Directory Access"
             >next</a> |</li>
        <li class="right" >
          <a href="../hashlib/index.html" title="hashlib – Cryptographic hashes and message digests"
             >previous</a> |</li>
        <li><a href="../contents.html">PyMOTW</a> &raquo;</li>
          <li><a href="../cryptographic.html" >Cryptographic Services</a> &raquo;</li> 
      </ul>
    </div>
    <div class="footer">
      &copy; Copyright Doug Hellmann.
      Last updated on Oct 24, 2010.
      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a>.

    <br/><a href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/" rel="license"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-sa/3.0/us/88x31.png"/></a>
    
    </div>
  </body>
</html>

[top] / python / PyMOTW / docs / hmac / index.html

contact | logmethods.com