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

@bicycle-codes/crypto-stream

v0.0.21

Published

Streaming encryption for the browser

Downloads

975

Readme

crypto stream

tests module types license

Streaming encryption for the browser, based on Encrypted Content-Encoding for HTTP (RFC 8188)

install

npm i -S @bicycle-codes/crypto-stream

fork

This is a fork of SocketDev/wormhole-crypto, just adding types.

example

import { Keychain } from '@bicycle-codes/crypto-stream'

// Create a new keychain. Since no arguments are specified, the key and salt
// are generated.
const keychain = new Keychain()

// Get a WHATWG stream somehow, from fetch(), from a Blob(), etc.
const stream = getStream()

// Create an encrypted version of that stream
const encryptedStream = await keychain.encryptStream(stream)

// Normally you'd now use `encryptedStream`, e.g. in fetch(), etc.
// However, for this example, we'll just decrypt the stream immediately
const plaintextStream = await keychain.decryptStream(encryptedStream)

// Now, you can use `plaintextStream` and it will be identical
// to if you had used `stream`.

example with blobs

See ./example for a version that uses blobs + a local vite server.

import { Keychain } from '@bicycle-codes/crypto-stream'

const encryptedData = await fetch(imgUrl)
const decryptedStream = await keychain.decryptStream(encryptedData.body)
const response = new Response(decryptedStream)
const blobUrl = window.URL.createObjectURL(await response.blob())

// ...

function Component () {
    return html`<img src="${blobUrl}" />`
}

API

new Keychain([key, [salt]])

constructor (key?:string|Uint8Array, salt?:string|Uint8Array)

Type: Class

Returns: Keychain

Create a new keychain object. The keychain can be used to create encryption streams, decryption streams, and to encrypt or decrypt a "metadata" buffer.

key

Type: Uint8Array | string | null

Default: null

The main key. This should be 16 bytes in length. If a string is given, then it should be a base64-encoded string. If the argument is null, then a key will be automatically generated.

salt

Type: Uint8Array | string | null

Default: null

The salt. This should be 16 bytes in length. If a string is given, then it should be a base64-encoded string. If this argument is null, then a salt will be automatically generated.

keychain.key

key:Uint8Array

The main key.

keychain.keyB64

keyB64:string

The main key as a base64url-encoded string.

keychain.salt

salt:Uint8Array

The salt.

Implementation note: The salt is used to derive the (internal) metadata key and authentication token.

keychain.saltB64

saltB64:string

The salt as a base64-encoded string.

keychain.authToken()

authToken ():Promise<ArrayBuffer>

Returns the authentication token. By default, the authentication token is automatically derived from the main key using HKDF SHA-256.

The authentication token can be used to communicate with the server and prove that the client has permission to fetch some data. Without a valid authentication token, the server can reject the request.

Since the authentication token is derived from the main key, the client would present it to the server as a "reader token" to prove that it is in possession of the main key without revealing the main key to the server.

For destructive operations, the client should instead present a "writer token", which is not derived from the main key but is provided by the server.

keychain.authTokenB64()

authTokenB64 ():Promise<string>

Returns the authentication token as a base64-encoded string.

keychain.authHeader()

authHeader ():Promise<string>
// => `Bearer sync-v1 ${authTokenB64}`

Returns a Promise that resolves to the HTTP header value to be provided to the server, as a base64 string. It contains the authentication token.

keychain.setAuthToken(authToken)

setAuthToken (authToken:string|Uint8Array|null):void

Update the keychain authentication token to the given authToken.

authToken

Type: Uint8Array | string | null

Default: null

The authentication token. This should be 16 bytes in length. If a string is given, then it should be a base64-encoded string. If this argument is null, then an authentication token will be automatically generated.

keychain.encryptStream(stream)

encryptStream (stream:ReadableStream):Promise<ReadableStream>

Type: Function

Returns: Promise<ReadableStream>

Returns a Promise that resolves to a ReadableStream encryption stream that consumes the data in stream and returns an encrypted version. Data is encrypted with Encrypted Content-Encoding for HTTP (RFC 8188).

stream

Type: ReadableStream

A WHATWG readable stream used as a data source for the encrypted stream.

keychain.decryptStream(encryptedStream)

Type: Function

Returns: Promise<ReadableStream>

Returns a Promise that resolves to a ReadableStream decryption stream that consumes the data in encryptedStream and returns a plaintext version.

keychain.decryptStreamRange(offset, length, totalEncryptedLength)

function decryptStreamRange (
    secretKey:CryptoKey,
    offset:number,
    length:number,
    totalEncryptedLength:number,
    rs:number = RECORD_SIZE
):{
    ranges:{ offset:number, length:number }[],
    decrypt:(streams:ReadableStream[])=>ReadableStream
}

Returns a Promise that resolves to a object containing ranges, which is an array of objects containing offset and length integers specifying the encrypted byte ranges that are needed to decrypt the client's specified range, and a decrypt function.

Once the client has gathered a stream for each byte range in ranges, the client should call decrypt(streams), where streams is an array of ReadableStream objects, one for each of the requested ranges. decrypt will then return a ReadableStream containing the plaintext data for the client's desired byte range.

encryptedStream

Type: ReadableStream

A WHATWG readable stream used as a data source for the plaintext stream.

keychain.encryptMeta(meta)

encryptMeta (meta:Uint8Array):Promise<Uint8Array>

Returns a Promise that resolves to an encrypted version of meta. The metadata is encrypted with AES-GCM.

Implementation note: The metadata key is automatically derived from the main key using HKDF SHA-256. The value is not user-controlled.

Implementation note: The initialization vector (IV) is automatically generated and included in the encrypted output. No need to generate it or to manage it separately from the encrypted output.

meta

Type: Uint8Array

The metadata buffer to encrypt.

keychain.decryptMeta(ivEncryptedMeta)

decryptMeta (ivEncryptedMeta:Uint8Array):Promise<Uint8Array>

Returns: Promise<Uint8Array>

Returns a Promise that resolves to a decrypted version of encryptedMeta.

ivEncryptedMeta

Type: Uint8Array

The encrypted metadata buffer to decrypt.

keychain.encryptBytes(bytes)

async function encryptBytes (
    bytes:ArrayBuffer|Uint8Array,
    opts?:{ iv?:Uint8Array },
):Promise<Uint8Array>

Encrypt and return the given data in-memory, not using streams.

keychain.decryptBytes(bytes)

async function decryptBytes (
    bytes:Uint8Array,
):Promise<ArrayBuffer>

Decrypt the given data in-memory, without streaming.

plaintextSize(encryptedSize)

function plaintextSize (
  encryptedSize:number,
  rs:number = RECORD_SIZE
):number

Given an encrypted size, return the corresponding plaintext size.

encryptedSize(plaintextSize)

function encryptedSize (
  plaintextSize:number,
  rs:number = RECORD_SIZE
):number

Given a plaintext size, return the corresponding encrypted size.

credits

Thank you Feross and SocketDev team for writing and publishing this.