2024-04-06 22:54:44 -04:00
|
|
|
<!doctype html>
|
|
|
|
<html lang="en">
|
2024-04-07 01:04:16 -04:00
|
|
|
<head>
|
|
|
|
<meta charset="UTF-8"/>
|
2025-02-10 18:24:59 -05:00
|
|
|
<link rel="icon" type="image/png" href="/favicon-96x96.png" sizes="96x96"/>
|
2025-02-10 18:08:39 -05:00
|
|
|
<link rel="icon" type="image/svg+xml" href="/totp.svg"/>
|
2025-02-10 18:24:59 -05:00
|
|
|
<link rel="shortcut icon" href="/favicon.ico"/>
|
|
|
|
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"/>
|
2025-02-16 16:42:09 -05:00
|
|
|
<meta name="apple-mobile-web-app-title" content="TOTP.fyi"/>
|
2025-02-10 18:24:59 -05:00
|
|
|
<link rel="manifest" href="/site.webmanifest"/>
|
2024-04-07 01:04:16 -04:00
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
2025-02-16 16:42:09 -05:00
|
|
|
<title>TOTP.fyi — A TOTP Code Generator for Developers</title>
|
2024-04-07 01:04:16 -04:00
|
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<nav class="navbar navbar-expand-lg">
|
|
|
|
<div class="container">
|
2025-02-16 16:42:09 -05:00
|
|
|
<a class="navbar-brand" href="#">TOTP.fyi</a>
|
2024-04-07 01:04:16 -04:00
|
|
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent"
|
|
|
|
aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
|
|
|
<span class="navbar-toggler-icon"></span>
|
|
|
|
</button>
|
|
|
|
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
|
|
|
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
|
|
|
<li class="nav-item">
|
|
|
|
<a class="nav-link" href="#what-is-this">What is this?</a>
|
|
|
|
</li>
|
|
|
|
<li class="nav-item">
|
2025-02-10 12:17:47 -05:00
|
|
|
<a class="nav-link" href="#how-to-use">How to use?</a>
|
|
|
|
</li>
|
2025-02-16 16:42:09 -05:00
|
|
|
<li class="nav-item">
|
|
|
|
<a class="nav-link" href="#how-does-it-work">How does it work?</a>
|
|
|
|
</li>
|
2025-02-10 12:17:47 -05:00
|
|
|
<li class="nav-item">
|
|
|
|
<a class="nav-link" href="#support-me">Support me</a>
|
2024-04-07 01:04:16 -04:00
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</nav>
|
|
|
|
|
|
|
|
<main class="container">
|
|
|
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
|
|
|
<div class="jumbotron">
|
|
|
|
<p class="lead">This is a code generator for the Time-based One Time Password (TOTP) algorithm.</p>
|
|
|
|
<hr>
|
2024-04-06 22:54:44 -04:00
|
|
|
<div id="root"></div>
|
2024-04-07 01:04:16 -04:00
|
|
|
</div>
|
|
|
|
</main>
|
|
|
|
|
2024-04-13 17:35:20 -04:00
|
|
|
<div class="container totp-about">
|
|
|
|
<div class="card">
|
|
|
|
<div class="card-body">
|
|
|
|
<h3 class="card-title" id="what-is-this">What is this?</h3>
|
|
|
|
<p class="card-text">This is a code generator for the <a
|
|
|
|
href="https://en.wikipedia.org/wiki/Time-based_One_Time_Password"><em>Time-based One Time Password</em>
|
2025-02-10 18:32:30 -05:00
|
|
|
(TOTP)</a> algorithm. It's intended for developers of web applications with TOTP support to quickly generate
|
|
|
|
codes for testing purposes. It's <strong>not</strong> meant to be a general purpose authenticator app.
|
2024-04-13 17:35:20 -04:00
|
|
|
</p>
|
|
|
|
<p class="card-text">What this tool can do:</p>
|
|
|
|
<ul class="card-text">
|
|
|
|
<li>Quickly generate TOTP codes;</li>
|
2025-02-10 18:32:30 -05:00
|
|
|
<li>View codes for past and future time windows; and</li>
|
|
|
|
<li>Fiddle with various TOTP parameters.</li>
|
2024-04-13 17:35:20 -04:00
|
|
|
</ul>
|
|
|
|
<p class="card-text">What this tool <strong>can't</strong> do:</p>
|
|
|
|
<ul class="card-text">
|
2025-02-10 12:17:47 -05:00
|
|
|
<li>Store your TOTP secrets (you can try bookmarking this page with the secret in the URL, but it's not
|
|
|
|
secure);
|
|
|
|
</li>
|
2024-04-13 17:35:20 -04:00
|
|
|
<li>Act as your general purpose authenticator app; and</li>
|
|
|
|
<li>Scan TOTP QR codes.</li>
|
|
|
|
</ul>
|
|
|
|
</div>
|
|
|
|
</div>
|
2025-02-10 12:17:47 -05:00
|
|
|
<div class="card">
|
|
|
|
<div class="card-body">
|
|
|
|
<h3 class="card-title" id="how-to-use">How do I use this tool?</h3>
|
|
|
|
<p class="card-text">To start, simply type or paste in the TOTP secret key. This should be in the standard base32
|
|
|
|
format. This will generate 6-digit TOTP codes that update every 30 seconds using the SHA-1 algorithm that's used
|
|
|
|
by default in all major authenticator apps.
|
|
|
|
</p>
|
|
|
|
<p class="card-text">You can press "show advanced settings" to adjust the TOTP parameters to use non-default
|
|
|
|
values.
|
|
|
|
</p>
|
|
|
|
<p class="card-text">The generated codes are displayed in chronological order. The current code is shown in large
|
|
|
|
text. The codes above are past codes, and the codes below are future codes.</p>
|
|
|
|
<p class="card-text">The settings are stored in the URL hash. You can bookmark the page or copy the link to go
|
|
|
|
directly to a certain configuration.</p>
|
|
|
|
</div>
|
|
|
|
</div>
|
2025-02-16 16:42:09 -05:00
|
|
|
<div class="card">
|
|
|
|
<div class="card-body">
|
|
|
|
<h3 class="card-title" id="how-does-it-work">How does TOTP work?</h3>
|
|
|
|
<p class="card-text">Time-based one-time password (TOTP), defined in <a
|
|
|
|
href="https://datatracker.ietf.org/doc/html/rfc6238">RFC 6238</a>, is based on the HMAC-based one-time password
|
|
|
|
(HOTP) algorithm, which uses the common HMAC construction based on the current time. TOTP requires the following
|
|
|
|
inputs:
|
|
|
|
</p>
|
|
|
|
<ul class="card-text">
|
|
|
|
<li>The cryptographic hash function <var>H</var>, which defaults to SHA-1. This is configurable in the advanced
|
|
|
|
settings;
|
|
|
|
</li>
|
|
|
|
<li>The secret key <var>K</var>, which is commonly encoded as Base32. This value, encoded in Base32, is what you
|
|
|
|
enter into the <strong>secret key</strong> field;
|
|
|
|
</li>
|
|
|
|
<li>The time window <var>X</var>, which is how long each code is valid for;</li>
|
|
|
|
<li>The epoch <var>T<sub>0</sub></var>, which is the Unix epoch (0 in Unix time) in every known implementation,
|
|
|
|
but could be changed; and
|
|
|
|
</li>
|
|
|
|
<li>The number of digits <var>d</var>, which is the length of the final output code in decimal digits.</li>
|
|
|
|
</ul>
|
|
|
|
<p class="card-text">The algorithm is as follows:</p>
|
|
|
|
<ol class="card-text">
|
|
|
|
<li>Take the current unix time <var>U</var>;</li>
|
|
|
|
<li>Compute the time step count
|
|
|
|
<img class="math" src="math/t.svg" alt="T=\left\lfloor\frac{U - T_0}{X}\right\rfloor" height="40">;
|
|
|
|
</li>
|
|
|
|
<li>Compute the HMAC <img class="math" src="math/h.svg" alt="h = \text{HMAC}_H(K, T)" height="18">;</li>
|
|
|
|
<li>Extract the 4 lowest order bits, i.e. the 4 least significant bits from the last byte of <var>h</var>, to
|
|
|
|
create the integer <var>i</var>;
|
|
|
|
</li>
|
|
|
|
<li>Take four bytes from <var>h</var> starting at <var>i</var>, i.e. bytes [<var>i</var>, <var>i</var>+4), mask
|
|
|
|
off the most significant bit (to support signed arithmetic), and use it to create the integer <var>y</var>;
|
|
|
|
and finally
|
|
|
|
</li>
|
|
|
|
<li>Compute the code as <img class="math" src="math/mod.svg" alt="y \bmod{10^d}" height="18"
|
2025-02-16 17:11:52 -05:00
|
|
|
style="vertical-align: -3px">, zero-padded to <var>d</var> digits.
|
2025-02-16 16:42:09 -05:00
|
|
|
</li>
|
|
|
|
</ol>
|
2025-02-16 17:11:52 -05:00
|
|
|
<p class="card-text">Express as Python code, the last 3 steps would look like:</p>
|
|
|
|
<pre class="highlight"><code><span class="n">i</span> <span class="o">=</span> <span class="n">h</span><span
|
|
|
|
class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">&</span> <span
|
|
|
|
class="mh">0xF</span>
|
|
|
|
<span class="n">y</span> <span class="o">=</span> <span class="p">(</span>
|
|
|
|
<span class="p">(</span><span class="n">h</span><span class="p">[</span><span class="n">i</span> <span
|
|
|
|
class="o">+</span> <span class="mi">0</span><span class="p">]</span> <span class="o">&</span> <span
|
|
|
|
class="mh">0x7F</span><span class="p">)</span> <span class="o"><<</span> <span
|
|
|
|
class="mi">24</span> <span class="o">|</span>
|
|
|
|
<span class="p">(</span><span class="n">h</span><span class="p">[</span><span class="n">i</span> <span
|
|
|
|
class="o">+</span> <span class="mi">1</span><span class="p">]</span> <span class="o">&</span> <span
|
|
|
|
class="mh">0xFF</span><span class="p">)</span> <span class="o"><<</span> <span
|
|
|
|
class="mi">16</span> <span class="o">|</span>
|
|
|
|
<span class="p">(</span><span class="n">h</span><span class="p">[</span><span class="n">i</span> <span
|
|
|
|
class="o">+</span> <span class="mi">2</span><span class="p">]</span> <span class="o">&</span> <span
|
|
|
|
class="mh">0xFF</span><span class="p">)</span> <span class="o"><<</span> <span class="mi">8</span> <span
|
|
|
|
class="o">|</span>
|
|
|
|
<span class="p">(</span><span class="n">h</span><span class="p">[</span><span class="n">i</span> <span
|
|
|
|
class="o">+</span> <span class="mi">3</span><span class="p">]</span> <span class="o">&</span> <span
|
|
|
|
class="mh">0xFF</span><span class="p">)</span>
|
|
|
|
<span class="p">)</span>
|
|
|
|
<span class="n">code</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">y</span> <span
|
|
|
|
class="o">%</span> <span class="mi">10</span><span class="o">**</span><span class="n">d</span><span class="p">)</span><span
|
|
|
|
class="o">.</span><span class="n">rjust</span><span class="p">(</span><span class="n">d</span><span class="p">,</span> <span
|
|
|
|
class="s1">'0'</span><span class="p">)</span>
|
|
|
|
</code></pre>
|
2025-02-16 16:42:09 -05:00
|
|
|
<p class="card-text">To avoid clock synchronization issues, most implementations will accept TOTP codes from the
|
|
|
|
window before and after the one based on the current time. This tool lets you see the previous and next codes to
|
|
|
|
help you debug.</p>
|
|
|
|
</div>
|
|
|
|
</div>
|
2025-02-10 12:17:47 -05:00
|
|
|
<div class="card">
|
|
|
|
<div class="card-body">
|
|
|
|
<h3 class="card-title" id="support-me">I like this website. How can I support you?</h3>
|
|
|
|
<p class="card-text">
|
|
|
|
For security reasons, this website will <b>NEVER</b> serve ads. Unfortunately, servers and domains are not free,
|
|
|
|
though I try to be as economical as I can. I would rather lose money running this public service than serve
|
|
|
|
ads or shut it down, but if you would like to help me offset the costs, feel free to send some money my way
|
|
|
|
on:
|
|
|
|
</p>
|
|
|
|
<ul>
|
|
|
|
<li><a href="https://github.com/sponsors/quantum5">GitHub Sponsors</a>;</li>
|
|
|
|
<li><a href="https://ko-fi.com/quantum5">Ko-fi</a>;</li>
|
|
|
|
<li><a href="https://liberapay.com/quantum">LiberaPay</a>; or</li>
|
|
|
|
<li><a href="https://donate.stripe.com/6oEcOL8gebjJeuk9AJ">Donate USD by card or bank with Stripe</a> or
|
|
|
|
<a href="https://donate.stripe.com/cN24ifdAy0F53PG7sA">CAD</a>.
|
|
|
|
</li>
|
|
|
|
</ul>
|
2024-04-13 17:35:20 -04:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
2025-02-10 12:17:47 -05:00
|
|
|
<footer class="footer">
|
|
|
|
<div class="container">
|
|
|
|
<p class="text-muted">Copyright © 2024-__YEAR__ <a href="https://quantum5.ca">Quantum</a>. Licensed under
|
|
|
|
<a href="https://www.gnu.org/licenses/agpl-3.0.en.html">GNU AGPLv3</a>. Source code available on
|
|
|
|
<a href="https://github.com/quantum5/totp">GitHub</a>.
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
</footer>
|
|
|
|
|
2024-04-07 01:04:16 -04:00
|
|
|
<script type="module" src="/src/main.tsx"></script>
|
|
|
|
</body>
|
2024-04-06 22:54:44 -04:00
|
|
|
</html>
|