403Webshell
Server IP : 178.105.222.151  /  Your IP : 216.73.216.38
Web Server : nginx/1.28.3
System : Linux MNK 7.0.0-15-generic #15-Ubuntu SMP PREEMPT_DYNAMIC Wed Apr 22 16:06:43 UTC 2026 x86_64
User : www-data ( 33)
PHP Version : 8.5.4
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : OFF
Directory :  /usr/share/doc/python3-passlib/html/narr/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /usr/share/doc/python3-passlib/html/narr/totp-tutorial.html
<!DOCTYPE html>

<html lang="en" data-content_root="../">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />

    <title>TOTP Tutorial &#8212; Passlib vlatest Documentation</title>
    <link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=fa44fd50" />
    <link rel="stylesheet" type="text/css" href="../_static/classic.css?v=2bf1fcf8" />
    
    <script src="../_static/documentation_options.js?v=c6e86fd7"></script>
    <script src="../_static/doctools.js?v=9bcbadda"></script>
    <script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
    
    <link rel="icon" href="../_static/logo.ico"/>
    <link rel="index" title="Index" href="../genindex.html" />
    <link rel="search" title="Search" href="../search.html" />
    <link rel="copyright" title="Copyright" href="../copyright.html" />
    <link rel="next" title="API Reference" href="../lib/index.html" />
    <link rel="prev" title="CryptContext Tutorial" href="context-tutorial.html" /> 
  </head><body>
    <div class="related" role="navigation" aria-label="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="../lib/index.html" title="API Reference"
             accesskey="N">next</a> |</li>
        <li class="right" >
          <a href="context-tutorial.html" title="CryptContext Tutorial"
             accesskey="P">previous</a> |</li>
        <li class="nav-item nav-item-0"><a href="../contents.html">Passlib latest Documentation</a> &#187;</li>
          <li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Walkthrough &amp; Tutorials</a> &#187;</li>
        <li class="nav-item nav-item-this"><a href=""><code class="xref py py-class docutils literal notranslate"><span class="pre">TOTP</span></code> Tutorial</a></li> 
      </ul>
    </div>  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body" role="main">
            
  <section id="totp-tutorial">
