Why don't we sign up with keys on the web?
There once was a web application….
All the web application today start out on a somewhat similar pattern when it involves user registration and authentication. You setup a database wherein you create a table called users/clients/customers. The next step is to create an e-mail and password field. Than you go on to make sure that the password is stored encrypted and your users can register and authenticate. This is a great and logical way to do it. However, what would happen if we challenge that basic pattern.
Why not with keys?
I thought it would be nice to try and see if it’s possible to make a very simple webapplication with user registration and authentication with a public-private key-pair and without any trace of the user itself in a database. I found out it was remarkably easy, with some downsides. I looked at alternatives for authentication and found out that I really liked the way you can authenticate yourself with something I use everyday: SSH. You sign in with a public-private key-pair and an optional password. There’s no user-data (name, address, etc.) tied to these keys except for an email address (which is optional).
This principle of authentication got my thinking: "why don’t we use this for the web?" In current day and age there’s a lot to say for privacy. Databases get hacked every now and than and people get away with stealing thousands if not millions of rows of users information. The way I think you can prevent this, is by having no user information at all in your database. If there’s nothing there, there’s nothing to steal.
I started out with learning about OpenSSL, ciphers, RSA, AES and you name it. The way I thought it could work is as follows:
This is a basic registration screen:
After signing in, the application will create a public-private key-pair with a password. The private key is stored on the server as a file and you’ll receive your public key:
Your public key - as you can see - is separated in two parts. The first bit is your actual public key. The second bit is your user information. That’s right, you’ll carry your user information with you. The setup is now that you can decrypt your user information with the above public key. It could also be setup in a way that it’s only possible to decrypt that information with the private key.
Signing in looks like this:
You select the public key from your files and type in your password and you’re signed in:
One upside is that your user data is not stored forever in a central database. Your data is send once to the server to generate keys and it will send your public key right back to you. Of course, a man in the middle attack could grab your e-mail and password, but that’s also the case with normal user registration and this project will not prevent that. Another upside is that when signing in, your data is always encrypted; your data is safe with you. Another upside I think is that the safety of the dats is now your responsibility instead of somebody else’s; you don’t lend the key of your house to your irresponsible nephew either. You’ll know that your data cannot be easily used to send bulk emails, perform large demographics of the user base and other unnecessary mining.
One downside of this approach are database associations. A lot of people use the users table as a way to associate it with — for example with a blog — blog posts. This way you can easily see who wrote which post. In this case that’s a little harder. You can associate a user to a post based on a unique user id but you wouldn’t know to which name that belongs. In a way you’re anonymous which could be interpreted as a downside or an upside (I'll leave that to you).
Another downside is forgetting your password or accidentally removing your key. The downside in this is that you can’t click a simple ‘forget password’ link and on top of that all your user data will be gone. A way to solve this would be with a key-hanger type desktop/mobile application where you would be able to store your public keys.
All in all this is just a project for fun; to see if it would be possible. There are still a lot of things that can be improved (for instance, using HTML5 type uploading, encryption with the private key and editing your user information). You can follow the progress of this project on github and I hope it inspires some other developers. If you don't want to explore the whole codebase just open the open_ssl.rb file which contains a basic sketch of what happens in the actual code.