Signatures as Authentication in Web3
Tags: ethereum, blockchain, web3, cryptography
Published: 2022-03-22 01:42:08

When interacting with web3 apps, you may have seen a signature request in your wallet that looks like this. This article explains what this signature is and how it's used as authentication.

![Screenshot of a signature request in MetaMask](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fzc9m17qsppvjafg735x.png) 

## What is a signature and what does it prove?
A cryptographic signature proves that the signer has the **private key** to a **public address**. A **public address** on the Ethereum blockchain is a 42-character hexadecimal address derived from the public key controlling the account with 0x appended in front. e.g., 0x88c78f158cac85f17ecfc063259543c5dc345ef3. Anyone can send money to an account using the public address, or look up the account activity and assets. However, to _control_ the assets in the account, you need to have the **private key**.

Ethereum wallets, such as MetaMask and Coinbase Wallet, store your public key and private key for you, and protect against apps directly accessing the private key. Instead, apps rely on a **cryptographic signature** that proves ownership of the address through the [Elliptic Curve Digital Signature Algorithm](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm), which **allows any external party to verify the signature without knowing the private key**. 

## Benefits of using a signature for authentication
In web3 apps, a user's Ethereum address is increasingly replacing a username or email to identify a user. And instead of a password to authenticate that a user controls the digital identity, a signature can be used.

Leveraging an existing Ethereum account is a lightweight way to onboard web3 users. It's faster than traditional account creation flows, and doesn't require the user to create and store yet another password. It also allows the user more anonymity, since they don't have to reveal private details like their email.

Unlike blockchain transactions, signature generation and verification can be done off-chain, and therefore requires no gas fees. And while it proves a user's control of an Ethereum address, future blockchain transactions will still require explicit approval through a separate wallet request.

## How signatures are used in hybrid apps
Some apps, such as [Snapshot](https://snapshot.org/) and [OpenSea](https://opensea.io/) use a hybrid of blockchain data and data from a private database. These apps will use a traditional database to store off-chain actions, such as voting (on Snapshot proposals) or favoriting NFTs (OpenSea stores users' favorited NFTs). Onboarding onto these apps is easy, because a user just has to allow it to connect to their Ethereum wallet. But to store the outcome of these actions, or any off-chain details about the user (such as profile name and photo), these apps must authenticate the user's digital identity.

For example, to change an OpenSea profile's details, the user must authenticate to prove they control this address.

![Screenshot of signature request in MetaMask wallet to login to OpenSea](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/229u75wl9hy1iwcqi2xv.png) 

For apps using signature authentication, it's important not to allow the same signature to be used twice. This is why the messages vary, and often include a [nonce](https://en.wikipedia.org/wiki/Cryptographic_nonce). 

## How to generate and verify signatures

### On Etherscan
To sign or verify a signature right now, you can use [Etherscan's Verified Signature tool](https://etherscan.io/verifiedSignatures#).

![Screenshot of signature tool with open MetaMask wallet requesting signature](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rgnpdcpexn8p7tlsn0tn.png)
_Connect a wallet and enter any message. Those two inputs, plus your private key, generate a unique hash._

![Screenshot of signature verification in etherscan](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/htjjtpx4a8ra1lpr2rp3.png)
_To verify this signature came from the wallet's owner, another party can input the signature hash, along with the address and message to validate._ 

### In your frontend app

To request a signature in your web3 app, you can use a library like [web3.js](https://web3js.readthedocs.io/en/v1.7.1/web3-eth-personal.html#sign) on the frontend. The code snippet below shows how to generate a `signatureHash` using a web3.js method, then an example of passing it to any signature verification API to your backend.

```

const signatureHash = await web3.eth.personal.sign(message, address)
someSignatureVerificationAPI(message, address, signatureHash)

```

## Conclusion
As the Ethereum address has replaced the account username, the signature has replaced the password. Because a cryptographic signature proves the user controls the private key to the public address, it is a secure method of authentication. Apps can use this gas-less primitive of Ethereum to verify a user has control over the digital identity provided by the address, and provide authentication to do arbitrary, non-web3 actions.