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

@scft.dev/easycrypto

v1.0.1

Published

EasyCrypto is first part of the scft utils set. It is a lightweight TypeScript wrapper around the crypto package, exposing certain basic hashing and cryptographic functions in a simplified, easy to use manner. It's probably just meaningful for our ow

Downloads

12

Readme

EasyCrypto

EasyCrypto is first part of the scft utils set. It is a lightweight TypeScript wrapper around the crypto package, exposing certain basic hashing and cryptographic functions in a simplified, easy to use manner. It's probably just meaningful for our own internal projects, but if others find it useful, then that's excellent!

It allows for quick and easy encryption with or without a supplied passphrase, generating a random one if needed. It will supply a hash of the supplied or generated passphrase (but will not supply a generated passphrase itself).
The hash, provided as a Buffer, can be used to generate a new KeyInfo object which will enable the successful decryption of encrypted data.

The decryptor should be able to decrypt any data encrypted with supported algorithms/modes, but if the encrypted package does not include the authTag (for gcm) and iv in appropriate positions at the end of the stream, then they will need to be manually concatenated prior to to successful decryption.

[encrypted data {n bytes}] + [authTag {0-16 bytes}] + [iv {12-16 bytes}]

Primary Functionality

  • Supports aes-256-cbc and aes-256-gcm algs/modes
  • Generates a passphrase-based or randomized key hash
  • Encrypts using cbc or gcm
  • Decrypts using cbc or gcm respectively
  • Concats iv (and authTag for gcm) to end of encrypted stream in third-party deconstructable manner.
  • Derives iv (and authTag for gcm) from end of encrypted stream
  • Hashes a given string

Notable Missing Functionality

  • cbc mode does not support mac/hmac authentication (the original cbc functionality is left in for backwards compatibility with early use) (recommed using gcm with authTag rather than cbc for new use cases)

Example 1 - Defaults, Generated Secret

(No comments or outputs)

import { EasyCrypto } from "EasyCrypto";

// Encrypt Data
const msg = Buffer.from('A test string for gcm encryption.');
const ci = EasyCrypto.generateAESCipherInfo();
const encrypted = EasyCrypto.encryptWith.aes256gcm(ci, msg);
const keyBytes = EasyCrypto.exportKey(ci.keyInfo.key);
const keyString = keyBytes.toString('hex');

// Decrypt Data (using key generated above)
const keyString2 = keyString;
const keyBytes2 = Buffer.from(keyString2, 'hex');  
const keyInfo = EasyCrypto.generateKeyInfo(EasyCrypto.default_ha, keyBytes2);
const ci2 = EasyCrypto.generateAESCipherInfo(EasyCrypto.default_ea, keyInfo);
const shared1 = EasyCrypto.decryptWith.aes256gcm(ci2, encrypted).toString();

(Comments and outputs)

import { EasyCrypto } from "EasyCrypto";

// Provide some data to be encrypted via a Buffer. User manages any string
// encoding options outside of EasyCrypto (which uses crypto defaults).
const msg = Buffer.from('A test string for gcm encryption.');

// You can generate a CipherInfo object from defaults, an exportable secret 
// key object will be generated from a psuedo-randomized hash.
const ci = EasyCrypto.generateAESCipherInfo();
const encrypted = EasyCrypto.encryptWith.aes256gcm(ci, msg);

// That's it for encrypting, just need to grab a copy of that generated key.
const keyBytes = EasyCrypto.exportKey(ci.keyInfo.key);
const keyString = keyBytes.toString('hex');

// When we're ready to decrypt, we pretty much just run it backwards.
const keyString2 = keyString;
const keyBytes2 = Buffer.from(keyString2, 'hex');  
const keyInfo = EasyCrypto.generateKeyInfo(EasyCrypto.default_ha, keyBytes2);
const ci2 = EasyCrypto.generateAESCipherInfo(EasyCrypto.default_ea, keyInfo);
const shared1 = EasyCrypto.decryptWith.aes256gcm(ci2, encrypted).toString();


console.log(`${ci.algorithm}\n` +
            `${ci.period}\n` +
            `${ci.keyInfo.hashAlgorithm}\n` +
            `${EasyCrypto.exportKey(ci.keyInfo.key).toString('hex')}\n` +
            `${ci.authTag?.toString('hex')}\n` +
            `${ci.iv?.toString('hex')}`);
/* output: 
    aes-256-gcm
    7889443200
    sha256
    2c7ed0f3786b17cd51e2b08235a4d60a702ff8ee55c64d51faddf94927a91ba3
    e399315960282d752b2753c513e2db3f
    34646561a82bc7f830a695d2
*/

console.log(keyString);   
// output: 88cd39e3fc7183b5ecb85799ebfb6cad8070cf1bd56688e40a66c92d3ff0967c

console.log(keyInfo); 
/* output:
    {
      hashAlgorithm: 'sha256',
      key: SecretKeyObject [KeyObject] { [Symbol(kKeyType)]: 'secret' }
    }
*/

