Hacker News new | past | comments | ask | show | jobs | submit | 3eb7988a1663's comments login

It is a bit terse, but there is a 20-line Python implementation which cleared up the ideas for me: https://github.com/susam/mintotp

It is even shorter without boilerplates:

    def hotp(key, counter, digits=6, digest='sha1'):
        key = base64.b32decode(key.upper() + '=' * ((8 - len(key)) % 8))
        counter = struct.pack('>Q', counter)
        mac = hmac.new(key, counter, digest).digest()
        offset = mac[-1] & 0x0f
        binary = struct.unpack('>L', mac[offset:offset+4])[0] & 0x7fffffff
        return str(binary)[-digits:].zfill(digits)
    
    def totp(key, time_step=30, digits=6, digest='sha1'):
        return hotp(key, int(time.time() / time_step), digits, digest)

Ever so slightly easier to read (IMO) if you inline arguments:

    def hotp(key: bytes, counter: int, digits: int = 6, digest: Literal["sha1", "sha256", "sha512"] = "sha1"):
        mac = hmac.digest(
            key=base64.b32decode(key.upper() + "=" * ((8 - len(key)) % 8)),
            msg=struct.pack(">Q", counter),
            digest=digest,
        )
        offset = mac[-1] & 0x0F
        binary: int = struct.unpack(">L", mac[offset : offset + 4])[0] & 0x7FFFFFFF
        return str(binary)[-digits:].zfill(digits)
And Pyright doesn’t yell at this version because no type-changing variables here: https://basedpyright.com/?typeCheckingMode=all&code=JYWwDg9g...

---

This is actually really helpful. I’m using Pass [1], which requires oathtool for OTP support [2]. I’m currently on a Mac without admin rights (so no Homebrew for me), and compiling oathtool is a PITA. I’ve wanted to put together a pure Python replacement for a while now, but with this it can be a single-file script: https://gist.github.com/notpushkin/7ac32ddf35a0c73bc6f181a1b...

[1]: https://www.passwordstore.org/

[2]: https://github.com/tadfisher/pass-otp#requirements


Why not do an integer division?

I love this one. The neat thing about TOTP is that while the algorithm itself is simple, the algorithms it depends on are also relatively simple, at least for cryptography. For HMAC you just need SHA1, and that can be implemented relatively easily without much more code. As a learning exercise it's quite good.

I adapted code for Java back in the day from here: https://github.com/j256/two-factor-auth/blob/master/src/main...

A bit longer but most of it is just boilerplate Java stuff to deal with polymorphism and a base32 implementation. I recall, stripping most of that away in our internal adapted version of that.

Key points:

- generate a 16 character base32 secret and stuff it in a totp link. otpauth://totp/Alice:alice@example.com?secret=JBSWY3DPEHPK3PXP&issuer=Alice

- stuff that in a QR code and show it to the user so they point their phone authenticator app at it to store the secret. We used a js library for this.

- store the secret with the user account in a secure way (we used aes encryption for this)

- when verifying, use the secret, a timestamp in seconds after the epoch divided by 30 (simple normalization step applied on the client as well) and use the user provided number to construct a sha1 hmac and grab the last digits and prepend with zeros. The calculated string should be the same as what the user typed from their token app as long as their clock is in sync.

- we actually implemented a grace period by calculating the before and after code as well so the user isn't screwed over if the number rotates while they were tapping out the code.

While relatively easy to implement, we ran into a lot of friction rolling this out to normal users. Basically non technical people find this stuff super confusing and we had to hand hold quite a few people through the process and we also had to deal with people that lost their secret, or kept on using the wrong code (for a different account). The UX of this stuff is just terrible. Be prepared to deal with a lot of support overhead if you choose to roll this out. A non trivial percentage of users will manage to lock themselves out of their accounts.


Those `>Q` and `>L` just make it more confusing for me, they just feel like a different language in the language...

Perhaps you could contribute a version in a language that uses more descriptive names, something like BitPacker.WriteInt64 for >Q if I'm guessing correctly what that means (I'd equally need to check the docs to know what format these letters represent, but I don't find it too confusing when you know it's simply some binary / byte array version of the same thing)

They are well documented and essentially are a DSL with the Python struct module for specifying memory representations of packed structures.

https://docs.python.org/3/library/struct.html#format-charact...


The issue tracker + pull requests are also worth browsing: https://github.com/hxu296/tariff/issues

Oh! Thanks for sharing. #4 is a winner!

> C++, what a disrespectful language! Nobody can be faster than Python, NOBODY! We should raise the tariff charged to C++ to 145x.

I know a woman who was part of a M&A team. On her first day, she was told her days of owning individual stocks in the industry were over. She could only purchase aggregate funds. Although, I do wonder if the same rules apply to the VPs who actually have to sign off on the deals.

Given that every product roadmap now looks to jam AI into every cranny, probably best to live with the bugs you know.

Is that a pre or post lawsuit foot long?

(Subway was sued that the "foot longs" were only 11-11.5 inches in length: https://www.startribune.com/subway-to-ensure-footlongs-measu...)


I am no fan of the administration or Greene, but the tariff day was well communicated beforehand (though, not the magnitude). Getting out of the market before the chaos hit the fan, seems like a fiscally savvy move.

Genetic algorithms to fit car shapes: https://rednuht.org/genetic_cars_2/

I cannot stand to watch, but I am curious how Fox News is presenting the latest events. Without that propaganda piece supporting the administration, how long can support be maintained.

They presented it by removing the stock ticket for the broadcast and otherwise ignoring it.

That’s maybe doable as long as the major impact is just the stock market. Most people do not pay much attention to the stock markets, at least not day by day. However, within weeks, price increases from the US tariffs and demand decreases from the Chinese tariffs will start to hit, and those will likely be more difficult to paper over.

Maybe the headline should note that this a parser vulnerability, not the format itself. I suppose that is obvious, but my first knee-jerk thought was, "Am I going to have to re-encode XXX piles of data?"

Also that it's in the Java parquet library, which somehow is nowhere in the article

What would it mean for the vulnerability to be in the format and not the parser?

I don't know. Something like a Python pickle file where parsing is unavoidable.

On a second read, I realized a format problem was unlikely, but the headline just said, "Apache Parquet". My mind might the same conclusion if it said "safetensors" or "PNG".


That data had to be encoded in a certain way which would lead to unavoidable exploitation in every conforming implementation. For example, PDF permits embedded JavaScript and… that has not gone well.

Macros in old Microsoft Word documents were quite a popular attack.

That does not follow for me. Pandas does not utilize Java/JVM.

I'm sorry. I made a mistake.

Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: