šŸš€ Big News:Socket Has Acquired Secure Annex.Learn More →
Socket
Book a DemoSign in
Socket

@alessiofrittoli/crypto-cipher

Package Overview
Dependencies
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@alessiofrittoli/crypto-cipher

Node.js Cipher cryptograph utility library

latest
Source
npmnpm
Version
3.1.0
Version published
Weekly downloads
16
-69.23%
Maintainers
1
Weekly downloads
Ā 
Created
Source

Crypto Cipher šŸ”

NPM Latest Version Coverage Status Socket Status NPM Monthly Downloads Dependencies

GitHub Sponsor

Node.js Cipher cryptograph utility library

Table of Contents

Getting started

The crypto-cipher library provides AES encryption and decryption functionality, supporting both in-memory buffers and streams. It adheres to the NIST SP 800-38D standard recommendations.

āš ļø Note that every performed operation cannot be accomplished client-side and must be executed on a back-end server.

It is part of the crypto utility libraries and can be installed by running the following command:

npm i @alessiofrittoli/crypto-cipher

or using pnpm

pnpm i @alessiofrittoli/crypto-cipher

Key features

  • Supports multiple AES algorithms (CCM, GCM, OCB, CBC) and even chacha20-poly1305.
  • In-memory buffer encryption and decrpytion.
  • Robust support for encrypting and decrypting streams (in-memory and file based).
  • Hybrid encryption methods for combining symmetric and asymmetric cryptography.

Security Considerations

  • Random salt and IV generation.
  • AEAD - Authenticated encryption modes with proper authTag and Additional Authenticated Data handling.

Readable and Modular

  • Separation of concerns with clear method responsibilities.
  • Comprehensive JSDoc comments enhance maintainability and readability.

What's Changed

šŸŽ‰ Core updates in the latest release:

  • Cipher methods have been refactored to provide a solid and easy usage
  • Cipher.HybridEncrypt() and Cipher.HybridDecrypt() have been added. These methods will allow you to encrypt/decrypt in-memory buffer data using hybrid encryption algorithms.
  • Cipher.stream subgroup has been added to keep method names consistent across the library.
  • hybrid encryption doesn't require a password anymore which was redundant. an RSA key pair is all what you need.
  • providing RSA key length during hybrid decryption is no longer needed.

Migration guide

Migrating from v2.x.x to v3.0.0

Cipher.encrypt()

Is now renamed to Cipher.Encrypt(). It's API implementation remain the same.

Cipher.decrypt()

Is now renamed to Cipher.Decrypt(). It's API implementation remain the same.

Cipher.streamEncrypt()

Before

await Cipher.streamEncrypt(password, { input, output }).encrypt();

Now

await Cipher.stream.Encrypt(password, { input, output });

Cipher.streamDecrypt()

Before

const { decrypt } = await Cipher.streamDecrypt(password, { input, output });

await decrypt();

Now

await Cipher.stream.Decrypt(password, { input, output });

Cipher.hybridEncrypt()

Before

const { encrypt } = Cipher.hybridEncrypt(
  password,
  {
    key: keyPair.publicKey,
    padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
    oaepHash: "SHA-256",
  },
  { input, output }
);
await encrypt();

Now

await Cipher.stream.HybridEncrypt(keyPair.publicKey, { input, output });

Cipher.hybridDecrypt()

Before

const { decrypt } = await Cipher.hybridDecrypt(
  {
    key: keyPair.privateKey,
    passphrase: passphrase,
    padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
    oaepHash: "SHA-256",
  },
  { input, output, rsaKeyLength }
);

await decrypt();

Now

await Cipher.stream.HybridDecrypt(
  { key: keyPair.privateKey, passphrase },
  { input, output }
);

Or even

await Cipher.stream.HybridDecrypt(keyPair.privateKey, { input, output });

API Reference

Constants

Cipher.SALT_LENGTH

Defines the minimum, maximum, and default lengths for salt.

Properties
PropertyValue
min16
max64
default32
Cipher.IV_LENGTH

Defines the minimum, maximum, and default lengths for initialization vectors (IV).

Properties
PropertyValue
min8
max32
default16
Cipher.AUTH_TAG_LENGTH

Defines the minimum, maximum, and default lengths for authentication tags.

Properties
PropertyValue
min4
max16
default16
Cipher.AAD_LENGTH