console.log(`${ci2.algorithm}\n` +
            `${ci2.period}\n` +
            `${ci2.keyInfo.hashAlgorithm}\n` +
            `${EasyCrypto.exportKey(ci2.keyInfo.key).toString('hex')}\n` +
            `${ci2.authTag?.toString('hex')}\n` +
            `${ci2.iv?.toString('hex')}`);
/* output
    aes-256-gcm
    7889443200
    sha256
    2c7ed0f3786b17cd51e2b08235a4d60a702ff8ee55c64d51faddf94927a91ba3
    e399315960282d752b2753c513e2db3f
    34646561a82bc7f830a695d2
*/

console.log(shared1);
// output: A test string for gcm encryption.

Example 2 - Customized Settings, Supplied Secret

(No comments or outputs)

import { EasyCrypto } from "EasyCrypto";

const eAlg = EasyCrypto.EncryptionAlgorithm.aes_256_gcm;
const hAlg = EasyCrypto.HashAlgorithm.sha256;
const message = Buffer.from('A test string for gcm encryption.');
const secret = 'S0M3-SH@R3D-S3CR3T-K3Y!';
const keyInfo1 = {key: secret, hashAlgorithm: EasyCrypto.HashAlgorithm.sha256};
const ci1 = EasyCrypto.getAESCipherInfo(eAlg, keyInfo1);
const encrypted = EasyCrypto.encryptWith.aes256gcm(ci1, message);


const ci2 = EasyCrypto.getAESCipherInfo(eAlg, keyInfo1);
const shared1 = EasyCrypto.decryptWith.aes256gcm(ci2, encrypted).toString();
const hashOfSecret1 = EasyCrypto.exportKey(ci1.keyInfo.key).toString('hex');
const hashedKey = Buffer.from(hashOfSecret1, 'hex');
const keyInfo3 = {key: hashedKey, hashAlgorithm: EasyCrypto.HashAlgorithm.sha256};
const ci3 = EasyCrypto.getAESCipherInfo(eAlg, keyInfo3);
const shared2 = EasyCrypto.decryptWith.aes256gcm(ci3, encrypted).toString();

(Comments and outputs)

import { EasyCrypto } from "EasyCrypto";

const eAlg = EasyCrypto.EncryptionAlgorithm.aes_256_gcm;
const hAlg = EasyCrypto.HashAlgorithm.sha256;
const message = Buffer.from('A test string for gcm encryption.');
const secret = 'S0M3-SH@R3D-S3CR3T-K3Y!';
const keyInfo1 = {key: secret, hashAlgorithm: EasyCrypto.HashAlgorithm.sha256};
// Get a new CipherInfo object.
const ci1 = EasyCrypto.getAESCipherInfo(eAlg, keyInfo1);


// It will populate the ci object's iv property.
// Since it's gcm, it will populate ci object's authTag property.
// Returned Buffer will have 12-byte iv and 16-byte authTag
// values appended to the end of the encrypted bytes Buffer.
const encrypted = EasyCrypto.encryptWith.aes256gcm(ci1, message);

// Use new CipherInfo object constructed with same secret to
// emulate running later on some other environment.
const ci2 = EasyCrypto.getAESCipherInfo(eAlg, keyInfo1);
const shared1 = EasyCrypto.decryptWith.aes256gcm(ci2, encrypted).toString();


// Keep a copy of our hashed key to share 
const hashOfSecret1 = EasyCrypto.exportKey(ci1.keyInfo.key).toString('hex');
const hashedKey = Buffer.from(hashOfSecret1, 'hex');
const keyInfo3 = {key: hashedKey, hashAlgorithm: EasyCrypto.HashAlgorithm.sha256};
const ci3 = EasyCrypto.getAESCipherInfo(eAlg, keyInfo3);
const shared2 = EasyCrypto.decryptWith.aes256gcm(ci3, encrypted).toString();


// Try it again, make sure everything is staying reusable.
const hashOfSecret2 = EasyCrypto.exportKey(ci3.keyInfo.key).toString('hex');
const hashedKey2 = Buffer.from(hashOfSecret2, 'hex');
const keyInfo4 = {key: hashedKey2, hashAlgorithm: EasyCrypto.HashAlgorithm.sha256};
const ci4 = EasyCrypto.getAESCipherInfo(eAlg, keyInfo4);
const shared3 = EasyCrypto.decryptWith.aes256gcm(ci4, encrypted).toString();


console.log(encrypted.toString('base64'));
//output <like>: S0m3B4s3643nc0D3DV3rS10N0fTh33NcryPt3Dm3sS4g36i/730s7jc5mfsjRkZWHtHIkcF7LjCw==

console.log((ci2.keyInfo.key as crypto.KeyObject).export().toString('hex'));
//output: 

console.log(shared1);
//output: A test string for gcm encryption.

console.log(EasyCrypto.exportKey(ci3.keyInfo.key).toString('hex'));
//output: 81bda621ea63758f98644aa7ee9550129f1d6933e6f812da856bbedb4da53a1c

console.log(shared2);
//output: A test string for gcm encryption.

console.log(EasyCrypto.exportKey(ci4.keyInfo.key).toString('hex'));
//output: 81bda621ea63758f98644aa7ee9550129f1d6933e6f812da856bbedb4da53a1c

console.log(shared3);
//output: A test string for gcm encryption.