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

sodium-crypter

v1.1.4

Published

A encryption and decryption tool with secret and public key cryptography

Downloads

21

Readme

sodium-crypter is a robust and secure package designed for encryption and decryption of data. It leverages the power of the Sodium cryptographic library to provide high-level encryption standards. This package is ideal for handling sensitive data, ensuring it remains secure during storage and transmission. It offers easy-to-use functions for encrypting and decrypting data, making it a go-to choice for developers needing reliable cryptographic operations in their applications.

Table of Contents

Prerequisites

Before you begin, ensure you have met the following requirements:

  • You have installed the latest version of Node.js and npm.
  • You are familiar with JavaScript and Node.js package management.

Back To The Top

Installation

To install sodium-crypter, follow these steps:

  1. Open your terminal.
  2. Use npm to install the package:
npm install sodium-crypter

Back To The Top

How to Use

Symmetric Encryption and Decryption

Here's a proper example for symmetric encryption and decryption or check ./examples/symmetric.test.js:

const fs = require("fs").promises;
const {
  CHUNK_SIZE,
  crypto_secretstream_xchacha20poly1305_ABYTES,
} = require("sodium-crypter/config/constants.js");
const serviceWorker = require("sodium-crypter/worker/serviceWorker.js");
const generatePassword = require("sodium-crypter/utils/generatePassword.js");
const passwordStrengthCheck = require("sodium-crypter/utils/passwordStrengthCheck.js");
const formatBytes = require("sodium-crypter/helpers/formatBytes.js");
let password, encryptedData, decryptedData;

async function encryption() {
  const filePath = "./path/to/your/data"; // path to file
  const fileContents = await fs.readFile(filePath);
  const fileName = await serviceWorker.assignFileNameEnc({ name: filePath });

  password = await generatePassword(); // Generate password
  if (!password.status) throw new Error(password.message);

  await passwordStrengthCheck({ password: password.data }); // Check password strength

  const fileSize = formatBytes(fileContents.length); // Get file size
  const encKey = await serviceWorker.encKeyGenerator({
    password: password.data,
  }); // Generate encryption key
  if (!encKey.status) throw new Error(encKey.message);

  // Encrypt file in chunks
  for (let index = 0; index < fileContents.length; index += CHUNK_SIZE) {
    const chunk = fileContents.slice(index, index + CHUNK_SIZE);
    const last = index + CHUNK_SIZE >= fileContents.length;

    encryptedData =
      index === 0
        ? await serviceWorker.encryptFirstChunk({ chunk: chunk, last: last })
        : await serviceWorker.encryptRestOfChunks({ chunk: chunk, last: last });
  }

  if (!encryptedData.status) throw new Error(encryptedData.message);
  await fs.writeFile(
    `./path/to/your/file/${fileName.data}`,
    encryptedData.data
  ); // Write encrypted data to file
}

async function decryption() {
  const startIndex = 51;
  const filePath = "./path/to/your/data"; // path to encrypted file
  const fileContents = await fs.readFile(filePath);
  const fileName = await serviceWorker.assignFileNameDec({ name: filePath });
  const fileSize = formatBytes(fileContents.length);

  const chunk = fileContents.slice(0, startIndex);
  const [signature, salt, header] = [
    chunk.slice(0, 11), // signature
    chunk.slice(11, 27), // salt
    chunk.slice(27, 51), // header
  ];

  const encType = await serviceWorker.checkEncryptionType({
    signature: signature,
  });
  if (!encType.status) throw new Error(encType.message);

  const decKeys = await serviceWorker.decKeyGenerator({
    password: password.data,
    signature: signature,
    salt: salt,
    header: header,
  });
  if (!decKeys.status) throw new Error(decKeys.message);

  if (
    startIndex + CHUNK_SIZE + crypto_secretstream_xchacha20poly1305_ABYTES >=
    fileContents.length
  ) {
    const fullChunk = fileContents.slice(
      startIndex,
      startIndex + CHUNK_SIZE + crypto_secretstream_xchacha20poly1305_ABYTES
    );
    const kickOfDecryption = await serviceWorker.testDecryption({
      password: password.data,
      signature: signature,
      salt: salt,
      header: header,
      decFileBuff: fullChunk,
    });
  }

  for (
    let i = startIndex;
    i < fileContents.length;
    i += CHUNK_SIZE + crypto_secretstream_xchacha20poly1305_ABYTES
  ) {
    const chunk = fileContents.slice(
      i,
      i + CHUNK_SIZE + crypto_secretstream_xchacha20poly1305_ABYTES
    );
    const last =
      i + CHUNK_SIZE + crypto_secretstream_xchacha20poly1305_ABYTES >=
      fileContents.length;

    decryptedData = await serviceWorker.decryptChunks({
      chunk: chunk,
      last: last,
    });
  }

  if (!decryptedData.status) throw new Error(decryptedData.message);
  await fs.writeFile(
    `./path/to/your/file/${fileName.data}`,
    decryptedData.data
  );
}

async function wait(seconds) {
  return new Promise((resolve) => setTimeout(resolve, seconds * 1000));
}

(async () => {
  try {
    await encryption();
    await wait(2); // wait for 2 seconds
    await decryption();
  } catch (error) {
    console.error(error);
  }
})();

This example demonstrates symmetric encryption and decryption. The data is first encrypted using the symmetricEncrypt function and then decrypted using the symmetricDecrypt function.

Back To The Top

Asymmetric Encryption and Decryption

Here's a proper example for asymmetric encryption and decryption or check ./examples/symmetric.test.js:

const fs = require("fs").promises;
const formatBytes = require("sodium-crypter/helpers/formatBytes.js");
const serviceWorker = require("sodium-crypter/worker/serviceWorker.js");
const {
  CHUNK_SIZE,
  crypto_secretstream_xchacha20poly1305_ABYTES,
} = require("sodium-crypter/config/constants.js");
const generateAsymmetricKeys = require("sodium-crypter/utils/generateAsymmetricKeys.js");
let senderKeys, receiverKeys;

async function encryption() {
  const filePath = "./path/to/your/data"; // path to file
  const fileContents = await fs.readFile(filePath);
  const fileName = await serviceWorker.assignFileNameEnc({ name: filePath });

  senderKeys = await generateAsymmetricKeys(); // Generate sender keys
  if (!senderKeys.status) throw new Error(senderKeys.message);

  receiverKeys = await generateAsymmetricKeys(); // Generate receiver keys
  if (!receiverKeys.status) throw new Error(receiverKeys.message);

  const fileSize = formatBytes(fileContents.length);
  const encKeyPair = await serviceWorker.encKeyPair({
    ssk: senderKeys.data.privateKey,
    rpk: receiverKeys.data.publicKey,
    mode: "derive",
  });
  if (!encKeyPair.status) throw new Error(encKeyPair.message);

  let encryptedData;
  for (let index = 0; index < fileContents.length; index += CHUNK_SIZE) {
    const chunk = fileContents.slice(index, index + CHUNK_SIZE);
    const last = index + CHUNK_SIZE >= fileContents.length;

    encryptedData =
      index === 0
        ? await serviceWorker.asymmetricEncryptFirstChunk({
            chunk: chunk,
            last: last,
          })
        : await serviceWorker.encryptRestOfChunks({ chunk: chunk, last: last });
  }

  if (!encryptedData.status) throw new Error(encryptedData.message);
  console.log("encrypted data: ", encryptedData.data, "file size: ", fileSize);
  await fs.writeFile(
    `./path/to/your/file/${fileName.data}`,
    encryptedData.data
  );
}

async function decryption() {
  const startIndex = 35;
  const filePath = "/path/to/your/data"; // path to encrypted file
  const fileContents = await fs.readFile(filePath);
  const fileName = await serviceWorker.assignFileNameDec({ name: filePath });
  const fileSize = formatBytes(fileContents.length);

  const chunk = fileContents.slice(0, startIndex);
  const [signature, header] = [
    chunk.slice(0, 11), // signature
    chunk.slice(11, startIndex), // header
  ];

  const encType = await serviceWorker.checkEncryptionType({
    signature: signature,
  });
  if (!encType.status) throw new Error(encType.message);

  let decryptedData;
  for (
    let i = startIndex;
    i < fileContents.length;
    i += CHUNK_SIZE + crypto_secretstream_xchacha20poly1305_ABYTES
  ) {
    const chunk = fileContents.slice(
      i,
      i + CHUNK_SIZE + crypto_secretstream_xchacha20poly1305_ABYTES
    );
    const last =
      i + CHUNK_SIZE + crypto_secretstream_xchacha20poly1305_ABYTES >=
      fileContents.length;

    if (i === startIndex) {
      const decKeyPair = await serviceWorker.requestDecKeyPair({
        rsk: receiverKeys.data.privateKey,
        spk: senderKeys.data.publicKey,
        header: header,
        decFileBuff: chunk,
        mode: "derive",
      });
      if (!decKeyPair.status) throw new Error(decKeyPair.message);
    }

    decryptedData = await serviceWorker.decryptChunks({
      chunk: chunk,
      last: last,
    });
  }

  if (!decryptedData.status) throw new Error(decryptedData.message);
  console.log("file size: ", fileSize);
  await fs.writeFile(`/path/to/your/file/${fileName.data}`, decryptedData.data);
}

async function wait(seconds) {
  return new Promise((resolve) => setTimeout(resolve, seconds * 1000));
}

(async () => {
  try {
    await encryption();
    console.log("Start");
    await wait(2); // wait for 2 seconds
    console.log("End");
    await decryption();
  } catch (error) {
    console.error(error);
  }
})();

This example demonstrates asymmetric encryption and decryption. Key pairs are generated for the sender and receiver. The data is then encrypted using the sender's private key and the receiver's public key, and decrypted using the receiver's private key and the sender's public key.

Back To The Top

Author

This project is created and maintained by XpeedStudio.

Back To The Top

License

Copyright © 2024 XpeedStudio

sodium-crypter is licensed under the GNU General Public License v3.0.

Back To The Top

References

This project makes use of the hat.sh web application for encryption and decryption. You can find the source code for hat.sh on its GitHub repository.

Back To The Top

Contributors

Thanks goes to these wonderful people:

| mdmuhtasimfuadfahim | emranio | mahmudsagar | | :------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------: |

Back To The Top