🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more
Socket
DemoInstallSign in
Socket

@bryopsida/key-store

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@bryopsida/key-store

A extendable TypeScript Node.JS library that provides a basic key store for data encryption keys

0.1.4
latest
Source
npm
Version published
Weekly downloads
130
7.44%
Maintainers
1
Weekly downloads
 
Created
Source

Key-Store

Quality Gate Status Coverage Security Rating Vulnerabilities Code Smells Bugs

What is this?

This is a typescript library that can be used to create a key store for managing root and data encryption keys. A basic file store key store is included but it can also be extended to persist to a shared store such as redis. What problem does this solve? This was intiailly created as part of a data munging project in which I needed to be able to dynamically encrypt credentials and share them across a distributed system using redis.

How do I use it?

To create your own store extend from the BaseKeyStore and implement the required key slot functions. For example:

import { writeFile, mkdir, access, readFile, unlink, rm } from 'fs/promises'
import { resolveHome } from './resolve.js'
import {
  BaseKeyStore,
  IKeyStoreContextProvider,
  IKeyStoreValueProvider,
} from './baseKeyStore'

/**
 * A implementation of BaseKeyStore that stores the sealed
 * keys into a desiginated spot in the file system, consumers
 * of the class supply providers that give the password, salt
 * and context to use for AAED
 */
export class FileKeyStore extends BaseKeyStore {
  private readonly keyStorePath: string

  /**
   *
   * @param {string} keyStorePath path to the folder where keys will be saved
   * @param {IKeyStoreValueProvider} keyStorePasswordProvider provide the password used to seal keys
   * @param {IKeyStoreValueProvider} keyStoreSaltProvider provide the salt used to seal keys
   * @param {IKeyStoreContextProvider} keyStoreContextProvider provider that will give the appropriate context based on key id
   */
  constructor(
    keyStorePath: string,
    keyStorePasswordProvider: IKeyStoreValueProvider,
    keyStoreSaltProvider: IKeyStoreValueProvider,
    keyStoreContextProvider: IKeyStoreContextProvider
  ) {
    super(
      keyStorePasswordProvider,
      keyStoreSaltProvider,
      keyStoreContextProvider
    )
    this.keyStorePath = resolveHome(keyStorePath)
  }

  /**
   * @Inheritdoc
   */
  protected hasKeyInSlot(keySlot: string): Promise<boolean> {
    return access(this.keyStorePath + '/' + keySlot)
      .then(() => true)
      .catch(() => false)
  }

  private async createKeyStoreDirIfNotExists(): Promise<void> {
    await access(this.keyStorePath).catch(async () => {
      await mkdir(this.keyStorePath, { recursive: true })
    })
  }

  /**
   * @Inheritdoc
   */
  protected async putKeyInSlot(keySlot: string, key: Buffer): Promise<void> {
    await this.createKeyStoreDirIfNotExists()
    await writeFile(this.keyStorePath + '/' + keySlot, key)
  }

  /**
   * @Inheritdoc
   */
  protected async getKeyInSlot(keySlot: string): Promise<Buffer> {
    return readFile(this.keyStorePath + '/' + keySlot)
  }

  /**
   * @Inheritdoc
   */
  protected async deleteKeySlot(keySlot: string): Promise<void> {
    await unlink(this.keyStorePath + '/' + keySlot)
  }

  /**
   * @Inheritdoc
   */
  protected async clearKeySlots(): Promise<void> {
    await rm(this.keyStorePath, { recursive: true, force: true, maxRetries: 3 })
  }

  /**
   * @Inheritdoc
   */
  async close(): Promise<void> {
    // nothing to do
  }
}

You can then use the store like this (snippet from a test):

const storeDir = tmpdir()
const key = randomBytes(32)
const salt = randomBytes(16)
const context = randomBytes(32)

// create a keystore
const keystore = new FileKeyStore(
  storeDir + '/keystore',
  () => Promise.resolve(key),
  () => Promise.resolve(salt),
  () => Promise.resolve(context)
)

// create random data to act as key store
const dek = randomBytes(32)
const id = randomUUID()

// save it
await keystore.saveSealedDataEncKey(id, dek)

// ask for it back
const fetchedDek = await keystore.fetchSealedDataEncKey(id)

// should be the same
expect(fetchedDek).toEqual(dek)

Keywords

crypto

FAQs

Package last updated on 27 Sep 2023

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts