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

cipher-share

v3.3.0

Published

Share data with trusted parties to allow for future secret recovery

Downloads

5

Readme

CipherShare

Introduction

CipherShare is a refined form of a secret-sharing scheme which allows for recovery of secrets in the case of losing access to said secret. These secrets may include passwords, images, files or keys. Currently a secret of any size can be derived into an encrypted secret and a key each of which can be shared with an independent trusted party. By re-collecting the encrypted secret and key it is possible to completely reconstruct the original secret. It is this possibility to reconstruct the original secret that is important - if one loses access to their original secret they can reconstruct it in future.

To emphasise, it is necessary to note that using this scheme to share secrets with trusted parties does introduce the possibility that those trusted parties, or any malicious parties that acquire access to them, can acquire access to the original secret in a manner that would not have been possible otherwise. Such access can be gained through collaboration between the parties that hold the derived secret and key. Only use CipherShare where these risks are acceptable.

Technical Specifications

One of many strengths of use of this library is the handling of data storage. Only the derived secret has to be stored at a size equal to the secret itself and the derived key is instead fixed to 60-bytes in length (when including the authentication tag). Therefore a user could entrust one party with large data storage capabilities the derived secret and the other party the derived key. Encryption and decryption is also performed at an average of 300 MB/s which remains faster than most bottlenecks that may be confronted. Using a public-key cryptosystem to achieve the same effects as performed by CipherShare would achieve an average of 20 MB/s which would mean large images for instance could take several seconds to process.

Multiple derived secrets

To derive a secret into more than two parts (the derived secret and a key) it is possible to reuse CipherShare on each derived secret or key to create multiple derived secrets that can be shared with multiple trusted parties. Performing this sequence ensures that each trusted party would have to collaborate together to reconstruct the secret meaning it would be more difficult for a malicious actor to achieve such a feat. However, because every derived secret (or key) would be required to recreate the original secret there is greater risk of data loss and more significant computational power required.

It is therefore recommended that CipherShare is used only to share a single derived secret and a single derived key between two trusted parties.

How it works conceptually

To explain how CipherShare works it is necessary to imagine two parties in communication with each other across an insecure network. One of the parties in this instance may be imagined to be a server or an API, especially one responsible for data storage. As all actions performed in CipherShare are symmetric the roles of the two parties are interchangeable.

Cipher-Sharing

Given a party desires to share a derived secret and key with two trusted parties such that the collaboration of those two parties will allow for the recovery of the original secret the following can be performed. Initially a randomised key and IV is created as the derived key in an AES cipher to encrypt the secret. Output of this (the derived secret) and the derived key (concatenated with the authentication tag) should be shared through encrypted channels with the trusted parties individually to be stored.

As long as no other party acquires access to the original party's derived key alongside the derived secret than no other party can acquire access to the contents of the original secret. The original party can decrypt the dervied secret as long as they regain knowledge of the derived key. Currently the most effective attacks against this scheme are brute-force attacks and as such this scheme can be considered secure where all previously mentioned conditions hold.

Secret-Sharing

One party intends on creating a derived secret to share with another party. Using their private-key and the other party's public-key they are able to derive a new "shared" key using the ECDH scheme. This dervied key is used alongside a unique IV (i.e. a nonce) in an AES cipher to encrypt the secret. Output of this can be shared across an insecure network with the other party to be stored.

As long as no other party acquires access to either party's private-key or the "shared" dervied key alongside the dervied secret than no other party can acquire access to the contents of the original secret. Either party can reconstruct the dervied key and therefore decrypt the dervied secret as long as they retain knowledge of the other party's public-key (and their own private-key) and the nonce. Currently the most effective attacks against this scheme are brute-force attacks and as such this scheme can be considered secure where all previously mentioned conditions hold.

How it works programmatically

Installation

Begin with installing this module into your project.

npm i cipher-share

Following installation, you can reference the CipherShare class in your project as demonstrated below. Note that referencing will not work unless you are using ESM6 (available for up to date versions of Node JS). If any errors occur you can refer to this official documentation for more assistance.

