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

@hutiwephy/ape

v1.0.1

Published

Authenticate and Encrypt HTTP with User Credentials (Not TLS-SRP).

Downloads

21

Readme

Authenticated Payload Exchange

Authenticate and Encrypt HTTP with User Credentials (Not TLS-SRP).

This project aims to solve one of the biggest problems with decentralized apps regarding authentication and encrypted data exchange without using certificates.

Note: TLS-SRP is not widely implemented that's why this library exists.

Contents

How does it work?

This data exchange method requires the client and the server to know an identifier and a secret. the secret can be randomly generated or a user password if it is the later then the usage of a salt is required as the key must be of a specified size required by the encryption function.

A key must be derived from the client secret by joining the current date, and using PBKDF2 with a salt of the length required by the encryption function.

When performing a request the Authorization header will be filled with a JWT containing the issuing date the client_id encoded in base64url, the salt in base64url, the signing algorithm and encryption function along side the require parameters (ie: initialization vector aka. iv) the JWT will be signed with the previously generated key. If the body is provided this should be encrypted with the provided function and encoded in base64url chunks each chunk must end with a dot (.).

Note: The hashing function and other key parameters used in the user password case must be known by both parties.

Generating a key

In order to build a key some parameters are required.

  • secret: This is the client secret it can be a password or a random array of bytes.
  • date: The current date in milliseconds counting from 1 Jan 1970 represented in utf8 characters (0-9).
  • salt: The salt to be used to derive the key this must be the correct size to be used with the encryption function.
  • length: Length of the key required by the encryption function

After this requirements are fullfiled a key can be build by concatenating the secret and date and using PBKDF2 to derive the key to the length required by the encryption function.

key = PBKDF2(secret+date, salt, length);

Building the token

The JWT that will be used in the Authorization header will have the following parameters set in the header section:

  • alg: The JWT signing algorithm, can only be:
    • HS256
    • HS384
    • HS512
  • enc: The encryption algorithm, can only be: (* is the size 128, 192, 256)
    • AES-*-CBC
    • AES-*-CFB
    • AES-*-CTR
    • AES-*-ECB
  • iv: the initialization vector must be 16 bytes and always provided.

while on the payload section the following are required:

  • sub: base64url encoded client id
  • salt: base64url encoded salt used to derive the key
  • iat: date used to create the key in ms formated as number type

After populating these fields the JWT must be assembled and signed with the previously generated key.

Note: the JWT can contain more paramters the AES padding is always Pkcs7

Request

The HTTP request must contain the previously generated token in the Authorization Header. when a body is present it can be separated into chunks of variable size, each chunk will be encrypted and encoded into base64url all chunks must end with a dot ..

Response

The HTTP Response will must not echo back the Authorization header and the body formating will follow the same as the Request's body, it can be separated into chunks of variable size, each chunk will be encrypted and encoded into base64url all chunks must end with a dot ..

Documentation

This repository also contains a NodeJS module and browser library that attempts to provide support to the spec above.

const ape = require("@hutiwephy/ape");
<script src="/ape.min.js"></script>

APE core

ape.request(method, url, client_id, client_secret, headers, body)

Performs an asynchronous request with ape functionality

Parameters:

  • method: string Method to be used

    values:

    • GET
    • POST
    • PUT
    • DELETE
  • url: string, URL URL to perform request.

  • client_id: string, ArrayBufferLike Client id. If string then it must be encoded in Base64.

  • client_secret: string, ArrayBufferLike Client secret. If string then it must be encoded in Base64.

  • headers (optional): null, OutgoingHttpHeaders Headers to be provided.

  • body (optional): null, string Body to be sent.

Returns:

  • Promise Server Response

    onfullfilled: ape.Response onferror: Error, TypeError

ape.Response

Object containing a raw and parse attempt of the response body

{
    raw: string|Buffer,
    decoded: Uint8Array|Buffer,
}

ape.libpath (NodeJS only)

Path to the Browser JS library

ape.Session

This class bundles all the required methods for verification and Encryption

// A Session can be built from a JSON Web Token string
var session = new ape.Session(token);

// or a client id and a client secret
var session = new ape.Session(id, secret);

