@linkedmink/passport-mutual-key-challenge-client
TypeScript icon, indicating that this package has built-in type declarations

0.1.5 • Public • Published

passport-mutual-key-challenge

Build State

This npm package implements a Passport strategy to authenticate a client by their public/private key pair. This method was primarily meant to be used in an internal environment, not a public facing site, where clients trust can be establish ahead of time.

The client starts authenticating by making a challenge request with a message encrypted by the server's public key. The server tries to find the public key of the user making the request. If found, it will decrypt and verify the signature as proof of its identiy. The decrypted message is sent back to the client with a encrypted, signed challenge issued by the server. Likewise, the client will decrypt and verify, sending back the decrypted message. Both parties have verified each others identiy and the handshake is complete.

Getting Started

Install the npm package

npm install --save @linkedmink/passport-mutual-key-challenge

Demo Program

The demo programs demonstrates how to use the strategy to do an initial handshake. Both the client and server have a public/private key pair, so you will need to generate the keys

# Generate the server key
ssh-keygen -t rsa -b 4096 -m PEM -f server.key
openssl rsa -in server.key -pubout -outform PEM -out server.key.pub
# Generate the client key
ssh-keygen -t rsa -b 4096 -m PEM -f client.key
openssl rsa -in client.key -pubout -outform PEM -out client.key.pub
# Move keys to demo root folder
mv ./*.key* ./src

The project uses Yarn as a package manager. Make sure it's installed globally and install dependency.

npm install -g yarn
yarn install

The demo server passport mutual authentication to do the initial handshake, using server.key as its private key. The users are mocked by loading a fixed client.key.pub file as the user's public key. If the handshake is successful, a JWT is issued for subsequent request. The server has two endpoints:

  • POST /authenticate : A route that accepts a challenge messge in the request body.
  • GET /protected : A route protected by JWT that just echos back the decoded JWT.
# Start the demo server
cd ./src
yarn start

The demo client does a handshake with the server using the opposite keys and outputs the result of the /protected endpoint on success:

# Run through a handshake
yarn run start:client

Distributed Systems

By default the the strategy uses a local memory cache to store pending challenges. This won't work if request are load balanced across multiple instances since a request may arrive on a different instance without the cached challenge.

You can implement the CachedChallenge interface and provide that as an option.

new MutualKeyChallengeStrategy({
  serverKey: myPrivateKey,
  userFunc: getUser,
  challengeOrResponseFunc: challengeByBase64Body("userId", "challenge", "response"),
  challengeCache: new MyCustomChallengeCache(),
})

See node-user-service for an example using Redis.

Package Sidebar

Install

npm i @linkedmink/passport-mutual-key-challenge-client

Weekly Downloads

3

Version

0.1.5

License

MIT

Unpacked Size

36.4 kB

Total Files

33

Last publish

Collaborators

  • linkedmink