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 🙏

© 2025 – Pkg Stats / Ryan Hefner

encrypted-stream

v1.2.0

Published

[![Version npm](https://img.shields.io/npm/v/encrypted-stream.svg?logo=npm)](https://www.npmjs.com/package/encrypted-stream)

Readme

encrypted-stream: Simple streaming encryption with authentication

Version npm

encrypted-stream is a simple and safe encryption library that provides a simple API for implementing userspace encrypted networking protocols. Inspired on simplicity of NaCL aimed to provide similar API but for authenticated two-side protocols.

Features

  • ✍️ Based on TLS and HomeKit Accessory Protocol
  • 🏎Fast and trusted Ed25519 and Curve25519 cryptography
  • 💪NaCl as base library for encryption implementation
  • 🔐Long term keys can be stored on hardware token
  • 🔑Forward Secrecy (new key per connection)

Getting Started

Install

yarn add encrypted-stream

Need universal-secure-random

yarn add universal-secure-random

Configuration

encrypted-stream protocol expects both sides to have assigned unique endpointId and Ed25519 key. Both sides have to know public key and endpointId of another.

Server Engine

ServerEngine can not be reused between connections. Create a new one for each incoming connection.

Keys

To create server you need a Ed25519 key that is stored persistently in some safe place. Losing the key will lead to impossibility to connect to a server by clients. Signer for this public key - a function that accepts buffer and creates a digital signature for it. For simplicity we provide createSigner function that creates this function from private key for you.

Peer Resolver

encrypted-stream does not send public keys since it should have them already therefore to make everything work you need to provide a function (endpointLookup in example bellow) that resolves an endpointId to a publicKey or a null if endpoint is unknown.

Example

import { newEd25519Key, createSigner, ServerEngine } from 'encrypted-stream';

const ltsKey = newEd25519Key();
const ltsSigner = createSigner(ltsKey.secretKey);
const serverEndpointId = 'eego-RANDOM-ID';
const endpointLookup = (id: string) => resolveKeyByIdOrNull(id); 

const server = new ServerEngine({
  endpointId: serverEndpointId,
  publicKey: ltsKey.publicKey,
  signer: ltsSigner
}, endpointLookup);

Client Engine

Client Engine is similar to Server one: you need Ed255519 key, endpoint ids and server keys.

import { newEd25519Key, createSigner, ClientEngine } from 'encrypted-stream';

const clientLTSKey = newEd25519Key();
const clientLTSSigner = createSigner(clientLTSKey.secretKey);
const clientEndpointId = 'user1';
const serverEndpointId = 'eego-RANDOM-ID';
const serverPublicKey = ....;

const client = new ClientEngine({
  endpointId: clientEndpointId,
  publicKey: clientLTSKey.publicKey,
  signer: clientLTSSigner
}, { endpointId: serverEndpointId, publicKey: serverPublicKey });

Handshake

Before being able to exchange encrypted messages handshake protocol must be executed. If any of the methods return null or false you can't use engine anymore - all methods will throw an error.

// First create Client Hello message
let clientHello = client.getClientHello();

// Deliver to server and apply
if (!server.setClientHello(clientHello)) {
  throw Error('Invalid Client Hello');
}

// Create Server Hello message
let serverHello = server.getServerHello();

// Deliver to client and apply
if (!client.setServerHello(serverHello)) {
  throw Error('Invalid Server Hello');
}

// Create Peer Info message
let clientPeerInfo = client.getPeerInfo();

// Deliver Peer Info to server
if (!server.setPeerInfo(clientPeerInfo)) {
    throw Error('Invalid Peer Info');
}

// Here you can find connected endpointId
const endpointId = server.endpointId;

Frame encryption and decryption

After a successful handshake encrypt and decrypt functions became available. encrypted-stream protocol requires strict order of decription of messages: they have to be decrypted in the same order as was encrypted. Incorrect order will lead to aborting engine. If decrypt method returns null then frame was invalid and engine is aborted.

const chipherText = server.encrypt(Buffer.from('Hello World!', 'utf-8'));
const plainText = client.decrypt(encrypted);
console.lof(plainText!.toString('utf-8')); // Ouput: Hello World!

License

MIT