User ID: John-CPE4E38J
Password: snoopy
For extra security the code would then move the random characters to the password so the authentication library would see this: User ID: John
Password: snoopy-CPE4E38J
In this way even an attacker who gains full access to the server database would be unable to read the passwords (assuming they have been hashed well).Also, the User ID can be stored in a cookie so that the User ID field on screen is pre-populated and the user only has to type "John-CPE4E38J" when he switches to a new computer.
More details here: http://security.stackexchange.com/questions/80352/is-it-a-ba...
Unfortunately, due to market competition many websites simply cannot require 'real' two-factor authentication for all users. Here are the steps I would need to provide to my father to register for a typical '30-day free trial':
1) Go to website.com and click 'Register'
2) Enter your email address
3) Think of a password and type it
4) Click 'I agree'
5) Click 'Register'
Here are the steps I would need to provide to my father to register on a website for a free trial with 2-factor authentication using the Google Authenticator app: 1) Go to website.com and click 'Register'
2) Enter your email address
3) Think of a password and type it
4) Click 'I agree'
5) On your phone, press the 'Play Store' or 'App Store' icon
6) Press the 'Search' icon and search for 'Google Authenticator'
7) Press 'Install' and wait for it to install (if you have an iPhone the install button might look like a little cloud icon)
8) Press 'Open' to open Google Authenticator
9) Press the 'Menu' button which looks like three dots in the top-right corner of the phone screen
10) Choose 'Scan with barcode'
11) Point the phone at the computer screen as though you were going to take a photo of the barcode on screen.
12) Wait for the phone to register the barcode, then enter the number shown on your phone into the website form
13) Click 'Register'
Even with all these steps laid out for him, my father would probably find it extremely frustrating to get to step 13.Some sites (Coibase) do 2FA with text message which is also great.
It seems like you are trying to force your user to remember a salt. Why not just use a proper salt and a strong password hashing function?
Also note that this protection is only useful in the case where an attacker can get a database dump but cannot perform an active attack on the server.
On the other hand, I have seen some sites (gandi.net comes to mind) do something similar to this. Wonder if they have a similar security reasoning?
Yes, essentially I'm trying to force the user to remember a client-side 'salt'.
> Why not just use a proper salt and a strong password hashing function?
Because it wouldn't protect against the attack described by userbinator (ie. 'just trying these 20 passwords gives you a ~18% success rate for any username'). Having a client-side 'salt' gives you that protection.
> I do [not] think that is very user-friendly, even with the cookie trick you describe.
Yes, this system imposes a cost in terms of user-friendliness. But for sensitive sites (eg. medical or financial) I think it's worth it.
You're right that their browser auto-complete will usually take care of it, but once it doesn't (because they switched browsers, because they got a new computer, because it got infected with malware and they took it to a wipe-and-reinstall shop), I'd expect a significant number of your users to fall back to just doing a password reset, which is a hassle.
From a security standpoint, I'm not sure what problem you're trying to solve. I get that you want to strengthen your users' passwords, but what is the specific scenario you're imagining where this is the best prevention? If you're concerned about someone brute-forcing user accounts from the outside, just make sure you have some sane throttling code. If you're concerned about someone stealing your database and breaking user passwords, just make sure you're using a robust password storage mechanism (blah blah bcrypt scrypt etc. etc.) and the usual other internet-facing application best practices (parameterized queries for example). If you're still feeling paranoid about that situation, then probably your server code could add some value to each password without doing any harm, I dunno. If someone gets sufficient access to your server to get your database and your code, game's over anyway. If you're concerned about your user having their credentials compromised elsewhere and that being used to access their account, do the same thing that many banks, Linode, and other services do: maintain IP white, grey, and black lists, and send a challenge/response to the user by text or email if the IP is on a grey list (in addition to checking for their login cookie first).
Your approach is different, but I don't understand it yet. :-)
And yes, I'm trying to solve the two problems you mentioned: (a) someone brute-forcing user accounts from the outside; and (b) someone gaining access to the server database and thereby gaining access to other sites where the user has the same credentials. If it is true that "just trying these 20 passwords gives you a ~18% success rate for any username" then it seems to me that throttling brute-force attempts would not be very effective.
It seems like this is an amusing enough hack to do on non-sensitive sites, but I wouldn't do this on anything "real". When it comes to authentication, "hey I had this really neat idea" is almost always an immediate precursor to making things worse.
I agree with your observation that "hey I had this really neat idea" is almost always an immediate precursor to making things worse. Almost.