Defines the minimum, maximum, and default lengths for additional authenticated data (AAD).

Properties
PropertyValue
min16
max4096
default32
Cipher.DEFAULT_ALGORITHM

Specifies default AES algorithms for buffer and stream operations.

Properties
OperationAlgorithmDescription
bufferaes-256-gcmDefault algorithm used for buffer data encryption/decryption
streamaes-256-cbcDefault algorithm used for stream encryption/decryption (Cipher Block Chaining mode).
Cipher.ALGORITHM

An object defining algorithm names.

Properties
PropertyValue
AES_128_CBC'aes-128-cbc'
AES_192_CBC'aes-192-cbc'
AES_256_CBC'aes-256-cbc'
AES_128_CCM'aes-128-ccm'
AES_192_CCM'aes-192-ccm'
AES_256_CCM'aes-256-ccm'
AES_128_GCM'aes-128-gcm'
AES_192_GCM'aes-192-gcm'
AES_256_GCM'aes-256-gcm'
AES_128_OCB'aes-128-ocb'
AES_192_OCB'aes-192-ocb'
AES_256_OCB'aes-256-ocb'
CHACHA_20_POLY'chacha20-poly1305'
Cipher.ALGORITHMS

An array of supported AES algorithms. This array includes all values in Cipher.ALGORITHM constant.

Methods

Cipher.Encrypt()

Encrypts an in-memory data buffer.

[!WARNING] This is not suitable for large data encryption. Use Cipher.stream.Encrypt() or Cipher.stream.HybridEncrypt() methods for large data encryption.

Parameters
NameTypeDescription
dataCoerceToUint8ArrayInputData to encrypt.
secretCoerceToUint8ArrayInputSecret key for encryption.
optionsCph.Options(Optional) Additional encryption options.
Returns

Type: Buffer

The encrypted result buffer.

Cipher.Decrypt()

Decrypts an in-memory data buffer.

[!WARNING] This is not suitable for large data decryption. Use Cipher.stream.Decrypt() or Cipher.stream.HybridDecrypt() methods for large data decryption.

Parameters
NameTypeDescription
dataCoerceToUint8ArrayInputData to decrypt.
secretCoerceToUint8ArrayInputSecret key for decryption.
optionsCph.Options(Optional) Decryption options (must match encryption).
Returns

Type: Buffer

The decrypted result buffer.

Cipher.HybridEncrypt()

Encrypts in-memory data using hybrid encryption.

[!WARNING] This is not suitable for large data encryption. Use Cipher.stream.HybridEncrypt() method for large data encryption.

[!WARNING] Please, note that when using hybrid encryption/decryption algorithms:

  • an RSA keypair is required.
  • if a passphrase is set for the Private Key, please make sure to use one of the Cipher Block Chaining algorithm or chacha20-poly1305 algorithm:
    • aes-128-cbc (type can be pkcs1 or pkcs8)
    • aes-192-cbc (type can be pkcs1 or pkcs8)
    • aes-256-cbc (type can be pkcs1 or pkcs8)
    • chacha20-poly1305 (type can only be pkcs1)
Parameters
ParameterTypeDefaultDescription
dataCoerceToUint8ArrayInput-The data to encrypt.
keycrypto.KeyLike-The RSA Public Key.
optionsCph.Options-(Optional) Additional options.
Returns

Type: Buffer

The encrypted result buffer.

Cipher.HybridDecrypt()

Decrypts in-memory data using hybrid encryption.

[!WARNING] This is not suitable for large data decryption. Use Cipher.stream.HybridDecrypt() method for large data decryption.

[!WARNING] Please, note that when using hybrid encryption/decryption algorithms:

  • an RSA keypair is required.
  • if a passphrase is set for the Private Key, please make sure to use one of the Cipher Block Chaining algorithm or chacha20-poly1305 algorithm:
    • aes-128-cbc (type can be pkcs1 or pkcs8)
    • aes-192-cbc (type can be pkcs1 or pkcs8)
    • aes-256-cbc (type can be pkcs1 or pkcs8)
    • chacha20-poly1305 (type can only be pkcs1)
Parameters
ParameterTypeDefaultDescription
dataCoerceToUint8ArrayInput-The data to encrypt.
keyCph.PrivateKey-The RSA Private Key.
optionsCph.Options-(Optional) Additional options.
Returns

Type: Buffer.

