The username / password paradigm for user authentication is ubiquitous, but rife with problems. Even with the use of a password manager, they are awkward and insecure. They are easily lost or forgotten, they are used in many locations for multiple accounts, and they are not changed as often as they should. Even people who are aware of best practices for passwords often do not follow them. Using a username / password authentication system is just a way of asking users to engage in behaviours that put themselves at risk. I propose a protocol whereby passwords are replaced by a piece of software or hardware that authenticates a user’s log-in, without the need for passwords at all.
Instead of allowing the user to choose a password at sign-up, the service in question and the user should both agree on a cryptographic hashing function, a number identifying what service and account name are being authenticated, a randomly-chosen salt (string of characters prefixed to something before passing through a hashing function) and a web address to post credentials to, on log-in.
A desktop / smartphone app for generating valid credentials
The identifier, the hashing function, the salt and the address to which credentials are to be posted would be saved to an encrypted file managed by a specially-designed application on a smartphone, desktop computer or on specialised hardware. This app or hardware would need to be able to read QR codes, save and recall data from a small database, perform the hashing function to generate valid credentials, and then post them to the provided web addresses.
When a user wants to log in to a service, she types her user name and the service in return shows a link or a button to click after authenticating and a QR code (also displayed as text that can be copied to the phone or computer clipboard). This QR code contains the identifier indicating which service is being authenticated and a randomly-generated string of letters and numbers. We will call this the “challenge string.” On the server-side, the challenge string will be tagged with the timestamp when it is provided to the user, and credentials generated with it will be valid for five minutes only, and will only be valid once.
When the user scans the QR code with her smartphone or other hardware, it reads the indicator for the service it is authenticating, as well as the challenge string. The user can also copy / paste the text into an app, in the case that she’s signing on to a site using her phone or is using the desktop version of the app. It would also be possible to write a plug-in for Firefox or Chrome, for example, that allows the user to right-click the QR code or the text equivalent and it brings up a “generate and submit credentials” button.
The app would then prefix the salt provided at sign-up to the challenge string, then pass it through the agreed-upon hash and submit that to the address that the service provided in the first place. On the server-side, the service would also take the challenge string and perform the same function, for comparison.
This tells the service that an authorised user is attempting to log in with the generated code. If it is the case that the credentials submitted to the web service are the same as the credentials that are expected, given the salt and hashing function, and if they are submitted before the challenge string expires, then the link or button that was provided along with the QR code is activated—on clicking it, the site logs the user in to the service in question.
The user does not need to remember anything but her user name, and does not type a password at any point.
If you’re on a strange wifi or something, someone could intercept the challenge string, wait a few minutes, and try claiming that it was her who authenticated it.
Possible solution: Invalidate a challenge string if a user claims to have authenticated it when she hasn’t yet. Allow only one log-in attempt per challenge string. Close a previously authenticated session if a user attempts another log-in.
Note that this is no worse than the username / password paradigm. If a malicious user was sophisticated enough to use this to hijack an authentication, she could certainly also record a username and password sent over her wifi, which would not only allow her to log in once, but any number of times, until the password is changed.
What if someone finds out your hashing function and salt?
The weakest link in the chain here is of course the secrecy of the hashing function and salt. These could be compromised if someone gains access to your phone or in the case of malware. This is no worse than using a password manager. (And certainly more secure than using a cloud-based password manager.)
Possible solution: Build an expiry date in to each password. Keep the list of credential-generating functions and salts and their associated accounts encrypted.
What if my phone dies?
Then you’ve lost all your passwords. You’ll have to restore your phone from a backup, or there would have to be an “I forgot my password” button.
Possible solution: A function that generates hashing functions / salts based on a root string of random letters and numbers and the web address of the account being authenticated. In this case, the root string of random letters and numbers could be printed on a piece of paper, to be kept somewhere secure, and used to generate all the salts and hashes, in the case of a destroyed phone.
- No one has to remember any passwords.
- No recycling of passwords.
- Instead of a single password for a service, the software generates a new password for every session according to (incomplete) instructions that are randomly generated at the time of log-in.
What it would take for this to work
For this to work, someone would need to write these smartphone / desktop apps to process the code and submit credentials. The smartphone / desktop app that generates the credentials would need to be open-source. I know I would want to know that the developer isn’t building himself a back-door into other people’s accounts.
Then, a standard library of functions and examples of how to use this system would need to be published. It would have to be an open standard, and it would have to be dead-simple to integrate into other software.
What I like about this idea is that it’s all within the realm of possibility. I personally have the ability to write all of this (although it would be nice to have some help).
Finally, adoption of this protocol on a large scale would need to take place, which I suppose is the tricky part. Once the protocol is formalised and some software libraries are written, I suppose a good place to start would be looking for other open-source projects (like WordPress) and either forking them so that they include this, talking to the development team or writing a plug-in or something so that they have the option of using this alternate authentication protocol.
Has someone already done something like this? Could it be made to work?
Maybe someone else has already invented this, and it just never caught on. Does anyone know if someone has attempted to replace the username / password like this before?
Can you see any glaring holes in this system that I’ve overlooked? I admit, I have little formal CS training, and it is entirely possible that I have missed something important.
Does anyone want to collaborate on this? I would seriously be interested in getting rid of passwords forever, but I don’t think I can do it alone. We can put it in the Creative Commons or whatever.
I just don’t want to have to use passwords anymore.