Old school two factor authentication — photo by Phong6698

In my previous post I described how smart contracts may be used to implement payment processor software. Today I will present my another inspiration how smart contracts might be used. In this post I’m not going to explain what Ethereum or smart contract is, so if you need it, please read this post.

Theory

Two-factor authentication (also known as 2FA) is a method of confirming a user’s claimed identity by utilizing a combination of two different components. Two-factor authentication is a type of multi-factor authentication.

Most of us probably use 2FA for our bank account transfers or even for email (e.g. Gmail). Most common methods are one-time-passwords (generated by an application or a hardware token) or SMS messages with secret codes. Why not to use smart contracts for that?

Smart contracts may receive (along with Ether and tokens) data from an account that are in hand of users (or computers), so we may use Blockchain as an authentication channel. In order to send data to a smart contract, the caller (a person or a computer) has be associated with an Ethereum account and use this account’s private key (PK). Data are kept on the Blockchain and might be read by everybody. Security of this authentication channel depends mainly on keeping private key secret. However I assume, that most Ethereum users is aware of fact that PK is something that should be protected.

In example above let’s consider scenario when 2FA is required during login process. Only user that authenticated with both factors will be trusted by the app. Here is how in that case the 2FA with the Blockchain may look like:

User signs up on the application site. He provides

e.g. email, password (1st authentication factor) and address of his Ethereum account (e.g. 0xF00BF74C2C530) User logs in with their email and password Application ask him to authenticate with Ethereum account and provides authentication token User sends authentication token as data to the Application’s smart contract The smart contract stores information, that sender address 0xF00BF74C2C530 has sent given token The application reads token that was stored in smart contract by account with address 0xF00BF74C2C530. If it’s correct token then user is authenticated

Maybe it sounds a bit complex but we may sum it up in 2 sentences:

Application sends token to the user

User sends it to the smart contract using his Ethereum account

Implementation

You will find complete code of the Dapp in GitHub repository, but please read the post first. The smart contract which stores a token and associated sender account address is super easy.

In this implementation I used uint type for token to save gas (since storing e.g. strings would be more expensive). Prover is the address of user that is trying to authenticate.

The backend part is not that simple. In my example I used Express as a backend server. It serves 2 things:

single page app written in AngularJS

web service that serves data to this app and communicates with blockchain

Single-page-app is quite ordinary except that is uses Web3 JS library that exposes simple API for communicating with smart contracts. This library must be provided by web browser e.g. by Chrome extension like Metamask or Parity. During development I used Metamask but that’s just user’s choice.

Backend service is just a mock for the purpose of that blogpost. It keeps it’s state in memory (not recommended for production apps) and to maintain user’s session it uses cookie-session which is library used by Express.

When user logs in with password the session is created, however the verification flag is set to false, so he is not fully authenticated. Then authentication token is randomly generated, saved and sent to the user.

Now user needs to send token to the smart contract with the Ethereum account that was provided during registration. It’s done with a service (I named it Tufa) using a web3 wrapper called ethClient. The most important parts are where it creates a proxy object to interact with the contract (line 2) and sends the token (line 23). All the rest is boilerplate.

At the end backend verifies if token was set by the user and if it was, the token verification flag in session is set to true.

Now user is authenticated by both factors and application on both ends (on front and backend) will trust him.

Discussion

The solution above is naive and for production use it would need couple more tweaks such as limited time for Blockchain authentication (now it’s limited to session’s lifespan) but generally implements the concept of 2FA with Ethereum’s Blockchain.

What are benefits of that solution? Users don’t need to provide information about their phone number to the application. Phone number is easy to trace and most of people want to keep their number private. There is no need to integrate with third parties such as SMS gateways or authentication tokens providers. It doesn’t force user to install additional software if he already uses Blockchain. Security is guaranteed by the Blockchain and as secure as Private Key to the user’s Blockchain account. Ethereum network guarantees high availability with no cost.

On the other hand 2FA authentication in this manner will cost user real money. Couple cents with current gas prices per each attempt. In this model cost of authentication is moved to the user, application owner doesn’t need to pay for SMS gateway or authentication app. The other problem is time, user will need to wait from about 15 second up to couple minutes depending on Gas price that was set. It’s worth to mention that the latest Byzantium hard fork decreased average block time from 30 to 13 seconds. This could be improved when Proof-of-stake will be implemented on Ethereum network. The other issue might be transparency of blockchain, other third party (e.g. competition) may trace our users’ activity. Some of the issues mentioned above might be fixed with private Ethereum blockchain, but then it’s not so simple solution anymore.

Pros:

Simplicity

Privacy of the users

Availability

Security

Cons:

Cost of authentication

Speed

Transparency

Summary

Experimenting with smart contract has taught me that it’s a very handful tool, however Ethereum’s blockchain doesn’t support data privacy or high-performance. You must be aware of that, when designing solution. Modern Blockchain based applications would be limited to the areas that those features aren’t an issue. On the other hand it forces developers and companies to design their applications and businesses in a way to benefit from Blockchain pros and avoid its limitations. I believe that Ethereum’s roadmap will fill those gaps in the near future with solutions such us Plasma or better support for zero knowledge proof. Source code discussed in this blogpost is available on GitHub. You may avoid some of those issues by using private blockchain but running private blockchain might be complex and expensive.