The encrypted result Buffer.

Cipher.stream.Encrypt()

Encrypt stream data.

Parameters
NameTypeDefaultDescription
secretCoerceToUint8ArrayInput-The secret key used to encrypt the data.
optionsCph.Stream.EncryptOptions-An object defining required options.
options.inputReadable-The Readable Stream where raw data to encrypt is read.
options.outputWritable-The Writable Stream where encrypted data is written.
options.algorithmCph.CBCTypesaes-256-cbcOne of the Cipher Block Chaining algorithm.
Returns

Type: Promise<void>

A new Promise that resolves void once stream encryption is completed.

Cipher.stream.Decrypt()

Decrypt stream data.

Parameters
NameTypeDefaultDescription
secretCoerceToUint8ArrayInput-The secret key used to decrypt the data.
optionsCph.Stream.DecryptOptions-An object defining required options.
options.inputReadable-The Readable Stream where encrypted data is read.
options.outputWritable-The Writable Stream where decrypted data is written.
options.algorithmCph.CBCTypesaes-256-cbcOne of the Cipher Block Chaining algorithm.
Returns

Type: Promise<void>

A new Promise that resolves void once stream decryption is completed.

Cipher.stream.HybridEncrypt()

Encrypt stream data using hybrid encryption.

[!WARNING] Please, note that when using hybrid encryption/decryption algorithms:

  • an RSA keypair is required.
  • if a passphrase is set for the Private Key, please make sure to use one of the Cipher Block Chaining algorithm or chacha20-poly1305 algorithm:
    • aes-128-cbc (type can be pkcs1 or pkcs8)
    • aes-192-cbc (type can be pkcs1 or pkcs8)
    • aes-256-cbc (type can be pkcs1 or pkcs8)
    • chacha20-poly1305 (type can only be pkcs1)
Parameters
ParameterTypeDefaultDescription
keycrypto.KeyLike-The RSA Public Key.
optionsCph.Stream.EncryptOptions-An object defining required options.
options.inputReadable-The Readable Stream where raw data to encrypt is read.
options.outputWritable-The Writable Stream where encrypted data is written.
options.algorithmCph.CBCTypesaes-256-cbcOne of the Cipher Block Chaining algorithm.
Returns

Type: Promise<void>

A new Promise that resolves void once stream encryption is completed.

Cipher.stream.HybridDecrypt()

Decrypt stream data using hybrid decryption.

[!WARNING] Please, note that when using hybrid encryption/decryption algorithms:

  • an RSA keypair is required.
  • if a passphrase is set for the Private Key, please make sure to use one of the Cipher Block Chaining algorithm or chacha20-poly1305 algorithm:
    • aes-128-cbc (type can be pkcs1 or pkcs8)
    • aes-192-cbc (type can be pkcs1 or pkcs8)
    • aes-256-cbc (type can be pkcs1 or pkcs8)
    • chacha20-poly1305 (type can only be pkcs1)
Parameters
ParameterTypeDefaultDescription
keyCph.PrivateKey-The RSA Private Key.
optionsCph.Stream.DecryptOptions-An object defining required options.
options.inputReadable-The Readable Stream where encrypted data is read.
options.outputWritable-The Writable Stream where decrypted data is written.
options.algorithmCph.CBCTypesaes-256-cbcOne of the Cipher Block Chaining algorithm.
Returns

Type: Promise<void>

A new Promise that resolves void once stream encryption is completed.

Types

CoerceToUint8ArrayInput

This module supports different input data types and it uses the coerceToUint8Array utility function from @alessiofrittoli/crypto-buffer to convert it to a Uint8Array.

Cph.CBCTypes

AES Cipher Block Chaining algorithms.

Cph.AesAlgorithm

All supported AES algorithms.

Cph.Options<T>

Common options in encryption/decryption processes.

Type parameters
ParameterDefaultDescription
TCph.AesAlgorithmAccepted algorithm in Cph.Options. This is usefull to constraint specifc algorithms.
Properties
PropertyTypeDefaultDescription
algorithmTaes-256-gcm | aes-256-cbcAccepted algorithms.
saltnumber32The salt length in bytes. Minimum: 16, Maximum: 64.
ivnumber16The Initialization Vector length in bytes. Minimum: 8, Maximum: 32.
authTagnumber16The authTag length in bytes. Minimum: 4, Maximum: 16.
aadCoerceToUint8ArrayInput-Custom Additional Authenticated Data. aadLength is then automatically resolved. If not provided, a random AAD is generated with a max length of aadLength.
aadLengthnumber32The auto generated AAD length in bytes. Minimum: 16, Maximum: 128.
Cph.Stream.EncryptOptions