<span id="index-1"></span><span id="index-0"></span><span id="id1"></span><h1><a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP" title="passlib.totp.TOTP"><code class="xref py py-class docutils literal notranslate"><span class="pre">TOTP</span></code></a> Tutorial<a class="headerlink" href="#totp-tutorial" title="Link to this heading">¶</a></h1>
<section id="overview">
<h2>Overview<a class="headerlink" href="#overview" title="Link to this heading">¶</a></h2>
<p>The <a class="reference internal" href="../lib/passlib.totp.html#module-passlib.totp" title="passlib.totp: totp / two factor authentaction"><code class="xref py py-mod docutils literal notranslate"><span class="pre">passlib.totp</span></code></a> module provides a set of classes for adding
two-factor authentication (2FA) support into your application,
using the widely supported TOTP specification (<span class="target" id="index-2"></span><a class="rfc reference external" href="https://datatracker.ietf.org/doc/html/rfc6238.html"><strong>RFC 6238</strong></a>).</p>
<p>This module is based around the <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP" title="passlib.totp.TOTP"><code class="xref py py-class docutils literal notranslate"><span class="pre">TOTP</span></code></a> class, which supports
a wide variety of use-cases, including:</p>
<blockquote>
<div><ul class="simple">
<li><p>Creating &amp; transferring configured TOTP keys to client devices.</p></li>
<li><p>Generating &amp; verifying tokens.</p></li>
<li><p>Securely storing configured TOTP keys.</p></li>
</ul>
</div></blockquote>
<div class="admonition seealso">
<p class="admonition-title">See also</p>
<p>The <a class="reference internal" href="../lib/passlib.totp.html#module-passlib.totp" title="passlib.totp: totp / two factor authentaction"><code class="xref py py-mod docutils literal notranslate"><span class="pre">passlib.totp</span></code></a> API reference,
which lists all details of all the classes and methods mentioned here.</p>
</div>
</section>
<section id="walkthrough">
<h2>Walkthrough<a class="headerlink" href="#walkthrough" title="Link to this heading">¶</a></h2>
<p>There are a number of different ways to integrate TOTP support into a server application.
The following is a general outline of one of way to do this.  Some details and
alternate choices are omitted for brevity, see the remaining sections
of this tutorial for more detailed information about these steps.</p>
<section id="generate-an-application-secret">
<span id="totp-walkthrough-step-1"></span><h3>1. Generate an Application Secret<a class="headerlink" href="#generate-an-application-secret" title="Link to this heading">¶</a></h3>
<p>First, generate a strong application secret to use when encrypting TOTP keys for storage.
Passlib offers a <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.generate_secret" title="passlib.totp.generate_secret"><code class="xref py py-meth docutils literal notranslate"><span class="pre">generate_secret()</span></code></a> method to help with this:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">passlib.totp</span> <span class="kn">import</span> <span class="n">generate_secret</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">generate_secret</span><span class="p">()</span>
<span class="go">&#39;pO7SwEFcUPvIDeAJr7INBj0TjsSZJr1d2ddsFL9r5eq&#39;</span>
</pre></div>
</div>
<p>This key should be assigned a numeric tag (e.g. “1”, a timestamp, or an iso date such as “2016-11-10”);
and should be stored in a file <em>separate</em> from your application’s configuration.
Ideally, after this file has been loaded by the TOTP constructor below,
the application should give up access permissions to the file.</p>
<p>Example file contents:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">2016</span><span class="o">-</span><span class="mi">11</span><span class="o">-</span><span class="mi">10</span><span class="p">:</span> <span class="n">pO7SwEFcUPvIDeAJr7INBj0TjsSZJr1d2ddsFL9r5eq</span>
</pre></div>
</div>
<p>This key will be used in a later step to encrypt TOTP keys for storage in your database.
The sequential tag is used so that if your database (or the application secrets)
are ever compromised, you can add a new application secret (with a newer tag),
and gracefully migrate the compromised TOTP keys.</p>
<div class="without-title float-center admonition seealso">
<p class="admonition-title">See also</p>
<p><strong>For more details see</strong> <a class="reference internal" href="#totp-encryption-setup"><span class="std std-ref">Application Secrets</span></a> (below).</p>
</div>
</section>
<section id="totp-factory-initialization">
<h3>2. TOTP Factory Initialization<a class="headerlink" href="#totp-factory-initialization" title="Link to this heading">¶</a></h3>
<p>When your application is being initialized, create a TOTP factory which is configured
for your application, and is set up to use the application secrets defined in step 1.
You can also set a default issuer here, instead of having to provide one explicitly in step 4:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">passlib.totp</span> <span class="kn">import</span> <span class="n">TOTP</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">TotpFactory</span> <span class="o">=</span> <span class="n">TOTP</span><span class="o">.</span><span class="n">using</span><span class="p">(</span><span class="n">secrets_path</span><span class="o">=</span><span class="s1">&#39;/path/to/secret/file/in/step/1&#39;</span><span class="p">,</span>
<span class="gp">... </span>                         <span class="n">issuer</span><span class="o">=</span><span class="s2">&quot;myapp.example.org&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">TotpFactory</span></code> object returned by <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP.using" title="passlib.totp.TOTP.using"><code class="xref py py-meth docutils literal notranslate"><span class="pre">TOTP.using()</span></code></a> is actually a subclass
of <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP" title="passlib.totp.TOTP"><code class="xref py py-class docutils literal notranslate"><span class="pre">TOTP</span></code></a> itself, and has the same methods and attributes.  The main difference is that (because
an application secret has been provided), the TOTP key will automatically be encrypted / decrypted
when serializing the object to disk.</p>
<div class="without-title float-center admonition seealso">
<p class="admonition-title">See also</p>
<p><strong>For more details see</strong> <a class="reference internal" href="#totp-creation"><span class="std std-ref">Creating TOTP Instances</span></a> (below).</p>
</div>
</section>
<section id="rate-limiting-cache-initialization">
<h3>3. Rate-Limiting &amp; Cache Initialization<a class="headerlink" href="#rate-limiting-cache-initialization" title="Link to this heading">¶</a></h3>
<p>As part of your application initialization, it <strong>critically important</strong> to
set up infrastructure to rate limit how many token verification
attempts a user / ip address is allowed to make, otherwise TOTP can be bypassed.</p>
<div class="without-title float-center admonition seealso">
<p class="admonition-title">See also</p>
<p><strong>For more details see</strong> <a class="reference internal" href="#totp-rate-limiting"><span class="std std-ref">Why Rate-Limiting is Critical</span></a> (below)</p>
</div>
<p class="clear">It’s also <strong>strongly recommended</strong> to set up a per-user cache which can store the last matched TOTP counter (an integer)
for a period of a few minutes (e.g. using <a class="reference external" href="https://pypi.python.org/pypi/dogpile.cache">dogpile.cache</a>,
memcached, redis, etc). This cache is used by later steps to protect your application during a narrow window of time
where TOTP would otherwise be vulnerable to a replay attack.</p>
<div class="without-title float-center admonition seealso">
<p class="admonition-title">See also</p>
<p><strong>For more details see</strong> <a class="reference internal" href="#totp-reuse-warning"><span class="std std-ref">Preventing Token Reuse</span></a> (below)</p>
</div>
</section>
<section id="setting-up-totp-for-a-user">
<h3>4. Setting up TOTP for a User<a class="headerlink" href="#setting-up-totp-for-a-user" title="Link to this heading">¶</a></h3>
<p>To set up TOTP for a new user: create a new TOTP object and key using <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP.new" title="passlib.totp.TOTP.new"><code class="xref py py-meth docutils literal notranslate"><span class="pre">TOTP.new()</span></code></a>.
This can then be rendered into a provisioning URI, and transferred to the user’s TOTP client
of choice.</p>
<p>Rendering to a provisioning URI using <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP.to_uri" title="passlib.totp.TOTP.to_uri"><code class="xref py py-meth docutils literal notranslate"><span class="pre">TOTP.to_uri()</span></code></a> requires picking an “issuer” string
to uniquely identify your application, and a “label” string to uniquely identify the user.
The following example creates a new TOTP instance with a new key,
and renders it to a URI, plugging in application-specific information.</p>
<p>Using the <code class="docutils literal notranslate"><span class="pre">TotpFactory</span></code> object set up in step 2:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">totp</span> <span class="o">=</span> <span class="n">TotpFactory</span><span class="o">.</span><span class="n">new</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">uri</span> <span class="o">=</span> <span class="n">totp</span><span class="o">.</span><span class="n">to_uri</span><span class="p">(</span><span class="n">issuer</span><span class="o">=</span><span class="s2">&quot;myapp.example.org&quot;</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="s2">&quot;username&quot;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">uri</span>
<span class="go">&#39;otpauth://totp/username?secret=D6RZI4ROAUQKJNAWQKYPN7W7LNV43GOT&amp;issuer=myapp.example.org&#39;</span>
</pre></div>
</div>
<p>This URI is generally passed to a QRCode renderer, though
as fallback it’s recommended to also display the key using <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP.pretty_key" title="passlib.totp.TOTP.pretty_key"><code class="xref py py-meth docutils literal notranslate"><span class="pre">TOTP.pretty_key()</span></code></a>.</p>
<div class="without-title float-center admonition seealso">
<p class="admonition-title">See also</p>
<p><strong>For more details, and more about QR Codes, see</strong> <a class="reference internal" href="#totp-configuring-clients"><span class="std std-ref">Configuring Clients</span></a> (below).</p>
</div>
</section>
<section id="storing-the-totp-object">
<h3>5. Storing the TOTP object<a class="headerlink" href="#storing-the-totp-object" title="Link to this heading">¶</a></h3>
<p>Before enabling TOTP for the user’s account, it’s good practice to first have the
user successfully verify a token (per step 6); thus confirming their client h
as been correctly configured.</p>
<p>Once this is done, you can store the TOTP object in your database.
This can be done via the <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP.to_json" title="passlib.totp.TOTP.to_json"><code class="xref py py-meth docutils literal notranslate"><span class="pre">TOTP.to_json()</span></code></a> method:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">totp</span><span class="o">.</span><span class="n">to_json</span><span class="p">()</span>
<span class="go">&#39;{&quot;enckey&quot;:{&quot;c&quot;:14,&quot;k&quot;:&quot;FLEQC3VO6SIT3T7GN2GIG6ONPXADG5CZ&quot;,&quot;s&quot;:&quot;UL2J4MZG4SONHOWXLKFQ&quot;,&quot;t&quot;:&quot;1&quot;,&quot;v&quot;:1},&quot;type&quot;:&quot;totp&quot;,&quot;v&quot;:1}&#39;</span>
</pre></div>
</div>
<p>Note that if there is no application secret configured, the key will not be encrypted,
and instead look like this:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">totp</span><span class="o">.</span><span class="n">to_json</span><span class="p">()</span>
<span class="go">&#39;{&quot;key&quot;:&quot;D6RZI4ROAUQKJNAWQKYPN7W7LNV43GOT&quot;,&quot;type&quot;:&quot;totp&quot;,&quot;v&quot;:1}&#39;</span>
</pre></div>
</div>
<p>To ensure you always save an encrypted token, you can use <code class="docutils literal notranslate"><span class="pre">totp.to_json(encrypted=True)</span></code>.</p>
<div class="float-center without-title admonition seealso">
<p class="admonition-title">See also</p>
<p><strong>For more details see</strong> <a class="reference internal" href="#totp-storing-instances"><span class="std std-ref">Storing TOTP instances</span></a></p>
</div>
</section>
<section id="verifying-a-token">
<h3>6. Verifying a Token<a class="headerlink" href="#verifying-a-token" title="Link to this heading">¶</a></h3>
<p>Whenever attempting to verify a token provided by the user,
first load the serialized TOTP object from the database (stored step 5),
as well as the last counter value from the cache (set up in step 3).
You should use these values to call the <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP.verify" title="passlib.totp.TOTP.verify"><code class="xref py py-meth docutils literal notranslate"><span class="pre">TOTP.verify()</span></code></a> method.</p>
<p>If verify() succeeds, it will return a <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TotpMatch" title="passlib.totp.TotpMatch"><code class="xref py py-class docutils literal notranslate"><span class="pre">TotpMatch</span></code></a> object.
This object contains information about the match,
including <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TotpMatch.counter" title="passlib.totp.TotpMatch.counter"><code class="xref py py-attr docutils literal notranslate"><span class="pre">TotpMatch.counter</span></code></a> (a time-dependant integer tied to this token),
and <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TotpMatch.cache_seconds" title="passlib.totp.TotpMatch.cache_seconds"><code class="xref py py-attr docutils literal notranslate"><span class="pre">TotpMatch.cache_seconds</span></code></a> (minimum time this counter should be cached).</p>
<p>If verify() fails, it will raise one of the <a class="reference internal" href="../lib/passlib.exc.html#passlib.exc.TokenError" title="passlib.exc.TokenError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">passlib.exc.TokenError</span></code></a> subclasses
indicating what went wrong. This will be one of three cases: the token was
malformed (e.g. too few digits), the token was invalid (didn’t match),
or a recent token was reused.</p>
<p>A skeleton example of how this should function:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">passlib.exc</span> <span class="kn">import</span> <span class="n">TokenError</span><span class="p">,</span> <span class="n">MalformedTokenError</span>

<span class="gp">&gt;&gt;&gt; </span><span class="c1"># pull information from your application</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">token</span> <span class="o">=</span> <span class="c1"># ... token string provided by user ...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">source</span> <span class="o">=</span> <span class="c1"># ... load totp json string from database ...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">last_counter</span> <span class="o">=</span> <span class="c1"># ... load counter value from cache ...</span>

<span class="gp">&gt;&gt;&gt; </span><span class="c1"># ... check attempt rate limit for this account / address (per step 3 above) ...</span>

<span class="gp">&gt;&gt;&gt; </span><span class="c1"># using the TotpFactory object defined in step 2, invoke verify</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">try</span><span class="p">:</span>
<span class="gp">... </span>    <span class="n">match</span> <span class="o">=</span> <span class="n">TotpFactory</span><span class="o">.</span><span class="n">verify</span><span class="p">(</span><span class="n">token</span><span class="p">,</span> <span class="n">source</span><span class="p">,</span> <span class="n">last_counter</span><span class="o">=</span><span class="n">last_counter</span><span class="p">)</span>
<span class="gp">... </span><span class="k">except</span> <span class="n">MalformedTokenError</span> <span class="k">as</span> <span class="n">err</span><span class="p">:</span>
<span class="gp">... </span>    <span class="c1"># --- malformed token ---</span>
<span class="gp">... </span>    <span class="c1"># * inform user, e.g. by displaying str(err)</span>
<span class="gp">... </span><span class="k">except</span> <span class="n">TokenError</span> <span class="k">as</span> <span class="n">err</span><span class="p">:</span>
<span class="gp">... </span>    <span class="c1"># --- invalid or reused token ---</span>
<span class="gp">... </span>    <span class="c1"># * add to rate limit counter</span>
<span class="gp">... </span>    <span class="c1"># * inform user, e.g. by displaying str(err)</span>
<span class="gp">... </span><span class="k">else</span><span class="p">:</span>
<span class="gp">... </span>    <span class="c1"># --- successful match ---</span>
<span class="gp">... </span>    <span class="c1"># * reset rate-limit counter</span>
<span class="gp">... </span>    <span class="c1"># * store &#39;match.counter&#39; in per-user cache for at least &#39;match.cache_seconds&#39;</span>
</pre></div>
</div>
<div class="float-center without-title admonition seealso">
<p class="admonition-title">See also</p>
<p><strong>For more details see</strong> <a class="reference internal" href="#totp-verifying"><span class="std std-ref">Verifying Tokens</span></a> (below)</p>
</div>
<section class="html-toggle" id="alternate-caching-strategy">
<h4>Alternate Caching Strategy<a class="headerlink" href="#alternate-caching-strategy" title="Link to this heading">¶</a></h4>
<p>As an alternative to storing <code class="docutils literal notranslate"><span class="pre">match.counter</span></code> in the cache,
applications using a cache such as memcached may wish to simply set a key
based on <code class="docutils literal notranslate"><span class="pre">user</span> <span class="pre">+</span> <span class="pre">token</span></code> for <code class="docutils literal notranslate"><span class="pre">match.cache_seconds</span></code>, and reject any
tokens coming in for that user who are marked in the cache.</p>
<p>In that case, they should run the tokens through <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP.normalize_token" title="passlib.totp.TOTP.normalize_token"><code class="xref py py-meth docutils literal notranslate"><span class="pre">TOTP.normalize_token()</span></code></a>
first, to make sure the token strings are normalized before comparison.
In this case, the skeleton example can be amended to:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="c1"># pull information from your application</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">token</span> <span class="o">=</span> <span class="c1"># ... token string provided by user ...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">source</span> <span class="o">=</span> <span class="c1"># ... load totp json string from database ...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">user_id</span> <span class="o">=</span> <span class="c1"># ... user identifier for cache</span>

<span class="gp">&gt;&gt;&gt; </span><span class="c1"># ... check attempt rate limit for this account / address (per step 3 above) ...</span>

<span class="gp">&gt;&gt;&gt; </span><span class="c1"># check token format</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">try</span><span class="p">:</span>
<span class="gp">... </span>    <span class="n">token</span> <span class="o">=</span> <span class="n">TotpFactory</span><span class="o">.</span><span class="n">normalize_token</span><span class="p">(</span><span class="n">token</span><span class="p">)</span>
<span class="gp">... </span><span class="k">except</span> <span class="n">MalformedTokenError</span> <span class="k">as</span> <span class="n">err</span><span class="p">:</span>
<span class="gp">... </span>    <span class="c1"># --- malformed token ---</span>
<span class="gp">... </span>    <span class="c1"># * inform user, e.g. by displaying str(err)</span>
<span class="gp">... </span>    <span class="k">return</span>

<span class="gp">&gt;&gt;&gt; </span><span class="c1"># check if token has been used, using app-defined present_in_cache() helper</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">cache_key</span> <span class="o">=</span> <span class="s2">&quot;totp-token-</span><span class="si">%s</span><span class="s2">-</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">user_id</span><span class="p">,</span> <span class="n">token</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">if</span> <span class="n">present_in_cache</span><span class="p">(</span><span class="n">cache_key</span><span class="p">):</span>
<span class="gp">... </span>    <span class="c1"># * add to rate limit counter</span>
<span class="gp">... </span>    <span class="c1"># * present &#39;token already used&#39; message</span>
<span class="gp">... </span>    <span class="k">return</span>

<span class="gp">&gt;&gt;&gt; </span><span class="c1"># using the TotpFactory object defined in step 2, invoke verify</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">try</span><span class="p">:</span>
<span class="gp">... </span>    <span class="n">match</span> <span class="o">=</span> <span class="n">TotpFactory</span><span class="o">.</span><span class="n">verify</span><span class="p">(</span><span class="n">token</span><span class="p">,</span> <span class="n">source</span><span class="p">)</span>
<span class="gp">... </span><span class="k">except</span> <span class="n">TokenError</span> <span class="k">as</span> <span class="n">err</span><span class="p">:</span>
<span class="gp">... </span>    <span class="c1"># --- invalid token ---</span>
<span class="gp">... </span>    <span class="c1"># * add to rate limit counter</span>
<span class="gp">... </span>    <span class="c1"># * inform user, e.g. by displaying str(err)</span>
<span class="gp">... </span><span class="k">else</span><span class="p">:</span>
<span class="gp">... </span>    <span class="c1"># --- successful match ---</span>
<span class="gp">... </span>    <span class="c1"># * reset rate-limit counter</span>
<span class="gp">... </span>    <span class="c1"># * set &#39;cache_key&#39; in per-user cache for at least &#39;match.cache_seconds&#39;</span>
</pre></div>
</div>
</section>
</section>
<section id="reserializing-existing-objects">
<h3>7. Reserializing Existing Objects<a class="headerlink" href="#reserializing-existing-objects" title="Link to this heading">¶</a></h3>
<p>An organization’s security policy may require that a developer periodically
change the application secret key used to decrypt/encrypt TOTP objects.
Alternately, the application secret may become compromised.</p>
<p>In either case, a new application secret will need to be created, and a new tag assigned
(per step 1).  Any deprecated secret(s) will need to be retained in the collection passed to the <code class="docutils literal notranslate"><span class="pre">TotpFactory</span></code>,
in order to be able to decrypt existing TOTP objects.</p>
<div class="float-right admonition note">
<p class="admonition-title">Note</p>
<p>You can verify which secret is will be used
to encrypt new keys by inspecting <code class="docutils literal notranslate"><span class="pre">tag</span> <span class="pre">=</span> <span class="pre">TotpFactory.wallet.default_tag</span></code>.</p>
</div>
<p class="clear">Once the new secret has been added, you will need to update all the serialized TOTP objects in the database,
decrypting them using the old secret, and encrypting them with the new one.</p>
<p>This can be done in a few ways.  The following skeleton example gives a simple loop that can be used,
which would ideally be run in a process that’s separate from your normal application:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="c1"># presuming query_user_totp() queries your database for all user rows,</span>
<span class="gp">&gt;&gt;&gt; </span><span class="c1"># and update_user_totp() updates a specific row.</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">for</span> <span class="n">user_id</span><span class="p">,</span> <span class="n">totp_source</span> <span class="ow">in</span> <span class="n">query_user_totp</span><span class="p">():</span>
<span class="gp">&gt;&gt;&gt; </span>    <span class="n">totp</span> <span class="o">=</span> <span class="n">TotpFactory</span><span class="o">.</span><span class="n">from_source</span><span class="p">(</span><span class="n">totp_source</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span>    <span class="k">if</span> <span class="n">totp</span><span class="o">.</span><span class="n">changed</span><span class="p">:</span>
<span class="gp">&gt;&gt;&gt; </span>        <span class="n">update_user_totp</span><span class="p">(</span><span class="n">user_id</span><span class="p">,</span> <span class="n">totp</span><span class="o">.</span><span class="n">to_json</span><span class="p">())</span>
</pre></div>
</div>
<p>This uses the <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP.changed" title="passlib.totp.TOTP.changed"><code class="xref py py-attr docutils literal notranslate"><span class="pre">TOTP.changed</span></code></a> attribute, which is set to <code class="docutils literal notranslate"><span class="pre">True</span></code> if
<a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP.from_source" title="passlib.totp.TOTP.from_source"><code class="xref py py-meth docutils literal notranslate"><span class="pre">TOTP.from_source()</span></code></a> (or other constructor) detects the source data is
encrypted with an old secret, is using outdated encryption settings,
or is stored in deprecated serialization format.</p>
<p>Some refinements that may need to be made for specific situations:</p>
<ul class="simple">
<li><p>For applications with a large number of users, it may be faster to accumulate <code class="docutils literal notranslate"><span class="pre">(user_id,</span> <span class="pre">totp.to_json())</span></code>
pairs in a buffer, and do a bulk SQL update once every 100-1000 rows.</p></li>
<li><p>Depending on the dbapi layer in use, it may take care of JSON serialization for you,
in which case you’ll need to use <code class="docutils literal notranslate"><span class="pre">totp.to_dict()</span></code> instead of <code class="docutils literal notranslate"><span class="pre">totp.to_json()</span></code>.</p></li>
</ul>
<p>Once all references to a deprecated secret have been replaced,
it can be removed from the secrets file.</p>
<div class="float-center without-title admonition seealso">
<p class="admonition-title">See also</p>
<p><strong>For more details see</strong> <a class="reference internal" href="#totp-walkthrough-step-1"><span class="std std-ref">Step 1</span></a> (above), or <a class="reference internal" href="#totp-encryption-setup"><span class="std std-ref">Application Secrets</span></a> (below)</p>
</div>
</section>
</section>
<section id="creating-totp-instances">
<span id="totp-creation"></span><h2>Creating TOTP Instances<a class="headerlink" href="#creating-totp-instances" title="Link to this heading">¶</a></h2>
<section id="direct-creation">
<h3>Direct Creation<a class="headerlink" href="#direct-creation" title="Link to this heading">¶</a></h3>
<p>Creating TOTP instances is straightforward:
The <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP" title="passlib.totp.TOTP"><code class="xref py py-class docutils literal notranslate"><span class="pre">TOTP</span></code></a> class can be called directly to constructor a TOTP instance
from it’s component configuration:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">passlib.totp</span> <span class="kn">import</span> <span class="n">TOTP</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">totp</span> <span class="o">=</span> <span class="n">TOTP</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="s1">&#39;GVDOQ7NP6XPJWE4CWCLFFSXZH6DTAZWM&#39;</span><span class="p">,</span> <span class="n">digits</span><span class="o">=</span><span class="mi">9</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">totp</span><span class="o">.</span><span class="n">generate</span><span class="p">()</span>
<span class="go">&#39;29387414&#39;</span>
</pre></div>
</div>
<p>You can also use a number of the alternate constructors,
such as <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP.new" title="passlib.totp.TOTP.new"><code class="xref py py-meth docutils literal notranslate"><span class="pre">TOTP.new()</span></code></a> or <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP.from_source" title="passlib.totp.TOTP.from_source"><code class="xref py py-meth docutils literal notranslate"><span class="pre">TOTP.from_source()</span></code></a>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="c1"># create new instance w/ automatically generated key</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">totp</span> <span class="o">=</span> <span class="n">TOTP</span><span class="o">.</span><span class="n">new</span><span class="p">()</span>

<span class="gp">&gt;&gt;&gt; </span><span class="c1"># or deserializing it from a string (e.g. the output of TOTP.to_json)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">totp</span> <span class="o">=</span> <span class="n">TOTP</span><span class="o">.</span><span class="n">from_source</span><span class="p">(</span><span class="s1">&#39;{&quot;key&quot;:&quot;D6RZI4ROAUQKJNAWQKYPN7W7LNV43GOT&quot;,&quot;type&quot;:&quot;totp&quot;,&quot;v&quot;:1}&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>Once created, you can inspect the object for it’s configuration and key:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">otp</span><span class="o">.</span><span class="n">base32_key</span>
<span class="go">&#39;GVDOQ7NP6XPJWE4CWCLFFSXZH6DTAZWM&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">otp</span><span class="o">.</span><span class="n">alg</span>
<span class="go">&quot;sha1&quot;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">otp</span><span class="o">.</span><span class="n">period</span>
<span class="go">30</span>
</pre></div>
</div>
<p>If you want a non-standard alg or period, you can specify it via the constructor.
You can also create TOTP instances from an existing key
(see the <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP" title="passlib.totp.TOTP"><code class="xref py py-class docutils literal notranslate"><span class="pre">TOTP</span></code></a> constructor’s <code class="docutils literal notranslate"><span class="pre">key</span></code> and <code class="docutils literal notranslate"><span class="pre">format</span></code> options for more details):</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">otp2</span> <span class="o">=</span> <span class="n">TOTP</span><span class="p">(</span><span class="n">new</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">period</span><span class="o">=</span><span class="mi">60</span><span class="p">,</span> <span class="n">alg</span><span class="o">=</span><span class="s2">&quot;sha256&quot;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">otp2</span><span class="o">.</span><span class="n">alg</span>
<span class="go">&#39;sha256&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">otp2</span><span class="o">.</span><span class="n">period</span>
<span class="go">60</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">otp3</span> <span class="o">=</span> <span class="n">TOTP</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="s1">&#39;GVDOQ7NP6XPJWE4CWCLFFSXZH6DTAZWM&#39;</span><span class="p">)</span>
</pre></div>
</div>
</section>
<section id="using-a-factory">
<h3>Using a Factory<a class="headerlink" href="#using-a-factory" title="Link to this heading">¶</a></h3>
<p>Most applications will have some default configuration which they want
all TOTP instances to have.  This includes application secrets (for encrypting
TOTP keys for storage), or setting a default issuer label (for rendering URIs).</p>
<p>Instead of having to call the <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP" title="passlib.totp.TOTP"><code class="xref py py-class docutils literal notranslate"><span class="pre">TOTP</span></code></a> constructor each time and provide
all these options, you can use the <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP.using" title="passlib.totp.TOTP.using"><code class="xref py py-meth docutils literal notranslate"><span class="pre">TOTP.using()</span></code></a> method.
This method takes in a number of the same options as the TOTP constructor,
and returns a <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP" title="passlib.totp.TOTP"><code class="xref py py-class docutils literal notranslate"><span class="pre">TOTP</span></code></a> subclass which has these options pre-programmed
in as defaults:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="c1"># here we create a TOTP factory with a random encryption secret and a default issuer</span>
<span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">passlib.totp</span> <span class="kn">import</span> <span class="n">TOTP</span><span class="p">,</span> <span class="n">generate_secret</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">TotpFactory</span> <span class="o">=</span> <span class="n">TOTP</span><span class="o">.</span><span class="n">using</span><span class="p">(</span><span class="n">issuer</span><span class="o">=</span><span class="s2">&quot;myapp.example.org&quot;</span><span class="p">,</span> <span class="n">secrets</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;1&quot;</span><span class="p">:</span> <span class="n">generate_secret</span><span class="p">()})</span>
</pre></div>
</div>
<p>Since this object is a subclass of <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP" title="passlib.totp.TOTP"><code class="xref py py-class docutils literal notranslate"><span class="pre">TOTP</span></code></a>, you can use all it’s normal
methods.  The difference is that it will integrate the information provided by using():</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">totp</span> <span class="o">=</span> <span class="n">TotpFactory</span><span class="o">.</span><span class="n">new</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">totp</span><span class="o">.</span><span class="n">issuer</span>
<span class="go">&#39;myapp.example.org&#39;</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">totp</span><span class="o">.</span><span class="n">to_json</span><span class="p">()</span>
<span class="go">&#39;{&quot;enckey&quot;:{&quot;c&quot;:14,&quot;k&quot;:&quot;FLEQC3VO6SIT3T7GN2GIG6ONPXADG5CZ&quot;,&quot;s&quot;:&quot;UL2J4MZG4SONHOWXLKFQ&quot;,&quot;t&quot;:&quot;1&quot;,&quot;v&quot;:1},&quot;type&quot;:&quot;totp&quot;,&quot;v&quot;:1}&#39;</span>
</pre></div>
</div>
<p>In typical usage, a server application will want to create a TotpFactory
as part of it’s initialization, and then use that class for all operations,
instead of referencing <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP" title="passlib.totp.TOTP"><code class="xref py py-class docutils literal notranslate"><span class="pre">TOTP</span></code></a> directly.</p>
<div class="float-center admonition seealso">
<p class="admonition-title">See also</p>
<ul class="simple">
<li><p><a class="reference internal" href="#totp-configuring-clients"><span class="std std-ref">Configuring Clients</span></a> for details about the <code class="docutils literal notranslate"><span class="pre">issuer</span></code> option</p></li>
<li><p><a class="reference internal" href="#totp-storing-instances"><span class="std std-ref">Storing TOTP instances</span></a> for details about storage and key encryption</p></li>
</ul>
</div>
</section>
</section>
<section id="configuring-clients">
<span id="totp-configuring-clients"></span><h2>Configuring Clients<a class="headerlink" href="#configuring-clients" title="Link to this heading">¶</a></h2>
<p>Once a TOTP instance &amp; key has been generated on the server,
it needs to be transferred to the client TOTP program for installation.
This can be done by having the user manually type the key into their TOTP client,
but an easier method is to render the TOTP configuration to a URI stored in a QR Code.</p>
<section id="rendering-uris">
<h3>Rendering URIs<a class="headerlink" href="#rendering-uris" title="Link to this heading">¶</a></h3>
<p>The <a class="reference external" href="https://github.com/google/google-authenticator/wiki/Key-Uri-Format">KeyUriFormat</a>
is a de facto standard for encoding TOTP keys &amp; configuration
information into a string.  Once the URI is rendered as a QR Code,
it can easily be imported into many smartphone clients (such as Authy and Google Authenticator)
via the smartphone’s camera.</p>
<p>When transferring the TOTP configuration this way, you will need to provide unique identifiers
for both your application, and the user’s account.  This allows TOTP clients to distinguish
this key from the others in it’s database.  This can be done via the <code class="docutils literal notranslate"><span class="pre">issuer</span></code> and <code class="docutils literal notranslate"><span class="pre">label</span></code>
parameters of the <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP.to_uri" title="passlib.totp.TOTP.to_uri"><code class="xref py py-meth docutils literal notranslate"><span class="pre">TOTP.to_uri()</span></code></a> method.</p>
<p>The <code class="docutils literal notranslate"><span class="pre">issuer</span></code> string should be a globally unique label for your application
(e.g. it’s domain name).  Since the issuer string shouldn’t change across users,
you can create a customized TOTP factory, and provide it with a default issuer.
<em>(If you skip this step, the issuer will need to be provided at every</em>
<a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP.to_uri" title="passlib.totp.TOTP.to_uri"><code class="xref py py-meth docutils literal notranslate"><span class="pre">TOTP.to_uri()</span></code></a> <em>call)</em>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">passlib.totp</span> <span class="kn">import</span> <span class="n">TOTP</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">TotpFactory</span> <span class="o">=</span> <span class="n">TOTP</span><span class="o">.</span><span class="n">using</span><span class="p">(</span><span class="n">issuer</span><span class="o">=</span><span class="s2">&quot;myapp.example.org&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>Once this is done, rendering to a provisioning URI just requires
picking a <code class="docutils literal notranslate"><span class="pre">label</span></code> for the URI.  This label should identify the user
within your application (e.g. their login or their email):</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="c1"># assume an existing TOTP instance has been created</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">totp</span> <span class="o">=</span> <span class="n">TotpFactory</span><span class="o">.</span><span class="n">new</span><span class="p">()</span>

<span class="gp">&gt;&gt;&gt; </span><span class="c1"># serialize the object to a URI, along with label for user</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">uri</span> <span class="o">=</span> <span class="n">totp</span><span class="o">.</span><span class="n">to_uri</span><span class="p">(</span><span class="n">label</span><span class="o">=</span><span class="s2">&quot;demo-user&quot;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">uri</span>
<span class="go">&#39;otpauth://totp/demo-user?secret=GVDOQ7NP6XPJWE4CWCLFFSXZH6DTAZWM&amp;issuer=myapp.example.org&#39;</span>
</pre></div>
</div>
</section>
<section id="rendering-qr-codes">
<h3>Rendering QR Codes<a class="headerlink" href="#rendering-qr-codes" title="Link to this heading">¶</a></h3>
<p>This URI can then be encoded as a QR Code, using various python &amp; javascript qrcode libraries.
As an example, the following uses <a class="reference external" href="https://pypi.python.org/pypi/PyQRCode">PyQrCode</a>
to render the URI to the console as a text-based QR code:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">pyqrcode</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">uri</span> <span class="o">=</span> <span class="n">totp</span><span class="o">.</span><span class="n">to_uri</span><span class="p">(</span><span class="n">label</span><span class="o">=</span><span class="s2">&quot;demo-user&quot;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">print</span><span class="p">(</span><span class="n">pyqrcode</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">uri</span><span class="p">)</span><span class="o">.</span><span class="n">terminal</span><span class="p">(</span><span class="n">quiet_zone</span><span class="o">=</span><span class="mi">1</span><span class="p">))</span>
<span class="gp">... </span><span class="n">very</span> <span class="n">large</span> <span class="n">ascii</span><span class="o">-</span><span class="n">art</span> <span class="n">qrcode</span> <span class="n">here</span><span class="o">...</span>
</pre></div>
</div>
<p>As a fallback to the QR Code, it’s recommended to alternately / also display
the key itself, so that users with camera-less TOTP clients can still enter it.
The <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP.pretty_key" title="passlib.totp.TOTP.pretty_key"><code class="xref py py-meth docutils literal notranslate"><span class="pre">TOTP.pretty_key()</span></code></a> method is provided to help with this:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">totp</span><span class="o">.</span><span class="n">pretty_key</span><span class="p">()</span>
<span class="go">&#39;D6RZ-I4RO-AUQK-JNAW-QKYP-N7W7-LNV4-3GOT&#39;</span>
</pre></div>
</div>
<p>Note that if you use a non-default <code class="docutils literal notranslate"><span class="pre">alg</span></code>, <code class="docutils literal notranslate"><span class="pre">digits</span></code>, or <code class="docutils literal notranslate"><span class="pre">period</span></code> values,
these should also be displayed next to the key.</p>
</section>
<section id="parsing-uris">
<h3>Parsing URIs<a class="headerlink" href="#parsing-uris" title="Link to this heading">¶</a></h3>
<p>On the client side, passlib offers the <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP.from_uri" title="passlib.totp.TOTP.from_uri"><code class="xref py py-meth docutils literal notranslate"><span class="pre">TOTP.from_uri()</span></code></a> constructor creating
a TOTP object from a provisioning URI.  This can also be useful for testing URI encoding &amp; output
during development:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="c1"># create new TOTP instance from a provisioning uri:</span>
<span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">passlib.totp</span> <span class="kn">import</span> <span class="n">TOTP</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">totp</span> <span class="o">=</span> <span class="n">TOTP</span><span class="o">.</span><span class="n">from_uri</span><span class="p">(</span><span class="s1">&#39;otpauth://totp/demo-user?secret=GVDOQ7NP6XPJWE4CWCLFFSXZH6DTAZWM&amp;issuer=myapp.example.org&#39;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">otp</span><span class="o">.</span><span class="n">base32_key</span>
<span class="go">&#39;GVDOQ7NP6XPJWE4CWCLFFSXZH6DTAZWM&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">otp</span><span class="o">.</span><span class="n">alg</span>
<span class="go">&quot;sha1&quot;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">otp</span><span class="o">.</span><span class="n">period</span>
<span class="go">30</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">otp</span><span class="o">.</span><span class="n">generate</span><span class="p">()</span><span class="o">.</span><span class="n">token</span>
<span class="go">&#39;897453&#39;</span>
</pre></div>
</div>
</section>
</section>
<section id="storing-totp-instances">
<span id="totp-storing-instances"></span><h2>Storing TOTP instances<a class="headerlink" href="#storing-totp-instances" title="Link to this heading">¶</a></h2>
<p>Once a TOTP object has been created, it inevitably needs to be stored
in a database.  Using <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP.to_uri" title="passlib.totp.TOTP.to_uri"><code class="xref py py-meth docutils literal notranslate"><span class="pre">to_uri()</span></code></a> to serialize it to a URI
has a few disadvantages - it always includes an issuer &amp; a label
(wasting storage space), and it stores the key in an unencrypted format.</p>
<section id="json-serialization">
<h3>JSON Serialization<a class="headerlink" href="#json-serialization" title="Link to this heading">¶</a></h3>
<p>To help with this passlib offers a way to serialize TOTP objects to and from
a simple JSON format, which can optionally encrypt the keys for storage.</p>
<p>To serialize a TOTP object to a string, use <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP.to_json" title="passlib.totp.TOTP.to_json"><code class="xref py py-meth docutils literal notranslate"><span class="pre">TOTP.to_json()</span></code></a>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">passlib.totp</span> <span class="kn">import</span> <span class="n">TOTP</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">totp</span> <span class="o">=</span> <span class="n">TOTP</span><span class="o">.</span><span class="n">new</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">data</span> <span class="o">=</span> <span class="n">totp</span><span class="o">.</span><span class="n">to_json</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">data</span>
<span class="go">&#39;{&quot;key&quot;:&quot;GVDOQ7NP6XPJWE4CWCLFFSXZH6DTAZWM&quot;,&quot;type&quot;:&quot;totp&quot;,&quot;v&quot;:1}&#39;</span>
</pre></div>
</div>
<p>This string can be stored in a database, and then deserialized as needed
using the <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP.from_json" title="passlib.totp.TOTP.from_json"><code class="xref py py-meth docutils literal notranslate"><span class="pre">TOTP.from_json()</span></code></a> constructor:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">totp2</span> <span class="o">=</span> <span class="n">TOTP</span><span class="o">.</span><span class="n">from_json</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">totp2</span><span class="o">.</span><span class="n">base32_key</span>
<span class="go">&#39;GVDOQ7NP6XPJWE4CWCLFFSXZH6DTAZWM&#39;</span>
</pre></div>
</div>
<p>There are also corresponding <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP.to_dict" title="passlib.totp.TOTP.to_dict"><code class="xref py py-meth docutils literal notranslate"><span class="pre">TOTP.to_dict()</span></code></a> and <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP.from_dict" title="passlib.totp.TOTP.from_dict"><code class="xref py py-meth docutils literal notranslate"><span class="pre">TOTP.from_dict()</span></code></a>
methods for applications that want to serialize the object without converting
it all the way into a JSON string.</p>
<div class="float-center admonition caution">
<p class="admonition-title">Caution</p>
<p>The above procedure should only be used for development purposes,
as it will NOT encrypt the keys; and the IETF <strong>strongly recommends</strong>
encrypting the keys for storage (<a class="reference external" href="https://tools.ietf.org/html/rfc6238#section-5.1">RFC-6238 sec 5.1</a>).
Encrypting the keys is covered below.</p>
</div>
</section>
<section id="application-secrets">
<span id="totp-encryption-setup"></span><h3>Application Secrets<a class="headerlink" href="#application-secrets" title="Link to this heading">¶</a></h3>
<p>The one thing lacking about the example above is that the resulting
data contained the plaintext key.  If the server were compromised,
the TOTP keys could be used directly to impersonate the user.
To solve this, Passlib offers a method for providing an application-wide
secret that <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP.to_json" title="passlib.totp.TOTP.to_json"><code class="xref py py-meth docutils literal notranslate"><span class="pre">TOTP.to_json()</span></code></a> will use to encrypt keys.</p>
<p>Per <a class="reference internal" href="#totp-walkthrough-step-1"><span class="std std-ref">Step 1</span></a> of the walkthrough (above),
applications can use the <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.generate_secret" title="passlib.totp.generate_secret"><code class="xref py py-func docutils literal notranslate"><span class="pre">generate_secret()</span></code></a> helper to create new secrets.
All existing secrets (the current one, and any deprecated / compromised ones)
should be assigned an identifying tag, and stored in a dict or file.</p>
<p>Ideally, these secrets should be stored in a location which the application’s process
does not have access to once it has been initialized.  Once this data is loaded,
applications can create a factory function using <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP.using" title="passlib.totp.TOTP.using"><code class="xref py py-meth docutils literal notranslate"><span class="pre">TOTP.using()</span></code></a>,
and provide these secrets as part of it’s arguments.
This can take the form of a file path, a loaded string, or a dictionary:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="c1"># load from dict</span>
<span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">passlib.totp</span> <span class="kn">import</span> <span class="n">TOTP</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">TotpFactory</span> <span class="o">=</span> <span class="n">TOTP</span><span class="o">.</span><span class="n">using</span><span class="p">(</span><span class="n">secrets</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;1&quot;</span><span class="p">:</span> <span class="s2">&quot;&#39;pO7SwEFcUPvIDeAJr7INBj0TjsSZJr1d2ddsFL9r5eq&#39;&quot;</span><span class="p">})</span>

<span class="gp">&gt;&gt;&gt; </span><span class="c1"># load from filepath</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">TotpFactory</span> <span class="o">=</span> <span class="n">TOTP</span><span class="o">.</span><span class="n">using</span><span class="p">(</span><span class="n">secrets_path</span><span class="o">=</span><span class="s2">&quot;/path/to/secret/file&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">secrets</span></code> and <code class="docutils literal notranslate"><span class="pre">secrets_path</span></code> values can be anything accepted
by the <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.AppWallet" title="passlib.totp.AppWallet"><code class="xref py py-class docutils literal notranslate"><span class="pre">AppWallet</span></code></a> constructor (the internal class that’s
used to load &amp; store the application secrets in memory).  An instance
of this object is accessible for inspection from the <code class="xref py py-attr docutils literal notranslate"><span class="pre">TOTP.wallet</span></code> attribute
of each factory:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">TotpFactory</span><span class="o">.</span><span class="n">wallet</span>
<span class="go">&lt;passlib.totp.AppWallet at 0x2ba5310&gt;</span>
</pre></div>
</div>
</section>
<section id="encrypting-keys">
<h3>Encrypting Keys<a class="headerlink" href="#encrypting-keys" title="Link to this heading">¶</a></h3>
<p>Once you have a TOTP factory configured with one or more application secrets,
any objects you create through the factory will automatically have access
to the application secrets, and will use them to encrypt the key when
serializing to json.</p>
<p>Assuming <code class="docutils literal notranslate"><span class="pre">TotpFactory</span></code> is set up from the previous step,
contrast the output of this with the plain JSON serialization example above:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">totp</span> <span class="o">=</span> <span class="n">TotpFactory</span><span class="o">.</span><span class="n">new</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">data</span> <span class="o">=</span> <span class="n">totp</span><span class="o">.</span><span class="n">to_json</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">data</span>
<span class="go">&#39;{&quot;enckey&quot;:{&quot;c&quot;:14,&quot;k&quot;:&quot;FLEQC3VO6SIT3T7GN2GIG6ONPXADG5CZ&quot;,&quot;s&quot;:&quot;UL2J4MZG4SONHOWXLKFQ&quot;,&quot;t&quot;:&quot;1&quot;,&quot;v&quot;:1},&quot;type&quot;:&quot;totp&quot;,&quot;v&quot;:1}&#39;</span>
</pre></div>
</div>
<p>This data can be stored in the database like normal, but
will require access to the application secret in order to decrypt:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">data</span> <span class="o">=</span> <span class="s1">&#39;{&quot;enckey&quot;:{&quot;c&quot;:14,&quot;k&quot;:&quot;FLEQC3VO6SIT3T7GN2GIG6ONPXADG5CZ&quot;,&quot;s&quot;:&quot;UL2J4MZG4SONHOWXLKFQ&quot;,&quot;t&quot;:&quot;1&quot;,&quot;v&quot;:1},&quot;type&quot;:&quot;totp&quot;,&quot;v&quot;:1}&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">totp</span> <span class="o">=</span> <span class="n">TotpFactory</span><span class="o">.</span><span class="n">from_source</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">totp</span><span class="o">.</span><span class="n">base32_key</span>
<span class="go">&#39;FLEQC3VO6SIT3T7GN2GIG6ONPXADG5CZ&#39;</span>
</pre></div>
</div>
<p>Whereas trying to decode without a secret configured will result in:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">totp</span> <span class="o">=</span> <span class="n">TOTP</span><span class="o">.</span><span class="n">from_source</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
<span class="gp">...</span>
<span class="go">TypeError: no application secrets present, can&#39;t decrypt TOTP key</span>
</pre></div>
</div>
<p>Note that when loading TOTP objects this way, you can check the <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP.changed" title="passlib.totp.TOTP.changed"><code class="xref py py-attr docutils literal notranslate"><span class="pre">TOTP.changed</span></code></a>
attr to see if the object needs to be re-serialized (e.g. deprecated secret,
too few encryption rounds, deprecated serialization format).</p>
</section>
</section>
<section id="generating-tokens-client-side-only">
<h2>Generating Tokens (Client-Side Only)<a class="headerlink" href="#generating-tokens-client-side-only" title="Link to this heading">¶</a></h2>
<p>Finally, the whole point of TOTP: generating and verifying tokens.
The TOTP protocol generates a new time &amp; key -dependant token every &lt;period&gt; seconds (usually 30).</p>
<p>Generating a totp token is done with the <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP.generate" title="passlib.totp.TOTP.generate"><code class="xref py py-meth docutils literal notranslate"><span class="pre">TOTP.generate()</span></code></a> method,
which returns a <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TotpToken" title="passlib.totp.TotpToken"><code class="xref py py-class docutils literal notranslate"><span class="pre">TotpToken</span></code></a> instance.  This object looks and acts
like a tuple of <code class="docutils literal notranslate"><span class="pre">(token,</span> <span class="pre">expire_time)</span></code>, but offers some additional
informational attributes:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">passlib</span> <span class="kn">import</span> <span class="n">totp</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">otp</span> <span class="o">=</span> <span class="n">TOTP</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="s1">&#39;GVDOQ7NP6XPJWE4CWCLFFSXZH6DTAZWM&#39;</span><span class="p">)</span>

<span class="gp">&gt;&gt;&gt; </span><span class="c1"># generate a TOTP token for the current timestamp</span>
<span class="gp">&gt;&gt;&gt; </span><span class="c1"># (your output will vary based on system time)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">otp</span><span class="o">.</span><span class="n">generate</span><span class="p">()</span>
<span class="go">&lt;TotpToken token=&#39;589720&#39; expire_time=1475342400&gt;</span>

<span class="gp">&gt;&gt;&gt; </span><span class="c1"># to get just the token, not the TotpToken instance...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">otp</span><span class="o">.</span><span class="n">generate</span><span class="p">()</span><span class="o">.</span><span class="n">token</span>
<span class="go">&#39;359275&#39;</span>

<span class="gp">&gt;&gt;&gt; </span><span class="c1"># you can generate a token for a specific time as well...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">otp</span><span class="o">.</span><span class="n">generate</span><span class="p">(</span><span class="n">time</span><span class="o">=</span><span class="mi">1475338840</span><span class="p">)</span><span class="o">.</span><span class="n">token</span>
<span class="go">&#39;359275&#39;</span>
</pre></div>
</div>
<div class="float-right admonition seealso">
<p class="admonition-title">See also</p>
<p>For more details, see the <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP.generate" title="passlib.totp.TOTP.generate"><code class="xref py py-meth docutils literal notranslate"><span class="pre">TOTP.generate()</span></code></a> method.</p>
</div>
</section>
<section id="verifying-tokens">
<span id="totp-verifying"></span><h2>Verifying Tokens<a class="headerlink" href="#verifying-tokens" title="Link to this heading">¶</a></h2>
<p>In order for successful authentication, the user must generate the token
on the client, and provide it to your server before the <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP.period" title="passlib.totp.TOTP.period"><code class="xref py py-attr docutils literal notranslate"><span class="pre">TOTP.period</span></code></a> ends.</p>
<p>Since this there will always be a little transmission delay (and sometimes
client clock drift) TOTP verification usually uses a small verification window,
allowing a user to enter a token a few seconds after the period has ended.
This window is usually kept as small as possible, and in passlib defaults to 30 seconds.</p>
<section id="match-verify">
<h3>Match &amp; Verify<a class="headerlink" href="#match-verify" title="Link to this heading">¶</a></h3>
<p>To verify a token a user has provided, you can use the <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP.match" title="passlib.totp.TOTP.match"><code class="xref py py-meth docutils literal notranslate"><span class="pre">TOTP.match()</span></code></a> method.
If unsuccessful, a <a class="reference internal" href="../lib/passlib.exc.html#passlib.exc.TokenError" title="passlib.exc.TokenError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">passlib.exc.TokenError</span></code></a> subclass will be raised.
If successful, this will return a <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TotpMatch" title="passlib.totp.TotpMatch"><code class="xref py py-class docutils literal notranslate"><span class="pre">TotpMatch</span></code></a> instance, with details about the match.
This object acts like a tuple of <code class="docutils literal notranslate"><span class="pre">(counter,</span> <span class="pre">timestamp)</span></code>, but offers some additional
informational attributes:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="c1"># NOTE: all of the following was done at a fixed time, to make these</span>
<span class="gp">&gt;&gt;&gt; </span><span class="c1">#       examples repeatable. in real-world use, you would omit the &#39;time&#39; parameter</span>
<span class="gp">&gt;&gt;&gt; </span><span class="c1">#       from all these calls.</span>

<span class="gp">&gt;&gt;&gt; </span><span class="c1"># assuming TOTP key &amp; config was deserialized from database store</span>
<span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">passlib</span> <span class="kn">import</span> <span class="n">totp</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">otp</span> <span class="o">=</span> <span class="n">TOTP</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="s1">&#39;GVDOQ7NP6XPJWE4CWCLFFSXZH6DTAZWM&#39;</span><span class="p">)</span>

<span class="gp">&gt;&gt;&gt; </span><span class="c1"># user provides malformed token:</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">otp</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="s1">&#39;359&#39;</span><span class="p">,</span> <span class="n">time</span><span class="o">=</span><span class="mi">1475338840</span><span class="p">)</span>
<span class="gp">...</span>
<span class="go">MalformedTokenError: Token must have exactly 6 digits</span>

<span class="gp">&gt;&gt;&gt; </span><span class="c1"># user provides token that isn&#39;t valid w/in time window:</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">otp</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="s1">&#39;123456&#39;</span><span class="p">,</span> <span class="n">time</span><span class="o">=</span><span class="mi">1475338840</span><span class="p">)</span>
<span class="gp">...</span>
<span class="go">InvalidTokenError: Token did not match</span>

<span class="gp">&gt;&gt;&gt; </span><span class="c1"># user provides correct token</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">otp</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="s1">&#39;359275&#39;</span><span class="p">,</span> <span class="n">time</span><span class="o">=</span><span class="mi">1475338840</span><span class="p">)</span>
<span class="go">&lt;TotpMatch counter=49177961 time=1475338840 cache_seconds=60&gt;</span>
</pre></div>
</div>
<p>As a further optimization, the <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP.verify" title="passlib.totp.TOTP.verify"><code class="xref py py-meth docutils literal notranslate"><span class="pre">TOTP.verify()</span></code></a> method allows deserializing
and matching a token in a single step.  Not only does this save a little code,
it has a signature much more similar to that of Passlib’s <a class="reference internal" href="../lib/passlib.ifc.html#passlib.ifc.PasswordHash.verify" title="passlib.ifc.PasswordHash.verify"><code class="xref py py-meth docutils literal notranslate"><span class="pre">passlib.ifc.PasswordHash.verify()</span></code></a>.</p>
<p>Typically applications will provide the TOTP key in whatever format it’s stored by the server.
This will usually be a JSON string (as output by <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP.to_json" title="passlib.totp.TOTP.to_json"><code class="xref py py-meth docutils literal notranslate"><span class="pre">TOTP.to_json()</span></code></a>), but can be any
format accepted by <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP.from_source" title="passlib.totp.TOTP.from_source"><code class="xref py py-meth docutils literal notranslate"><span class="pre">TOTP.from_source()</span></code></a>.
As an example:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="c1"># application loads json-serialized TOTP key</span>
<span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">passlib.totp</span> <span class="kn">import</span> <span class="n">TOTP</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">totp_source</span> <span class="o">=</span> <span class="s1">&#39;{&quot;v&quot;: 1, &quot;type&quot;: &quot;totp&quot;, &quot;key&quot;: &quot;otxl2f5cctbprpzx&quot;}&#39;</span>

<span class="gp">&gt;&gt;&gt; </span><span class="c1"># parse &amp; match the token in a single call</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">match</span> <span class="o">=</span> <span class="n">TOTP</span><span class="o">.</span><span class="n">verify</span><span class="p">(</span><span class="s1">&#39;123456&#39;</span><span class="p">,</span> <span class="n">totp_source</span><span class="p">)</span>
</pre></div>
</div>
<div class="float-right admonition seealso">
<p class="admonition-title">See also</p>
<p>For more details, see the <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP.match" title="passlib.totp.TOTP.match"><code class="xref py py-meth docutils literal notranslate"><span class="pre">TOTP.match()</span></code></a> and <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP.verify" title="passlib.totp.TOTP.verify"><code class="xref py py-meth docutils literal notranslate"><span class="pre">TOTP.verify()</span></code></a> methods.</p>
</div>
</section>
<section id="preventing-token-reuse">
<span id="totp-reuse-warning"></span><h3>Preventing Token Reuse<a class="headerlink" href="#preventing-token-reuse" title="Link to this heading">¶</a></h3>
<p>Even if an attacker is able to observe a user entering a TOTP token,
it will do them no good once <code class="docutils literal notranslate"><span class="pre">period</span> <span class="pre">+</span> <span class="pre">window</span></code> seconds have passed (typically 60).
This is because the current time will now have advanced far enough that
<code class="xref py py-meth docutils literal notranslate"><span class="pre">TOTP.match()</span></code> will <em>never</em> match against the stolen token.</p>
<p>However, this leaves a small window in which the attacker can observe and replay
a token, successfully impersonating the user.
To prevent this, applications are strongly encouraged to record the
latest <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TotpMatch.counter" title="passlib.totp.TotpMatch.counter"><code class="xref py py-attr docutils literal notranslate"><span class="pre">TotpMatch.counter</span></code></a> value that’s returned by the <code class="xref py py-meth docutils literal notranslate"><span class="pre">TOTP.match()</span></code> method.</p>
<p>This value should be stored per-user in a temporary cache for at least
<code class="docutils literal notranslate"><span class="pre">period</span> <span class="pre">+</span> <span class="pre">window</span></code> seconds.  (This is typically 60 seconds, but for an exact value,
applications may check the <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TotpMatch.cache_seconds" title="passlib.totp.TotpMatch.cache_seconds"><code class="xref py py-attr docutils literal notranslate"><span class="pre">TotpMatch.cache_seconds</span></code></a> value returned by
the <code class="xref py py-meth docutils literal notranslate"><span class="pre">TOTP.match()</span></code> method).</p>
<p>Any subsequent calls to verify should check this cache,
and pass in that value to <code class="xref py py-meth docutils literal notranslate"><span class="pre">TOTP.match()</span></code>’s “last_counter” parameter
(or <code class="docutils literal notranslate"><span class="pre">None</span></code> if no value found).  Doing so will ensure that tokens
can only be used once, preventing replay attacks.</p>
<p>As an example:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="c1"># NOTE: all of the following was done at a fixed time, to make these</span>
<span class="gp">&gt;&gt;&gt; </span><span class="c1">#       examples repeatable. in real-world use, you would omit the &#39;time&#39; parameter</span>
<span class="gp">&gt;&gt;&gt; </span><span class="c1">#       from all these calls.</span>

<span class="gp">&gt;&gt;&gt; </span><span class="c1"># assuming TOTP key &amp; config was deserialized from database store</span>
<span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">passlib.totp</span> <span class="kn">import</span> <span class="n">TOTP</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">otp</span> <span class="o">=</span> <span class="n">TOTP</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="s1">&#39;GVDOQ7NP6XPJWE4CWCLFFSXZH6DTAZWM&#39;</span><span class="p">)</span>

<span class="gp">&gt;&gt;&gt; </span><span class="c1"># retrieve per-user counter from cache</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">last_counter</span> <span class="o">=</span> <span class="o">...</span><span class="n">consult</span> <span class="n">application</span> <span class="n">cache</span><span class="o">...</span>

<span class="gp">&gt;&gt;&gt; </span><span class="c1"># if user provides valid value, a TotpMatch object will be returned.</span>
<span class="gp">&gt;&gt;&gt; </span><span class="c1"># (if they provide an invalid value, a TokenError will be raised).</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">match</span> <span class="o">=</span> <span class="n">otp</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="s1">&#39;359275&#39;</span><span class="p">,</span> <span class="n">last_counter</span><span class="o">=</span><span class="n">last_counter</span><span class="p">,</span> <span class="n">time</span><span class="o">=</span><span class="mi">1475338830</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">match</span><span class="o">.</span><span class="n">counter</span>
<span class="go">49177961</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">match</span><span class="o">.</span><span class="n">cache_seconds</span>
<span class="go">60</span>

<span class="gp">&gt;&gt;&gt; </span><span class="c1"># application should now cache the new &#39;match.counter&#39; value</span>
<span class="gp">&gt;&gt;&gt; </span><span class="c1"># for at least &#39;match.cache_seconds&#39;.</span>

<span class="gp">&gt;&gt;&gt; </span><span class="c1"># now that last_counter has been properly updated: say that</span>
<span class="gp">&gt;&gt;&gt; </span><span class="c1"># 10 seconds later attacker attempts to re-use token user just entered:</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">last_counter</span> <span class="o">=</span> <span class="mi">49177961</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">match</span> <span class="o">=</span> <span class="n">otp</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="s1">&#39;359275&#39;</span><span class="p">,</span> <span class="n">last_counter</span><span class="o">=</span><span class="n">last_counter</span><span class="p">,</span> <span class="n">time</span><span class="o">=</span><span class="mi">1475338840</span><span class="p">)</span>
<span class="gp">...</span>
<span class="go">UsedTokenError: Token has already been used, please wait for another.</span>
</pre></div>
</div>
<div class="float-right admonition seealso">
<p class="admonition-title">See also</p>
<p>For more details, see the <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP.match" title="passlib.totp.TOTP.match"><code class="xref py py-meth docutils literal notranslate"><span class="pre">TOTP.match()</span></code></a> method;
for more examples, see Step 6 above.</p>
</div>
</section>
<section id="why-rate-limiting-is-critical">
<span id="totp-rate-limiting"></span><h3>Why Rate-Limiting is Critical<a class="headerlink" href="#why-rate-limiting-is-critical" title="Link to this heading">¶</a></h3>
<p>The <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP.match" title="passlib.totp.TOTP.match"><code class="xref py py-meth docutils literal notranslate"><span class="pre">TOTP.match()</span></code></a> method offers a <code class="docutils literal notranslate"><span class="pre">window</span></code>
parameter, expanding the search range to account for the client getting
slightly out of sync.</p>
<p>While it’s tempting to be user-friendly, and make this window as large as possible,
there is a security downside: Since any token within the window will be
treated as valid, the larger you make the window, the more likely it is
that an attacker will be able to guess the correct token by random luck.</p>
<p>Because of this, <strong>it’s critical for applications implementing OTP to rate-limit
the number of attempts on an account</strong>, since an unlimited number of attempts
guarantees an attacker will be able to guess any given token.</p>
<p><strong>The Gory Details</strong></p>
<p>For TOTP, the formula is <code class="docutils literal notranslate"><span class="pre">odds</span> <span class="pre">=</span> <span class="pre">guesses</span> <span class="pre">*</span> <span class="pre">(1</span> <span class="pre">+</span> <span class="pre">2</span> <span class="pre">*</span> <span class="pre">window</span> <span class="pre">/</span> <span class="pre">period)</span> <span class="pre">/</span> <span class="pre">10**digits</span></code>;
where <code class="docutils literal notranslate"><span class="pre">window</span></code> in this case is the <a class="reference internal" href="../lib/passlib.totp.html#passlib.totp.TOTP.match" title="passlib.totp.TOTP.match"><code class="xref py py-meth docutils literal notranslate"><span class="pre">TOTP.match()</span></code></a> window (measured in seconds),
and <code class="docutils literal notranslate"><span class="pre">period</span></code> is the number of seconds before the token is rotated.</p>
<p>This formula can be inverted to give the maximum window we want to allow
for a given configuration, rate limit, and desired odds:
<code class="docutils literal notranslate"><span class="pre">max_window</span> <span class="pre">=</span> <span class="pre">floor((odds</span> <span class="pre">*</span> <span class="pre">10**digits</span> <span class="pre">/</span> <span class="pre">guesses</span> <span class="pre">-</span> <span class="pre">1)</span> <span class="pre">*</span> <span class="pre">period</span> <span class="pre">/</span> <span class="pre">2)</span></code>.</p>
<p>For example (assuming TOTP with 7 digits and 30 second period),
if you want an attacker’s odds to be no better than 1 in 10000,
and plan to lock an account after 4 failed attempts –
the maximum window you should use would be
<code class="docutils literal notranslate"><span class="pre">floor((1/10000</span> <span class="pre">*</span> <span class="pre">10**6</span> <span class="pre">/</span> <span class="pre">4</span> <span class="pre">-</span> <span class="pre">1)</span> <span class="pre">*</span> <span class="pre">30</span> <span class="pre">/</span> <span class="pre">2)</span></code> or 360 seconds.</p>
</section>
</section>
</section>


            <div class="clearer"></div>
          </div>
        </div>
      </div>
      <div class="sphinxsidebar" role="navigation" aria-label="Main">
        <div class="sphinxsidebarwrapper">
            <p class="logo"><a href="../contents.html">
              <img class="logo" src="../_static/masthead.png" alt="Logo of Passlib"/>
            </a></p>
<search id="searchbox" style="display: none" role="search">
  <h3 id="searchlabel">Quick search</h3>
    <div class="searchformwrapper">
    <form class="search" action="../search.html" method="get">
      <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
      <input type="submit" value="Go" />
    </form>
    </div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script>
<h3><a href="../contents.html">Table of Contents</a></h3>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../index.html">Introduction</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="index.html">Walkthrough &amp; Tutorials</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="../install.html">Installation</a></li>
<li class="toctree-l2"><a class="reference internal" href="overview.html">Library Overview</a></li>
<li class="toctree-l2"><a class="reference internal" href="quickstart.html">New Application Quickstart Guide</a></li>
<li class="toctree-l2"><a class="reference internal" href="hash-tutorial.html"><code class="xref py py-class docutils literal notranslate"><span class="pre">PasswordHash</span></code> Tutorial</a></li>
<li class="toctree-l2"><a class="reference internal" href="context-tutorial.html"><code class="xref py py-class docutils literal notranslate"><span class="pre">CryptContext</span></code> Tutorial</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#"><code class="xref py py-class docutils literal notranslate"><span class="pre">TOTP</span></code> Tutorial</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#overview">Overview</a></li>
<li class="toctree-l3"><a class="reference internal" href="#walkthrough">Walkthrough</a><ul>
<li class="toctree-l4"><a class="reference internal" href="#generate-an-application-secret">1. Generate an Application Secret</a></li>
<li class="toctree-l4"><a class="reference internal" href="#totp-factory-initialization">2. TOTP Factory Initialization</a></li>
<li class="toctree-l4"><a class="reference internal" href="#rate-limiting-cache-initialization">3. Rate-Limiting &amp; Cache Initialization</a></li>
<li class="toctree-l4"><a class="reference internal" href="#setting-up-totp-for-a-user">4. Setting up TOTP for a User</a></li>
<li class="toctree-l4"><a class="reference internal" href="#storing-the-totp-object">5. Storing the TOTP object</a></li>
<li class="toctree-l4"><a class="reference internal" href="#verifying-a-token">6. Verifying a Token</a></li>
<li class="toctree-l4"><a class="reference internal" href="#reserializing-existing-objects">7. Reserializing Existing Objects</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="#creating-totp-instances">Creating TOTP Instances</a><ul>
<li class="toctree-l4"><a class="reference internal" href="#direct-creation">Direct Creation</a></li>
<li class="toctree-l4"><a class="reference internal" href="#using-a-factory">Using a Factory</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="#configuring-clients">Configuring Clients</a><ul>
<li class="toctree-l4"><a class="reference internal" href="#rendering-uris">Rendering URIs</a></li>
<li class="toctree-l4"><a class="reference internal" href="#rendering-qr-codes">Rendering QR Codes</a></li>
<li class="toctree-l4"><a class="reference internal" href="#parsing-uris">Parsing URIs</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="#storing-totp-instances">Storing TOTP instances</a><ul>
<li class="toctree-l4"><a class="reference internal" href="#json-serialization">JSON Serialization</a></li>
<li class="toctree-l4"><a class="reference internal" href="#application-secrets">Application Secrets</a></li>
<li class="toctree-l4"><a class="reference internal" href="#encrypting-keys">Encrypting Keys</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="#generating-tokens-client-side-only">Generating Tokens (Client-Side Only)</a></li>
<li class="toctree-l3"><a class="reference internal" href="#verifying-tokens">Verifying Tokens</a><ul>
<li class="toctree-l4"><a class="reference internal" href="#match-verify">Match &amp; Verify</a></li>
<li class="toctree-l4"><a class="reference internal" href="#preventing-token-reuse">Preventing Token Reuse</a></li>
<li class="toctree-l4"><a class="reference internal" href="#why-rate-limiting-is-critical">Why Rate-Limiting is Critical</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../lib/index.html">API Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="../other.html">Other Documentation</a></li>
</ul>

        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related" role="navigation" aria-label="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="../lib/index.html" title="API Reference"
             >next</a> |</li>
        <li class="right" >
          <a href="context-tutorial.html" title="CryptContext Tutorial"
             >previous</a> |</li>
        <li class="nav-item nav-item-0"><a href="../contents.html">Passlib latest Documentation</a> &#187;</li>
          <li class="nav-item nav-item-1"><a href="index.html" >Walkthrough &amp; Tutorials</a> &#187;</li>
        <li class="nav-item nav-item-this"><a href=""><code class="xref py py-class docutils literal notranslate"><span class="pre">TOTP</span></code> Tutorial</a></li> 
      </ul>
    </div>
    <div class="footer" role="contentinfo">
    &#169; <a href="../copyright.html">Copyright</a> 2008-2025, Assurance Technologies, LLC. Last Updated 2025-12-21.
      Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 8.2.3.
    </div>
  </body>
</html>

Youez - 2016 - github.com/yon3zu
LinuXploit