Experimenting with Authentication Concepts

Ibrahim AminIbrahim Amin
3 min read

I recently felt like revisiting some areas related to web development and doing some from-scratch experimentation for learning purposes, and for this article, I will be experimenting with authentication.

What is authentication?

Authentication in general is the process of verifying the identity of a user, device, or system. In other words, it ensures that an entity is who or what it claims to be, this is typically done by validating credentials such as passwords, bio-metrics or security tokens.

Authentication for the web

HTTP is a stateless protocol, each request doesn’t depend on a previous request and the server doesn’t know if two requests came from the same client, so you would usually save some state on the client and keep sending it with every request. Browsers offer client-side storage that fulfills that purpose, you can use cookies or local storage and the browser/client will keep attaching some kind of credentials or security tokens representing a claim to be some user, device or system to each request so that the server can authenticate and validate that claim.

The problem is, you shouldn’t blindly trust the client, clients can claim to be whoever they want to be or sometimes impersonate other users by editing or tampering with the stored state.

For example, a silly implementation of utilizing that client state is by just storing a “user” cookie that contains the email of the person who the user is claiming to be, if the server just trusts it, that person can just edit the value of that cookie to another email and impersonate other users.

It’s obvious now that some of the requirements of that “piece of data” that the user or the client will keep as it’s “identity claim” are:

  • It mustn’t be predictable or guessable (e.g. emails are bad because people can guess emails and impersonate other users, but if it is some kind of cryptographically-secure random bytes it won’t be something that I can just sit and guess, or construct it).

  • Preferably it should expire after some specific finite amount of time.

  • The server should store that piece of data in some persistent storage so that it can later validate that it was the one that issued that piece of data and that it was actually issued before.

Sessions

At this point we can adopt a strategy where the server sends a piece of data to the client (that the client will use in the future to claim an identity) but that piece of data is:

  1. Unpredictable and not guessable so that it is not construct-able on purpose.

  2. The server stores it in a persistent storage so that it can later verify that it actually issued that piece of data at an earlier point in time.

  3. Expires after some finite amount of time so that if it was leaked or hijacked it becomes invalid at some point.

We will call that piece of data a Session.

Up until now, we can simply represent it like this:

package sessions

import "time"

type Session struct {
    Id        string    `json:"id"` // cryptographically-secure random bytes.
    CreatedAt time.Time `json:"createdAt"`
}

func New(id string) *Session {
    return &Session{
        Id:        id,
        CreatedAt: time.Now(),
    }
}

It is the responsibility of the caller to provide a suitable secure id, I will use my own implementation that generates a secure random string of length n providing 6 * n bits of entropy.

package utils

import (
    "crypto/rand"
    "encoding/base64"
)

// important: this function generates `n * 6` bits of entropy.
func SecureRandomString(n uint32) (string, error) {
    buf := make([]byte, 2*n) // # of bits of entropy depends on chosen `n`, aim for no less than 120 bits of entropy.

    _, err := rand.Read(buf) // cryptographically-secure random source.
    if err != nil {
        return "", err
    }

    return base64.URLEncoding.EncodeToString(buf)[:n], nil
}

Some examples of securely generated session IDs of length 20 (e.g. 20 × 6 = 120 bits of entropy):

  • 968bfSChqWudepzYzgN9

  • iJLlKbPq3Dkhtmlv3Ny2

  • eW023-WlNz2F-7_D2lDz

0
Subscribe to my newsletter

Read articles from Ibrahim Amin directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Ibrahim Amin
Ibrahim Amin