Stream symmetric encryption options.

Properties
PropertyTypeDescription
inputReadableThe Readable Stream from where raw data to encrypt is read.
outputWritableThe Writable Stream where encrypted data is written.
algorithmCph.CBCTypesOne of the Cipher Block Chaining algorithm.
Cph.Stream.DecryptOptions

Stream symmetric decryption options.

Properties
PropertyTypeDescription
inputReadableThe Readable Stream from where encrypted data is read.
outputWritableThe Writable Stream where decrypted data is written.
algorithmCph.CBCTypesOne of the Cipher Block Chaining algorithm.
Cph.PrivateKey

The RSA Private Key.

It could be:

  • a crypto.KeyLike
  • an object defining key and passphrase where key is a crypto.KeyLike

Examples

In-memory data buffer encryption/decryption

The simpliest way to encrypt/decrypt in-memory data buffers.

// encrypt
const data = "my top-secret data";
const password = "my-very-strong-password";

const encrypted = Cipher.Encrypt(data, password);

// decrypt
const decrypted = Cipher.Decrypt(encrypted, password);
console.log(decrypted); // Outputs: my top-secret data

In-memory data buffer hybrid encryption/decryption

Hybrid encryption offers an higher level of security since only the RSA Private Key owner will be able to decrypt the data.

[!WARNING] Please, note that when using hybrid encryption/decryption algorithms:

  • an RSA keypair is required.
  • if a passphrase is set for the Private Key, please make sure to use one of the Cipher Block Chaining algorithm or chacha20-poly1305 algorithm:
    • aes-128-cbc (type can be pkcs1 or pkcs8)
    • aes-192-cbc (type can be pkcs1 or pkcs8)
    • aes-256-cbc (type can be pkcs1 or pkcs8)
    • chacha20-poly1305 (type can only be pkcs1)
Keypair
import { Cipher } from "@alessiofrittoli/crypto-cipher";

const keyPair = crypto.generateKeyPairSync("rsa", {
  modulusLength: 512 * 8, // 4096 bits
  publicKeyEncoding: { type: "spki", format: "pem" },
  privateKeyEncoding: { type: "pkcs1", format: "pem" },
});

// or you can optionally set a custom passphrase
const passphrase = "custompassphrase";

const keyPair = crypto.generateKeyPairSync("rsa", {
  modulusLength: 512 * 8, // 4096 bits
  publicKeyEncoding: { type: "spki", format: "pem" },
  privateKeyEncoding: {
    type: "pkcs1",
    format: "pem",
    passphrase,
    cipher: Cipher.ALGORITHM.CHACHA_20_POLY,
  },
});
import { Cipher } from "@alessiofrittoli/crypto-cipher";

// encrypt
const data = "my top-secret data";
const encrypted = Cipher.HybridEncrypt(data, keypair.publicKey);

// decrypt
const decrypted = Cipher.HybridDecrypt(encrypted, {
  key: keypair.privateKey,
  passphrase,
});

In-memory data stream encryption/decryption

The in-memory data stream comes pretty handy when, for example, we need to stream encrypted data within a Server Response or to decrypt stream data from a Server Response.

Streaming
// /api/stream-encrypt

import { Readable, Writable } from "stream";
import { Stream } from "@alessiofrittoli/stream-writer";

const routeHandler = () => {
  const password = "my-very-strong-password";
  const stream = new Stream();
  const headers = new Headers(stream.headers);

  const input = Readable.from([
    Buffer.from("Chunk n.1"),
    Buffer.from("Chunk n.2"),
    Buffer.from("Chunk n.3"),
    Buffer.from("Chunk n.4"),
  ]);

  // `Writable` Stream where encrypted data is written
  const output = new Writable({
    async write(chunk, encoding, callback) {
      await new Promise((resolve) => setTimeout(resolve, 2000));
      await stream.write(chunk);
      callback();
    },
    async final(callback) {
      await stream.close();
      callback();
    },
  });

  Cipher.stream.Encrypt(password, { input, output }).catch(async () => {
    await stream.close();
  });

  return (
    // encrypted stream
    new Response(stream.readable, { headers })
  );
};
Decrypting received stream
// /api/stream-decrypt

