[HN Gopher] MinTOTP - Minimal TOTP generator in 20 lines of Python
       ___________________________________________________________________
        
       MinTOTP - Minimal TOTP generator in 20 lines of Python
        
       Author : susam
       Score  : 133 points
       Date   : 2022-10-18 11:28 UTC (11 hours ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | jsjohnst wrote:
       | 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.
        
         | tyingq wrote:
         | I don't see any fluff myself. Where's the overhead?
        
           | tantalor wrote:
           | Wrapper functions, imports, input handling, etc.
        
           | jsjohnst wrote:
           | 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 wrote:
             | 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.
        
               | masklinn wrote:
               | It's not golfed at all, it's more or less where you get
               | when you implement TOTP by hand from the RFCs.
               | 
               | Except for the final reduction, which in the RFC is
               | implemented via a mod, and the base32 decoding, which is
               | not part of either HOTP or TOTP RFCs, but is instead part
               | of the ad hoc "key uri" format. Which is a funny spec
               | because it was defined for Google Authenticator yet AFAIK
               | GA uses none of the parametrisation so that's only useful
               | if you specifically want to exclude GA users.
        
         | martinky24 wrote:
         | It can be done with a python 1-liner by that logic!
         | 
         | `mintotp.totp('ZYTYYE5FOAGW5ML7LRWUL4WTZLNJAMZS')`
        
           | jsjohnst wrote:
           | I meant specifically chaining generic commands, not a purpose
           | built tool.
        
         | maratc wrote:
         | Can you paste your bash one-liner here?
        
           | jsjohnst wrote:
           | 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"
        
           | gabrielbarros wrote:
           | oathtool --base32 --totp VHR2WYCQPNXIFB2SPLIAE2AZHQ
        
             | remram wrote:
             | Which part of this involves bash? This is an "oathtool one-
             | liner" if anything.
        
           | [deleted]
        
             | [deleted]
        
       | ranger_danger wrote:
       | 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 wrote:
         | 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 wrote:
           | 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 wrote:
             | 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.
        
         | otachack wrote:
         | 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!
        
           | ranger_danger wrote:
           | https://github.com/RavuAlHemio/cpptotp/blob/master/src/libcp.
           | ..
        
         | bvrmn wrote:
         | What other library functions you consider as "cheating"?
        
           | est wrote:
           | Anything above BIOS level. /kidding
        
           | daneel_w wrote:
           | In my opinion the Base32-decoder is the main "cheat" of this
           | TOTP implementation. See my comment a few lines up.
        
             | masklinn wrote:
             | The base32 decoding isn't even part of TOTP.
        
               | daneel_w wrote:
               | It's not part of the RFC, but it is part of TOTP as we
               | know it because of conventions that stuck.
        
       | FerretFred wrote:
       | 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.
        
       | macintux wrote:
       | Active discussion about TOTP underway here:
       | https://news.ycombinator.com/item?id=33245042
        
       | joshka wrote:
       | 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.
        
       | nashashmi wrote:
       | Kind of offtopic. IPhone has a totp password key store in icloud.
       | It is very unknown feature.
        
         | loloquwowndueo wrote:
         | Docs or it didn't happen.
        
           | nashashmi wrote:
           | https://support.apple.com/guide/iphone/automatically-fill-
           | in...
        
             | loloquwowndueo wrote:
             | This is amazing ! Thanks so much!
        
               | slim wrote:
               | can't decide if this is genuine excitement or sarcasm.
               | good job, both of you.
        
               | loloquwowndueo wrote:
               | It's not sarcasm :)
        
               | nashashmi wrote:
               | bunch of upvotes tells me this is real for everyone.
        
       | teach wrote:
       | 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
        
       | bvrmn wrote:
       | Huge thanks to author. I use mintotp pretty much always I need to
       | get token from "pass" stored secret.
        
       | michaelhoffman wrote:
       | Hats off to the author for providing 482 lines of documentation
       | (sloc) to accompany it!
        
       | bwblabs wrote:
       | Shameless plug of my TOTP in '4' lines of PL/pgSQL:
       | https://gist.github.com/bwbroersma/676d0de32263ed554584ab132...
        
       | nathancahill wrote:
       | Tangentially, I wrote a Python generator for the Duo TOTP app
       | which draws from local iOS backups: https://nathancahill.com/duo-
       | cli
        
       | account-5 wrote:
       | There's Go and Ruby clones from the issues. This even seems
       | something I could do myself, nice!
        
       ___________________________________________________________________
       (page generated 2022-10-18 23:02 UTC)