-
-
Notifications
You must be signed in to change notification settings - Fork 137
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changed default secret length from 80bits to 160bits as recommended by RFC4226 #117
Conversation
https://www.ietf.org/rfc/rfc4226.txt (and TOTP refers to RFC4226, see https://www.ietf.org/rfc/rfc6238.txt)
Before I fix the tests: Is this something that you would be willing to change? |
Hello, I have a question: why not go to 256 instead of aiming for the minimum accepted value? And I vote strongly for this change, on the condition that it doesn't impact existing secrets, because if it does, it is a major breaking change that nobody wants to deal with (imho). But if it only impacts newly created secrets, then it's all good! |
Yeah I don't hate this, whatever the default value ends up being, I would only say that technically it could break backwards compatibility if some users had very strict string lengths in their database |
a question for how spicy @RobThree wants to be I guess 😅 |
Well, I would like to go "all the way", but in my past experience (it's been a little while though, things probably changed) some authenticators didn't handle anything but the (then) common 80 bits / 6 digits / SHA1 / 30 seconds intervals. So if we're gonna make a change like this I'd love to see the most common authenticators tested and confirmed at the very least that they work without issue. Besides that, we already allow users to go beyond the default 80 bits, they just need to configure it explicitly. Another option would be to put a bit more emphasis on that in the documentation. To be clear: I'm NOT opposed, I am a bit hesitant though as long as we haven't tested / confirmed. And, finally, while, yes, more bits is more better, I don't think it adds that much more value. Things like replay attacks are much more dangerous IMHO. Another factor to keep in mind is that people may have a column in their database to store the secrets of type You know what? I'll dump my 2FA secrets (I have quite a few) and I'll plot their lengths, just for poops and giggles. Here we go:
The majority is 80 bits, closely followed by 160 bits. Not sure what, if anything, this demonstrates but it's interesting at the very least. I think it shows at the minimum that 80 bits secrets are still incredibly common and, thus, we need to be careful since this will affect possibly half of our users in one way or another. |
Yes it only affects newly created secrets! And about why not 256: well that is always the discussion with security. The same story for SSL certificates for example. It does add overhead (either longer computational time, increased storage or network traffic). And if you have a method that for example with current processing power takes 100000 years to brute-force: is it worth making this 1000000 with the extra overhead. That said: I am in no way an expert on this but I assume the ones responsible for the recommendation in the RFC are.
Yes that indeed is a thing, so this should be a new major release if you look at it that way. (Or document that security defaults can be changed at any time)
Interesting to see the distribution! If I am correct the 160 bits recommendation was added later so yeah you do have to notice that :) I did a bit of testing with: Google Authenticator, Authy, Microsoft Authenticator, FreeOTP. They all are ok with the longer secret. (I was also thinking of suggestion to change the hash to SHA-256 but that is still not widely supported!) |
changing the hash default is definitely very chaotic so probably not ready for that for a long while 😅 it might be interesting to throw a deprecation notice with |
Maybe we can introduce a middleware function |
I don't quite understand this in the context of this issue? The number of bits can be specified in the constructor, no need for parsing the URL and no need for an 'intermediate' function that returns the url parts as associative array? But maybe I'm understanding this wrong? Having said that, how about we change the default to 160 bits and release as beta/pre-release-something and leave it for a few months to see what comes out of it? It's better than doing nothing and it's better than just going straight for deploying with the defaults. Though I'm also good with @willpower232's suggestion and raising a deprecation of some kind. |
A beta version seems fine to me. A deprecation can be added (at a later moment). Or do you want to add that the release version? That might also not even be bad. I also don't understand the comment regarding the middleware. When I am back from holiday I can finish the PR with working tests and then I can rebase it to whatever branch we want. |
@valerio-bozzolan Could you please elaborate? |
My comment no longer has any connection to the code. I was probably root and drunk. Apologies. |
if this is the only breaking BC change, then it's fine to include it in 3.0, no? As long as the changelog says: Make sure to store the secret in a column of at least XX size. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sounds like a plan everyone is happy with
@RobThree don't let that merge button go cold!!!!! 😜 |
Whoops, wait, I "resolved" a little too much 🤦 |
This change will improve the default 'security' of this lib.
The TOTP RFC https://www.ietf.org/rfc/rfc6238.txt lists:
The HTOP RFC https://www.ietf.org/rfc/rfc4226.txt lists:
For example the Android App FreeOTP shows a notice when < 160 bits
(see for example freeotp/freeotp-android#307)