summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorThomas Voss <mail@thomasvoss.com> 2023-08-28 21:59:32 +0300
committerThomas Voss <mail@thomasvoss.com> 2023-08-28 21:59:32 +0300
commit1ed0137c7143a7f0f9f6257a082f64ed8c2b5961 (patch)
tree6d66b0b1cb9a1eb8bc489e8d46f8d838293fed5e /src
parent406f609ee81ce0f32c1fe5536d645d4283dbcb22 (diff)
Add an article on ‘totp(1)’
Diffstat (limited to 'src')
-rw-r--r--src/prj/index.html1
-rw-r--r--src/prj/totp/basic-usage.sh.html7
-rw-r--r--src/prj/totp/index.html140
-rw-r--r--src/prj/totp/zbarimg.sh.html4
-rw-r--r--src/style.css31
5 files changed, 171 insertions, 12 deletions
diff --git a/src/prj/index.html b/src/prj/index.html
index c38dd05..b8c8bc9 100644
--- a/src/prj/index.html
+++ b/src/prj/index.html
@@ -30,6 +30,7 @@
<p>Posts:</p>
<ul>
+ <li><a href="totp">totp — generate TOTP codes</a></li>
<li><a href="mkpass">mkpass — make a password</a></li>
<li><a href="mmv">mmv, mpc — mapped file moves and -copies</a></li>
</ul>
diff --git a/src/prj/totp/basic-usage.sh.html b/src/prj/totp/basic-usage.sh.html
new file mode 100644
index 0000000..9023218
--- /dev/null
+++ b/src/prj/totp/basic-usage.sh.html
@@ -0,0 +1,7 @@
+$ <span class="sh-var">code</span>=<span class="sh-ex">`mkpass A-Z0-7`</span>
+$ <span class="sh-fn">totp</span> $<span class="sh-var">code</span>
+475867
+$ <span class="sh-fn">echo</span> $<span class="sh-var">code</span> | <span class="sh-fn">totp</span>
+475867
+$ <span class="sh-fn">totp</span> -d 10 $<span class="sh-var">code</span>
+0718732338
diff --git a/src/prj/totp/index.html b/src/prj/totp/index.html
new file mode 100644
index 0000000..6974a0c
--- /dev/null
+++ b/src/prj/totp/index.html
@@ -0,0 +1,140 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ m4_include(head.html)
+ </head>
+ <body>
+ <header>
+ <div>
+ <h1>Easy Password Generation</h1>
+ m4_include(nav.html)
+ </div>
+
+ <figure class="quote">
+ <blockquote>
+ <p>The C preprocessor is worse than m4, and I would kill myself
+ before I had to use m4.</p>
+ </blockquote>
+ <figcaption>
+ Arav K.
+ </figcaption>
+ </figure>
+ </header>
+
+ <main>
+ <p>
+ <em>
+ You can find the <code>totp</code> git repository over at
+ <a href="https://git.sr.ht/~mango/totp" target="_blank">sourcehut</a>
+ or <a href="https://github.com/Mango0x45/totp"
+ target="_blank">GitHub</a>.
+ </em>
+ </p>
+
+ <h2>Table of Contents</h2>
+
+ <ul>
+ <li><a href="#prologue">Prologue</a></li>
+ <li><a href="#terms">Terminology</a></li>
+ <li><a href="#usage">Basic Usage</a></li>
+ <li><a href="#qr">Working with QR Codes</a></li>
+ </ul>
+
+ <h2 id="prologue">Prologue</h2>
+ <p>
+ <abbr class="totp">TOTP</abbr> codes are pretty cool, and really easy to
+ do. They’re also the backbone of modern two-factor authentication.
+ With <code>totp</code> I hope to make
+ handling <abbr class="totp">TOTP</abbr> codes as easy and extensible as
+ possible.
+ </p>
+
+ <h2 id="terms">Terminology</h2>
+ <p>
+ There are a few terms that I will be using throughout this post, so it’s
+ good to make sure that we’re all on the same page about what I’m
+ referring to.
+ </p>
+
+ <dl>
+ <dt>Secret</dt>
+ <dd>
+ <p>
+ Your <em>secret</em> is
+ a <a href="https://en.wikipedia.org/wiki/Base32"
+ target="_blank">base32</a> encoded secret key that you should under
+ no circumstances share with anyone else. It is from this secret key
+ that we can generate valid <abbr class="totp">TOTP</abbr> codes.
+ </p>
+ </dd>
+
+ <dt>Digits</dt>
+ <dd>
+ <p>
+ Your <em>digits</em> is the length of the generated
+ <abbr class="totp">TOTP</abbr> in digits. If <em>digits</em> is 8,
+ then your generated key could be ‘01234567’. When dealing
+ with <abbr class="tfa">2FA</abbr> this is typically 6.
+ </p>
+ </dd>
+
+ <dt>Period</dt>
+ <dd>
+ <p>
+ Your <em>period</em> it the duration for which the generated key is
+ valid in seconds. When working with <abbr class="tfa">2FA</abbr>
+ this is typically 30.
+ </p>
+ </dd>
+ </dl>
+
+ <h2 id="usage">Basic Usage</h2>
+ <p>
+ <code>totp</code> takes secret keys as command-line arguments, but also
+ reads them from the standard input if none are provided. It assumes
+ that <em>digits</em> is 6 and <em>period</em> is 30. These defaults can
+ be changed with the <code>-d</code> and <code>-p</code> flags.
+ </p>
+
+ <figure>
+ <pre>m4_fmt_code(basic-usage.sh.html)</pre>
+ </figure>
+
+ <aside>
+ <p>
+ I’m using <code>mkpass</code> to generate a random secret. You can
+ see my post about <code>mkpass</code> <a href="/prj/mkpass">here</a>.
+ </p>
+ </aside>
+
+ <h2 id="qr">Working with <abbr class="qr">QR</abbr> Codes</h2>
+ <p>
+ Often times when enabling <abbr class="tfa">2FA</abbr> on your account
+ on some website or platform, you will be shown
+ a <abbr class="qr">QR</abbr> code you can scan with
+ your <abbr class="">2FA</abbr> mobile application.
+ These <abbr class="qr">QR</abbr> codes
+ contain <em>otpauth</em> <abbr class="uri">URI</abbr>s. We can extract
+ these from downloaded images using utilities such
+ as <code>zbarimg</code> and use them in <code>totp</code> using
+ the <code>-u</code> flag to enable ‘<abbr class="uri">URI</abbr> mode’
+ </p>
+
+ <figure>
+ <pre>m4_fmt_code(zbarimg.sh.html)</pre>
+ </figure>
+
+ …and that’s all! There’s nothing else you need. You can use secret keys
+ and otpauth <abbr class="uri">URI</abbr>s, and you can configure
+ the <em>digits</em> and <em>period</em> of the generated codes. You can
+ generate multiple keys at once, and all outputs are printed to the
+ standard output.
+ </main>
+
+ <hr>
+
+ <footer>
+ m4_footer
+ </footer>
+ </body>
+</html>
diff --git a/src/prj/totp/zbarimg.sh.html b/src/prj/totp/zbarimg.sh.html
new file mode 100644
index 0000000..862eb78
--- /dev/null
+++ b/src/prj/totp/zbarimg.sh.html
@@ -0,0 +1,4 @@
+$ <span class="sh-fn">zbarimg</span> -q my-qr-code.svg <span class="sh-cmt"># Also works with jpg, png, etc.</span>
+QR-Code:otpauth://totp/GitHub:Mango0x45?secret=O1AIWMONKWVRJY4H&issuer=GitHub
+$ <span class="sh-fn">zbarimg</span> -q my-qr-code.svg | <span class="sh-fn">sed</span> s/QR-Code:// | <span class="sh-fn">totp</span> -u
+554210
diff --git a/src/style.css b/src/style.css
index 07c8d8c..78e8ef2 100644
--- a/src/style.css
+++ b/src/style.css
@@ -10,6 +10,7 @@
--aqua: #8ABEB7;
--blue: #81A2BE;
--red: #C66;
+ --salmon: #FA8072;
}
@font-face {
@@ -171,6 +172,7 @@ dl {
.c-pp { color: var(--blue); }
.sh-str { color: var(--aqua); }
.sh-hd { color: var(--aqua); }
+ .sh-ex { color: var(--salmon); }
.diff-ins { color: var(--green); }
.diff-del { color: var(--red); }
@@ -197,6 +199,7 @@ dl {
abbr {
cursor: help;
position: relative;
+ text-underline-offset: 4px;
text-decoration-line: underline;
text-decoration-style: dotted;
}
@@ -219,18 +222,22 @@ dl {
pointer-events: none;
}
- abbr.cli::before { content: 'Command-Line Interface'; }
- abbr.cpu::before { content: 'Central Processing Unit'; }
- abbr.css::before { content: 'Cascading Stylesheets'; }
- abbr.cv::before { content: 'Curriculum Vitæ'; }
- abbr.ec::before { content: 'Embedded Controller'; }
- abbr.gnu::before { content: 'GNU’s Not UNIX'; }
- abbr.html::before { content: 'Hypertext Markup Language'; }
- abbr.it::before { content: 'Information Technology'; }
- abbr.led::before { content: 'Light-Emitting Diode'; }
- abbr.nas::before { content: 'Network Attached Storage'; }
- abbr.rgb::before { content: 'Red Green Blue'; }
- abbr.xml::before { content: 'Extensible Markup Language'; }
+ abbr.cli::before { content: 'Command-Line Interface'; }
+ abbr.cpu::before { content: 'Central Processing Unit'; }
+ abbr.css::before { content: 'Cascading Stylesheets'; }
+ abbr.cv::before { content: 'Curriculum Vitæ'; }
+ abbr.ec::before { content: 'Embedded Controller'; }
+ abbr.gnu::before { content: 'GNU’s Not UNIX'; }
+ abbr.html::before { content: 'Hypertext Markup Language'; }
+ abbr.it::before { content: 'Information Technology'; }
+ abbr.led::before { content: 'Light-Emitting Diode'; }
+ abbr.nas::before { content: 'Network Attached Storage'; }
+ abbr.qr::before { content: 'Quick Response'; }
+ abbr.rgb::before { content: 'Red Green Blue'; }
+ abbr.tfa::before { content: 'Two-Factor Authentication'; }
+ abbr.totp::before { content: 'Time-Based One-Time Password'; }
+ abbr.uri::before { content: 'Uniform Resource Identifier'; }
+ abbr.xml::before { content: 'Extensible Markup Language'; }
}
@media (max-width: 40em) {