npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

keygrip

v1.1.0

Published

Key signing and verification for rotated credentials

Downloads

12,592,288

Readme

keygrip

NPM Version NPM Downloads Node.js Version Build Status Test Coverage

Keygrip is a node.js module for signing and verifying data (such as cookies or URLs) through a rotating credential system, in which new server keys can be added and old ones removed regularly, without invalidating client credentials.

Install

$ npm install keygrip

API

keys = new Keygrip([keylist], [hmacAlgorithm], [encoding])

This creates a new Keygrip based on the provided keylist, an array of secret keys used for SHA1 HMAC digests. keylist is obligatory. hmacAlgorithm defaults to 'sha1' and encoding defaults to 'base64'.

Note that the new operator is also optional, so all of the following will work when Keygrip = require("keygrip"):

keys = new Keygrip(["SEKRIT2", "SEKRIT1"])
keys = Keygrip(["SEKRIT2", "SEKRIT1"])
keys = require("keygrip")()
keys = Keygrip(["SEKRIT2", "SEKRIT1"], 'sha256', 'hex')
keys = Keygrip(["SEKRIT2", "SEKRIT1"], 'sha256')
keys = Keygrip(["SEKRIT2", "SEKRIT1"], undefined, 'hex')

The keylist is an array of all valid keys for signing, in descending order of freshness; new keys should be unshifted into the array and old keys should be popped.

The tradeoff here is that adding more keys to the keylist allows for more granular freshness for key validation, at the cost of a more expensive worst-case scenario for old or invalid hashes.

Keygrip keeps a reference to this array to automatically reflect any changes. This reference is stored using a closure to prevent external access.

keys.sign(data)

This creates a SHA1 HMAC based on the first key in the keylist, and outputs it as a 27-byte url-safe base64 digest (base64 without padding, replacing + with - and / with _).

keys.index(data, digest)

This loops through all of the keys currently in the keylist until the digest of the current key matches the given digest, at which point the current index is returned. If no key is matched, -1 is returned.

The idea is that if the index returned is greater than 0, the data should be re-signed to prevent premature credential invalidation, and enable better performance for subsequent challenges.

keys.verify(data, digest)

This uses index to return true if the digest matches any existing keys, and false otherwise.

Example

// ./test.js
var assert = require("assert")
  , Keygrip = require("keygrip")
  , keylist, keys, hash, index

// but we're going to use our list.
// (note that the 'new' operator is optional)
keylist = ["SEKRIT3", "SEKRIT2", "SEKRIT1"]
keys = Keygrip(keylist)
// .sign returns the hash for the first key
// all hashes are SHA1 HMACs in url-safe base64
hash = keys.sign("bieberschnitzel")
assert.ok(/^[\w\-]{27}$/.test(hash))

// .index returns the index of the first matching key
index = keys.index("bieberschnitzel", hash)
assert.equal(index, 0)

// .verify returns the a boolean indicating a matched key
matched = keys.verify("bieberschnitzel", hash)
assert.ok(matched)

index = keys.index("bieberschnitzel", "o_O")
assert.equal(index, -1)

// rotate a new key in, and an old key out
keylist.unshift("SEKRIT4")
keylist.pop()

// if index > 0, it's time to re-sign
index = keys.index("bieberschnitzel", hash)
assert.equal(index, 1)
hash = keys.sign("bieberschnitzel")

License

MIT