import { CipherShare, SecretShare } from 'cipher-share'

Cipher-Sharing

Creating derived secret and key for sharing

When a new CipherShare object is instantiated it will generate two values of importance. These two values are the equivalents to the dervied secret and key as established in the previous conceptual explanation. It is these two derived secrets that need to be shared securely with trusted parties (depending on the user's intention for CipherShare).

const encryptMessage = (message) => {
	// Necessary for plaintext to be in form of a Buffer
	let plaintext = Buffer.from(message)

	// Perform encryption/derivation
	let ciphertext = new CipherShare(plaintext)

	// Information needed to recreate "derived key"
	let shareKey = ciphertext.getShareKey()
	let nonce = ciphertext.getNonce()
	let authTag = ciphertext.getAuthTag()
	console.log(shareKey, nonce, authTag)

	// Information equivalent to "derived secret"
	let secret = ciphertext.getSecret()
	console.log(secret)
}

It is up to each individual project to determine how they decide to transfer these secrets, and what precautions they will take to guarantee safety of these secrets.

Recovering secret from derived secret and key

In the case that the user has lost access to their secret and desires to perform recovery, a similar process as to the derivation performed above is conducted. Assuming that the user has received the derived secret and the information required to regenerate the dervied key securely the following can be conducted.

const decryptMessage = (secret, shareKey, nonce, authTag) => {
	// Decrypt derived secret
	let plaintext = CipherShare(secret, shareKey, nonce, authTag)

	// Information equivalent to original message
	let message = plaintext.getSecret().toString()
	console.log(message)
}

Secret-Sharing

Creating derived secret and key for sharing

When a new SecretShare object is instantiated it will generate two values of importance. These two values are the equivalents to the dervied secret and key as established in the previous conceptual explanation. It is these two derived secrets that need to be shared securely with trusted parties (depending on the user's intention for CipherShare).

const encryptMessage = (message, privateKey, publicKey, nonce) => {
	// Necessary for plaintext to be in form of a Buffer
	let plaintext = Buffer.from(message)

	// Perform encryption/derivation
	let ciphertext = SecretShare(plaintext, privateKey, publicKey, nonce)

	// Information needed to recreate "derived key"
	let nonce = ciphertext.getNonce()
	let authTag = ciphertext.getAuthTag()
	console.log(nonce, authTag)

	// Information equivalent to "derived secret"
	let secret = ciphertext.getSecret()
	console.log(secret)
}

It is up to each individual project to determine how they decide to transfer these secrets, and what precautions they will take to guarantee safety of these secrets.

Recovering secret from derived secret and key

In the case that the user has lost access to their secret and desires to perform recovery, a similar process as to the derivation performed above is conducted. Assuming that the user has received the derived secret and the information required to regenerate the dervied key securely the following can be conducted.

const decryptMessage = (secret, privateKey, publicKey, nonce, authTag) => {
	// Decrypt derived secret
	let plaintext = new CipherShare(secret, privateKey, publicKey, nonce, authTag)

	// Information equivalent to original message
	let message = plaintext.getSecret().toString()
	console.log(message)
}

Security properties

By using the AES-256-GMC cipher with a sufficiently secure key of 32-bytes in length and a sufficiently unique nonce of 12-bytes in length on a message for encryption, a sufficiently random string equal in length to the secret can be calculated. Therefore, the security of CipherShare is dependent on the uniqueness of SHA256 hashing algorithms and the security of the AES cipher being used. Assuming that the AES-256-GMC cipher is robust and that SHA256 is sufficiently unique when applied on different strings as currently indicated by NIST, then CipherShare has 256-bit security. This is considered sufficient for any confidential information.

Exercise caution when using this module or any other cryptographic module however. It is important to note that no guarantee can be made of the robustness of this module or any others. Any unintended consequences from using this module is the responsibility of the user of this module. This is true of all cryptography. Users can exercise caution by considering if use of this module is truly necessary in their program, or if the risk is greater than the reward of using it.