// however when provided with a string this must be in base64 format
var session = new ape.Session(btoa(id), btoa(secret));

// you can also overide or extend the JWT by passing extra options
var session = new ape.Session(btoa(id), btoa(secret), {
    header: {},
    payload: {},
});

session.jwt

Returns the parsed JWT

session.clientId

Returns the Client Id in either Buffer or Uint8Array format.

session.token

Returns the string used in the Authorization header, if the key is present.

session.verify(secret, options)

Returns true or false depending on whether the verification succeeded or failed

This method must be called before the session.encode or session.decode functions, when the client secret was not provided to the constructor.

Note:

  • This method also throws errors it is recommended to catch and handle them
  • This Method only accepts Base64 encoded strings as secrets

Parameters:

  • secret: null, string, ArrayBufferLike Client secret. If string then it must be encoded in Base64.

  • options: jwt.validationOptions Additional JWT validation options. validators.subject will be ignored. tolerance must be set to perform iat (Issued At) validation.

Returns:

  • boolean

session.encode(chunk)

If key is populated it will encode a chunk of data into a body chunk

Parameters:

  • chunk: string, ArrayBufferLike UTF-8 string or Array of Bytes to encode

Returns:

  • string Body chunk string

session.decode(chunk)

If key is populated it will decode a body chunk into a chunk of data

Parameters:

  • chunk: string UTF-8 string to decode

Returns:

  • Buffer, Uint8Array Raw decoded bytes

session.parse(body)

Parse a Request or Response body

Parameters:

  • body: string UTF-8 string to decode

Returns:

  • Buffer, Uint8Array Raw decoded bytes

Browser Extensions

This library extends some functionality on the Browser

window.CryptoJS

The CryptoJS library is fully exposed for personal usage

window.hash(algorithm, message)

Wrapper function around multiple CryptoJS hashing functions

Parameters:

  • algorithm: string Algorithm to use

    values:

    • MD5
    • RIPEMD160
    • SHA1
    • SHA224
    • SHA256
    • SHA384
    • SHA512
  • message: string, ArrayBufferLike Message to encode. Can be a UTF-8 string or an Array of bytes.

Returns:

  • Buffer, Uint8Array Resulting Bytes

window.WordArray2ArrayBuffer(wa)

Convert CryptoJS WordArray to a Uint8Array

Parameters:

  • wa: CryptoJS.lib.WordArray WordArray to convert

Returns:

  • Uint8Array Resulting Bytes

window.request(method, url, headers, body)

Promise based HTTP Request function used by ape.request()

Parameters:

  • method: string Method to be used

    values:

    • GET
    • POST
    • PUT
    • DELETE
  • url: string, URL URL to perform request.

  • headers (optional): null, OutgoingHttpHeaders Headers to be provided.

  • body (optional): null, string Body to be sent.

Returns:

  • Promise Server Response

    onfullfilled: string, Buffer onferror: Error, TypeError

Uint8Array.concat()

NodeJS Buffer like concatenation function.

Parameters: (Takes any iterable)

Returns:

  • Uint8Array Resulting Bytes.

Uint8Array.prototype.toString(encoding)

NodeJS Buffer like toString function with encoding. Defaults to utf8

Parameters:

  • encoding: string Target encoding

    values:

    • utf8
    • base64
    • base64url
    • hex

Returns:

  • string Resulting string.

JSON Web Tokens

jwt.RegisteredClaims

Enum of all JWT Registered claims

const RegisteredClaims = {
    ISSUER: "iss",
    SUBJECT: "sub",
    AUDIENCE: "aud",
    EXPIRATION: "exp",
    NOTBEFORE: "nbf",
    ISSUEDAT: "iat",
    JWTID: "jti"
};

jwt.validationOptions

Object containing data relevant for the validation of a JSON Web Token

{
    critical?:     Array.<string>, // values can be any of jwt.RegisteredClaims
    date?:         number,
    maxlifetime?:  number,
    tolerance?:    number, // Must be set to perform iat, exp and nbf validation
    validators?: {
        issuer?:   Array.<string> | function(string):boolean,
        audience?: Array.<string> | function(string):boolean,
        jwtid?:    Array.<string> | function(string):boolean,
    },
}