1. Getting started - adonisv79/express-swish-protocol GitHub Wiki

What is express-swish-protocol?

This middleware is basically the expressJS implementation of the swish-protocol. It allows developers to create API's with session management that encrypts each transaction (or transmission) with a freshly generated key from both client and server.

What it is (and not)

  1. Swish does not bother with authentication and authorization. It just manages the security of the transactions on each request. You are free to utilize any authentication and authorization mechanisms while utilizing swish.
  2. Swish is not HTTPS. while it allows for encryption end-to-end even on HTTP, we recommend it runs in tandem with HTTPS for twice the security

When to use it

The swish protocol is only used when you make an API that...

  1. Does not allow multiple asynchronous requests coming from 1 client at a time. It enforces that the client must complete each request before they can receive the next key sets to make another request. Going against it breaks their request chain thus making them lose their session.
  2. You have an Express API that is not just web client focused. Express-Session works for cookies and hides several abstractions of handling them. However that limits us to only web clients. Managing your own session creation and retrieval source allows us to manage API session's that any app that can connect thru REST.

How it works

Swish has 2 major flows. the Handshake (or introduction step) and the Communications (transaction step).

Handshake

Handshake allows the client to identify itself to the server and kickstart a new session

  1. The client generates a valid handshake request signature by doing the following
    1. Generate a new RSA keys (public + private)
    2. Generate a new AES Key and IV (initialization vector)
    3. Encrypt the RSA public key with the AES Key and IV
    4. Client sends its communications request set containing the following
      • The encrypted RSA public key
      • The AES Key and IV
      • action 'handshake_init'
  2. The server upon receiving a 'handshake_init' action, validates the request and then performs the following
    1. The server retrieves the RSA public key (to be used for the response) by decrypting with the AES keys
    2. As this is a new user session, create a new session by triggering the onSessionCreate callback provided by the developer.
    3. Server generates its own RSA (public + private) keys and an AES Keys
    4. Encrypts the RSA public key using the new AES Key and IV.
    5. Using the client's public key, encrypt the new AES Key and IV
    6. Server sends its handshake response set containing the following
      • The encrypted RSA public key (telling the client that on their next request, encrypt message using this)
      • The encrypted AES Key and IV
      • The unique session_id
  3. The client (upon receiving the response), will
    1. Decrypt the AES Key and IV using the client's previous private key
    2. Use the decrypted Key and IV to unpack the server generated public key (to be used on the next transmission) and store it
    3. Store the session_id that it will use on any request moving forward

Communications

Communications allows the client to transmit data to the server securely using an existing session key set

  1. The client generates a valid communications request signature by doing the following
    1. Generate a new RSA keys (public + private)
    2. Generate a new AES Key and IV (initialization vector)
    3. Encrypt the RSA public key with the AES Key and IV
    4. if the request has a body(payload), encrypt this also using AES Key and IV 5 Encrypt the AES Key and IV with the last server provided public key
    5. Client sends its communications request set containing the following
      • The encrypted RSA public key
      • The encrypted AES Key and IV
      • The encrypted payload (if any)
      • The unique session_id
      • action 'request_basic'
  2. The server upon receiving a 'request_basic' action, validates the request and then performs the following
    1. As this should be an existing session, retrieve the session using the session id.
      1. call on the developer provided implementation for onSessionRetrieve()
      2. if the session is not found or is corrupted, reject the request and end transaction
      3. if found, return the session value containing the session id and session 'previous' keys
    2. The server retrieves the client's AES key and IV by decrypting with their previous private keys.
    3. The server retrieves the RSA public key (to be used for the response) by decrypting with the AES keys
    4. If the request has an encrypted body by decrypting this with the AES keys
    5. Server can now process the request by passing (next) to the middleware stack.
  3. The server is ready to respond. This is handled when a middleware route has called res.sendSwish()
    1. Server generates its own RSA (public + private) keys and an AES Keys
    2. Encrypts the RSA public key using the new AES Key and IV.
    3. if the response has a body(payload), encrypt this also using AES Key and IV
    4. Using the client's public key, encrypt the new AES Key and IV
    5. Server sends its handshake response set containing the following
      • The encrypted RSA public key (telling the client that on their next request, encrypt message using this)
      • The encrypted AES Key and IV
      • The encrypted payload (if any)
      • The unique session_id
  4. The client (upon receiving the response), will
    1. Decrypt the AES Key and IV using the client's previous private key
    2. Use the decrypted Key and IV to unpack the server generated public key (to be used on the next transmission) and store it
    3. Decrypt the body (if any) using the AES Key and IV