import { Transform, Writable } from "stream";
import { Cipher } from "@alessiofrittoli/crypto-cipher";
import { StreamReader } from "@alessiofrittoli/stream-reader";

const password = "my-very-strong-password";

const routeHandler = () =>
  fetch("/api/stream-encrypt").then((response) => {
    if (!response.body) {
      return new Respone(null, { status: 400 });
    }

    // web stream where decrypted data is written
    const stream = new Stream<Buffer, string>({
      transform(chunk, controller) {
        controller.enqueue(chunk.toString());
      },
    });
    const headers = new Headers(stream.headers);

    headers.set("Content-Type", "text/html");

    const reader = new StreamReader<Uint8Array, Buffer, false>(response.body, {
      inMemory: false,
      transform: Buffer.from,
    });

    const input = new Transform();

    reader.on("data", (chunk) => input.push(chunk));
    reader.on("close", () => input.end());

    reader.read();

    // `Writable` Stream where encrypted data is written
    const output = new Writable({
      async write(chunk: Buffer, encoding, callback) {
        await stream.write(chunk);
        callback();
      },
      final(callback) {
        stream.close();
        callback();
      },
    });

    Cipher.stream.Decrypt(password, { input, output }).catch(async (error) => {
      console.error(error);
      await stream.close();
    });

    return new Response(stream.readable, { headers });
  });

In-memory data stream with hybrid encryption/decryption

Hybrid encryption offers an higher level of security since only the RSA Private Key owner will be able to decrypt the data.

[!WARNING] Please, note that when using hybrid encryption/decryption algorithms:

  • an RSA keypair is required.
  • if a passphrase is set for the Private Key, please make sure to use one of the Cipher Block Chaining algorithm or chacha20-poly1305 algorithm:
    • aes-128-cbc (type can be pkcs1 or pkcs8)
    • aes-192-cbc (type can be pkcs1 or pkcs8)
    • aes-256-cbc (type can be pkcs1 or pkcs8)
    • chacha20-poly1305 (type can only be pkcs1)
Keypair
import { Cipher } from "@alessiofrittoli/crypto-cipher";

const keyPair = crypto.generateKeyPairSync("rsa", {
  modulusLength: 512 * 8, // 4096 bits
  publicKeyEncoding: { type: "spki", format: "pem" },
  privateKeyEncoding: { type: "pkcs1", format: "pem" },
});

// or you can optionally set a custom passphrase
const passphrase = "custompassphrase";

const keyPair = crypto.generateKeyPairSync("rsa", {
  modulusLength: 512 * 8, // 4096 bits
  publicKeyEncoding: { type: "spki", format: "pem" },
  privateKeyEncoding: {
    type: "pkcs1",
    format: "pem",
    passphrase,
    cipher: Cipher.ALGORITHM.CHACHA_20_POLY,
  },
});
Encrypt
const data = "my top-secret data";
/** Store encrypted chunks for next example. */
const encryptedChunks: Buffer[] = [];

// Create a `Readable` Stream with raw data.
const input = new Readable({
  read() {
    this.push(data); // Push data to encrypt
    this.push(null); // Signal end of stream
  },
});

// Create a `Writable` Stream where encrypted data is written
const output = new Writable({
  write(chunk, encoding, callback) {
    // push written chunk to `encryptedChunks` for further usage.
    encryptedChunks.push(chunk);
    callback();
  },
});

await Cipher.stream.HybridEncrypt(keyPair.publicKey, { input, output });
Decrypt
/** Store decrypted chunks. */
const chunks: Buffer[] = [];
// Create a `Readable` Stream with encrypted data.
const input = Readable.from(encryptedChunks);

// Create a `Writable` Stream where decrypted data is written
const output = new Writable({
  write(chunk, encoding, callback) {
    chunks.push(chunk);
    callback();
  },
});

await Cipher.stream.HybridDecrypt(
  {
    key: keyPair.privateKey,
    passphrase, // optional passhrase (required if set while generating keypair).
  },
  { input, output }
);

console.log(Buffer.concat(chunks).toString()); // Outputs: 'my top-secret data'

File based data stream encryption/decryption

Nothig differs from the In-memory data stream encryption/decryption example, except for input and output streams which now comes directly from files reading/writing.

Encrypt a file
import fs from "fs";

const password = "my-very-strong-password";

// input where raw data to encrypt is read
const input = fs.createReadStream("my-very-large-top-secret-file.pdf");
// output where encrypted data is written
const output = fs.createWriteStream("my-very-large-top-secret-file.encrypted");
// encrypt
await Cipher.stream.Encrypt(password, { input, output });
Decrypt a file
import fs from "fs";

const password = "my-very-strong-password";

// input where encrypted data is read
const input = fs.createReadStream("my-very-large-top-secret-file.encrypted");
// output where decrypted data is written
const output = fs.createWriteStream(
  "my-very-large-top-secret-file-decrypted.pdf"
);
// decrypt
await Cipher.stream.Decrypt(password, { input, output });

File based data stream with hybrid encryption/decryption

Nothig differs from the In-memory data stream with hybrid encryption/decryption example, except for input and output streams which now comes directly from files reading/writing.

[!WARNING] Please, note that when using hybrid encryption/decryption algorithms:

  • an RSA keypair is required.
  • if a passphrase is set for the Private Key, please make sure to use one of the Cipher Block Chaining algorithm or chacha20-poly1305 algorithm:
    • aes-128-cbc (type can be pkcs1 or pkcs8)
    • aes-192-cbc (type can be pkcs1 or pkcs8)
    • aes-256-cbc (type can be pkcs1 or pkcs8)
    • chacha20-poly1305 (type can only be pkcs1)
Keypair
import { Cipher } from "@alessiofrittoli/crypto-cipher";

const keyPair = crypto.generateKeyPairSync("rsa", {
  modulusLength: 512 * 8, // 4096 bits
  publicKeyEncoding: { type: "spki", format: "pem" },
  privateKeyEncoding: { type: "pkcs1", format: "pem" },
});

// or you can optionally set a custom passphrase
const passphrase = "custompassphrase";

const keyPair = crypto.generateKeyPairSync("rsa", {
  modulusLength: 512 * 8, // 4096 bits
  publicKeyEncoding: { type: "spki", format: "pem" },
  privateKeyEncoding: {
    type: "pkcs1",
    format: "pem",
    passphrase,
    cipher: Cipher.ALGORITHM.CHACHA_20_POLY,
  },
});
Encrypt a file
import fs from "fs";

// input where raw data to encrypt is read
const input = fs.createReadStream("my-very-large-top-secret-file.pdf");
// output where encrypted data is written
const output = fs.createWriteStream("my-very-large-top-secret-file.encrypted");
// encrypt
await Cipher.stream.HybridEncrypt(keyPair.publicKey, { input, output });
Decrypt a file
import fs from "fs";

// input where encrypted data is read
const input = fs.createReadStream("my-very-large-top-secret-file.encrypted");
// output where decrypted data is written
const output = fs.createWriteStream(
  "my-very-large-top-secret-file-decrypted.pdf"
);
// decrypt
const { decrypt } = await Cipher.stream.HybridDecrypt(
  {
    key: keyPair.privateKey,
    passphrase, // optional passhrase (required if set while generating keypair).
  },
  { input, output }
);

Development

Install depenendencies

npm install

or using pnpm

pnpm i

Build the source code

Run the following command to test and build code for distribution.

pnpm build

ESLint

warnings / errors check.

pnpm lint

Jest

Run all the defined test suites by running the following:

# Run tests and watch file changes.
pnpm test:watch

# Run tests in a CI environment.
pnpm test:ci

Run tests with coverage.

An HTTP server is then started to serve coverage files from ./coverage folder.

āš ļø You may see a blank page the first time you run this command. Simply refresh the browser to see the updates.

test:coverage:serve

Contributing

Contributions are truly welcome!

Please refer to the Contributing Doc for more information on how to start contributing to this project.

Help keep this project up to date with GitHub Sponsor.

GitHub Sponsor

Security

If you believe you have found a security vulnerability, we encourage you to responsibly disclose this and NOT open a public issue. We will investigate all legitimate reports. Email security@alessiofrittoli.it to disclose any security vulnerabilities.

Made with ā˜•

avatar
Alessio Frittoli
https://alessiofrittoli.it | info@alessiofrittoli.it

Keywords

nodejs-crypto

FAQs

Package last updated on 14 Mar 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts