We do web-authentication via blockchain
I recently participated in the Ethereum-hackathon, and today I want to talk about the EtherAuth project, with which the MixBytes team took third place. EtherAuth is an attempt to make a decentralized version of the site login using an external account. Like button to enter through Facebook, only without Facebook.
Problem and solutions
If you want to make a closed area for users on your website, you have to choose: to develop your own system of identification, authentication and authorization of users, or to use a ready-made solution. A ready solution means that your user already has an account on some system (Facebook, Google, Yahoo, Outlook, or even just an email). And you use the appropriate mechanism (most often the OAuth 2.0 protocol) to make sure that someone who tries to login to your site using an external user ID is this user.
The latter option is easier to implement, but a risk arises for the user: if something happens to his main account (for example, Facebook blocks the account without explaining the reasons), he will also lose access to his information on your site.
In addition, if I, as a user, want to log in to a site that I don’t trust, I’m faced with the need to give this site access to my personal information, such as email or age. If the site only supports logging in with an external account, I have to literally make a choice: refuse to use the site or sacrifice my anonymity.
Most users end up sacrificing anonymity with the words "yes, that the worst can happen, I have nothing to hide." Unfortunately, the majority of attacks targeted at an unprepared user and ending in monetary losses begin with similar words. "What terrible can happen if I send a code from an SMS to a bank employee?" “What terrible can happen if I send a request header to a tech support employee?” The answer to this question is most often learned when nothing can be done.
How can Ethereum help here? We already understood that there are three main problems:
- The user is not obliged to trust the website he visits and wants to avoid the leakage of personal information.
- The site wants to use an external authentication system to avoid storing user data and the associated security costs.
- Existing external systems that provide sites with the ability to authenticate users carry the danger of censorship. Any account can be blocked at any time without explaining the reasons and sometimes without the possibility of recovery.
We can use the Ethereum network instead of the external system and store in it only the necessary data set. Care must be taken not to keep secret information publicly available, but since every wallet on the Ethereum network is actually a pair of cryptographically secure keys, in which the public key determines the wallet address and the private key is never transmitted over the network and is known only to the owner, we we can use asymmetric encryption to authenticate users.
In the simplest case, you can use the address of the Ethereum wallet as a user ID. But here a problem arises: in the event of a key leak, the user loses access to the system forever. More precisely, from the moment when the user's secret key became known to an attacker or simply happened to be in the public domain, we cannot use such a key for authentication.
In our solution, I wrote a simple EtherAuth smart contract to store user IDs and their associated wallet addresses. The user ID is simply a UTF-8 string, ranging in size from 2 to 32 bytes. It comes up with once the user himself and later uses to enter any site that supports EtherAuth. Today I would add another restriction on the possible characters included in the string, leaving the possibility of using Latin characters and Arabic numerals (subsets of 7-bit ASCII encoding) to limit the possibility of creating externally similar logins.
When creating an account in EtherAuth, a key pair is specified: an authorization key (authAddr) and a key to restore access (recoveryKey). The recoveryKey name is not entirely good, since this address is used to manage your account, not just to recover. When creating, both addresses are equal to the address of the purse on whose behalf the transaction was sent. But a user who cares about their security should create a separate control key and store it in a place inaccessible over the network. I would even keep it on paper in a safe in the form of 12 mnemonic words, allowing, if necessary, to recreate a pair of keys.
It is also wise to use a separate wallet address for authentication, separating it from the wallet address, which stores all your Ether. The authKey connection with the address of the wallet that created the account can still be traced by analyzing the sequence of transactions of the smart contract. Now you can not set a separate authKey and recoveryKey when creating an account. However, if you refine the smart contract in this direction, the address that created the account will not necessarily be associated with the account owner, which will allow anyone who wants to protect their anonymity.
For user interaction with a smart contract, we created a separate web page. You can create an account on it, change its keys or delete it. To work, the user will need to install the browser plugin MetaMask. If you are already actively using the Ethereum network, most likely you have already installed this plugin, that is, the majority of users who want to access the site via Ethereum will not encounter an additional obstacle in their path.
The overall user authentication process using EtherAuth looks like this:
- The site (backend) contacts the smart contract and receives the user's Ethereum address;
- The site (backend) generates and remembers some message and asks the user to sign this message using the authKey address;
- The user, while on the site (frontend), signs the message using the MetaMask plugin and sends it to the backend;
- The site (backend) verifies the signature, and if everything is in order, it activates the user's session in accordance with its chosen logic.
In our solution for the hackathon, for simplicity, we combined the backend- and frontend-parts, we got one big frontend. In real life, it is important that authentication checks take place in an environment not controlled by the user, that is, not in a browser, but on a server.
Of the problems that we encountered, we can note the verification of the signature in the frontend part. The browser did not support elliptic curves, so I had to add a function to the smart contract that returns the ecrecover result from the message and learn how to pass parameters to it (get them from the signed MetaMask message).
As a result, for two days we received proof-of-concept decentralized authentication using the Ethereum network and the MetaMask plugin. We understand how to modify this system in order to add anonymity to the user. The user has the opportunity to restore access in case of a leak of his primary key (but not in the case of a recovery key leak). The decentralized system is not subject to censorship of large structures, such as Google or Facebook. If it is necessary to censor, the site should implement it independently, but it can do it only within its own system, without affecting the user's access to other systems. The Ethereum network does not conduct transactions very quickly (when creating an account, the user may have to wait a few minutes), but you can get data and verify user authentication very quickly. This solution scales well because there are a lot of data nodes, and anyone can add another one at any time. The complexity of implementing such a solution for site owners is not higher than the complexity of implementing support for OAuth 2.0.
Of course, today users using the Ethereum network are negligible compared to the number of Facebook users. However, the popularity of blockchain technologies is growing, and I believe that in the foreseeable future, such users will become more and more, which means that it will be possible to use decentralized authentication in industrial systems.