Brian Lovin
/
Hacker News
Daily Digest email

Get the top HN stories in your inbox every day.

nashashmi

Kind of offtopic. IPhone has a totp password key store in icloud. It is very unknown feature.

joshka

I'd call this 7 lines rather than 20. The rest is function definition and argument parsing. But really it should be just 1:

  pyotp.TOTP('base32secret3232').now()
Why is this relevant? Because it's inadvisable to write security related software if you're not prepared to take on the full range of possible problems that introducing another security library brings (CVEs, supply chain security, etc.). The adage that doing security right requires doing everything right. Doing security wrong only takes 1 thing.

macintux

Active discussion about TOTP underway here: https://news.ycombinator.com/item?id=33245042

teach

This reminds me a lot of my own attempt[0] from a few years back, but packaged as a Python module instead of a standalone script.

[0] https://github.com/grahammitchell/google-authenticator

account-5

There's Go and Ruby clones from the issues. This even seems something I could do myself, nice!

jsjohnst

It can be done as a bash one liner, so yeah, definitely doable in minimal lines of Python code. More than 50% of this file is “overhead” even.

martinky24

It can be done with a python 1-liner by that logic!

`mintotp.totp('ZYTYYE5FOAGW5ML7LRWUL4WTZLNJAMZS')`

jsjohnst

I meant specifically chaining generic commands, not a purpose built tool.

maratc

Can you paste your bash one-liner here?

jsjohnst

To be very clear, I don’t use this, but I confirmed it does work and generates the same codes as the linked article. Requires Bash (3+) and doesn’t work as written in Zsh.

https://gist.github.com/jsjohnst/95f34bc1f6ab46fd5c038138f0e...

————

   read -r -p 'Secret Key: ' secret_key; dgst=$(printf '%016X' $(($(date -u '+%s') / ${TOTP_PERIOD_SECONDS:=30})) | xxd -r -p | openssl dgst -sha1 -mac hmac -macopt "hexkey:$(printf $secret_key | tr '[:lower:]' '[:upper:]' | base32 -d | xxd -p)"); offset=$(( 2 * 16#${dgst: -1} )); token=$(( ( 16#${dgst:offset:8} & 0x7fffffff ) % 10**${TOTP_DIGITS:=6} )); printf "%0${TOTP_DIGITS}d\n" "$token"

undefined

[deleted]

undefined

[deleted]

gabrielbarros

  oathtool --base32 --totp VHR2WYCQPNXIFB2SPLIAE2AZHQ

remram

Which part of this involves bash? This is an "oathtool one-liner" if anything.

tyingq

I don't see any fluff myself. Where's the overhead?

jsjohnst

It’s not “fluff”, it’s overhead. The real work there is done in about 4 lines (which could be compacted to two and still be somewhat readable). The rest as someone else already said, imports, helper functions (there’s no technical need for totp to just be a wrapper around hotp unless you want to expose hotp or be illustrative), function overhead, etc.

That said, TOTP shouldn’t be treated as code golf, especially in production code. The point is the protocol is trivially simple to implement not that it’s X lines in Y language.

tyingq

Ah, okay. It doesn't appear overly golfed to me. It felt like the point of publishing it was probably similar to what you're saying. That the TOTP algorithm isn't terribly complicated.

tantalor

Wrapper functions, imports, input handling, etc.

bvrmn

Huge thanks to author. I use mintotp pretty much always I need to get token from "pass" stored secret.

FrenchyJiby

Huh, have you heard of the popular pass(1) extension pass-opt[1]?

It allows one to get OTP secrets via a simple:

pass otp secretname # Add -c for clipboard, as usual

And because the OTP side is just a otpauth:// URL on a line of the GPG file, we can still use the rest of the secret for other things:

pass secretname -c

Real smooth!

[1]: https://github.com/tadfisher/pass-otp

bwblabs

Shameless plug of my TOTP in '4' lines of PL/pgSQL: https://gist.github.com/bwbroersma/676d0de32263ed554584ab132...

michaelhoffman

Hats off to the author for providing 482 lines of documentation (sloc) to accompany it!

nathancahill

Tangentially, I wrote a Python generator for the Duo TOTP app which draws from local iOS backups: https://nathancahill.com/duo-cli

ranger_danger

Not pictured: the wall of incomprehensible math code implementing SHA1. Most languages do not provide such implementations by default so I struggle to really call this only 20 lines.

daneel_w

The hmac can be forgiven, in my opinion. But the ~30 lines of code for the Python stdlib's Base32-decoder, which would inflate the line count by 150%, is harder to forgive.

b32-decoding can be made compact, of course: https://github.com/stolendata/totp/blob/master/totp.php#L16-...

pletnes

Base32? The hard part is to implement QR code scanning across a range of different cameras, lighting conditions and shaky hands. Not to mention melting your own sand to make silicon.

masklinn

Don't forget creating the rock which you then weather into sand.

Frankly TFA should work a bit harder on this apple pie, this is just lazy.

bvrmn

What other library functions you consider as "cheating"?

daneel_w

In my opinion the Base32-decoder is the main "cheat" of this TOTP implementation. See my comment a few lines up.

masklinn

The base32 decoding isn’t even part of TOTP.

est

Anything above BIOS level. /kidding

otachack

Fair assessment, but the crypto community has that one high standard of "don't roll your own crypto" unless you have to or it's a learning project.

Now I'm interested in a minimal SHA-1 implementation!

FerretFred

Woohoo! Thanks for that susam - I can now use this on my Pi Zero portable computer project: the missing piece! The GPG option is sneakily good also.

Daily Digest email

Get the top HN stories in your inbox every day.