Skip to content

SSbit01/singlecrypt-text

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

42 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SingleCrypt Text

Warning

This package uses Uint8Array.prototype.toBase64() and Uint8Array.fromBase64(), which, as of November 2025, are only supported by the latest versions of browsers, Bun, Deno 2.5 or later and Node.js 25 or later. See MDN for compatibility.

A simple, secure, and fast symmetric encryption library that makes use of AES-GCM and modern platform features. It leverages the native Web Crypto API, so it works both in browsers (in secure contexts) and JavaScript runtimes.

Why AES-GCM?

AES-GCM is extremely fast on modern CPUs, which have dedicated hardware acceleration (AES-NI), in addition to being highly secure and even quantum-resistant (AES-256-GCM).

Installation

Use your preferred package manager.

# npm
npm i singlecrypt-text

# Yarn
yarn add singlecrypt-text

# pnpm
pnpm add singlecrypt-text

# Bun
bun add singlecrypt-text

Examples

This is a simple demonstration; production uses should utilize key rotation, among many other security measures.

There are two ways to use this library: object-oriented (recommended) or functional-oriented.

Object-oriented

./lib/crypto.js

import SingleCryptText from "singlecrypt-text";
import { getMessageEncryptionKey } from "./lib/key";

export const cryptoMessage = new SingleCryptText(
  await getMessageEncryptionKey()
);

Usage

And now you can easily encrypt and decrypt messages:

// ...
import { cryptoMessage } from "./lib/crypto.js";
// ...

const message = await getMessage();

const encryptedMessage = await cryptoMessage.encrypt(message);
// ...
const decryptedMessage = await cryptoMessage.decrypt(encryptedMessage);
// ...
console.log(message === decryptedMessage);  // True
// ...

Functional-oriented

./lib/crypto/message.ts

import {
  createSymmetricKeyFromText,
  encryptTextSymmetrically,
  decryptTextSymmetrically
} from "singlecrypt-text";

import { getMessageEncryptionKey } from "./lib/crypto/key";


const messageCryptoKey = await createSymmetricKeyFromText(
  await getMessageEncryptionKey()
);


export async function encryptMessage(text: string) {
  return await encryptTextSymmetrically(
    text,
    messageCryptoKey
  );
}

export async function decryptMessage(ciphertext: string) {
  return await decryptTextSymmetrically(
    ciphertext,
    messageCryptoKey
  );
}

Or you can reuse TextEncoder and TextDecoder instances for slightly better performance:

import {
  createSymmetricKeyFromText,
  encryptTextSymmetrically,
  decryptTextSymmetrically
} from "singlecrypt-text";

import { getMessageEncryptionKey } from "./lib/crypto/key";


const textEncoder = new TextEncoder();
const textDecoder = new TextDecoder();

const messageCryptoKey = await createSymmetricKeyFromText(
  await getMessageEncryptionKey()
);


export async function encryptMessage(text: string) {
  return await encryptTextSymmetrically(
    text,
    messageCryptoKey,
    true,
    textEncoder
  );
}

export async function decryptMessage(ciphertext: string) {
  return await decryptTextSymmetrically(
    ciphertext,
    messageCryptoKey,
    textDecoder
  );
}

Usage

And now you can easily encrypt and decrypt messages:

// ...
import { encryptMessage, decryptMessage } from "./lib/crypto/message.ts";
// ...

const message = await getMessage();

const encryptedMessage = await encryptMessage(message);
// ...
const decryptedMessage = await decryptMessage(encryptedMessage);
// ...
console.log(message === decryptedMessage);  // True
// ...

Reference

Object-oriented API: SingleCryptText

A class that simplifies symmetric encryption and decryption using a shared key derived from a text string.

It is also the default export.

new SingleCryptText(
  key: string,
  extractable: boolean = false,
  textEncoder?: TextEncoder,
  textDecoder?: TextDecoder
)
  • key: The secret string to use as a key (should be high-entropy, such as a 32-byte random string).
  • extractable (optional): Whether the generated cryptographic key is extractable. Defaults to false.
  • textEncoder/textDecoder (optional): Optionally reuse your own encoder/decoder instances.

Instance methods

  • async encrypt(text: string, urlSafe?: boolean): Promise<string>

    Encrypt a string using the instance's key. Optionally specify urlSafe (true by default) to use base64url encoding.

  • async decrypt(ciphertext: string): Promise<string>

    Decrypt a string previously encrypted by this or any compatible instance.

  • async getKey(): Promise<CryptoKey>

    Returns the underlying CryptoKey instance.

Example

import SingleCryptText from "singlecrypt-text";

const crypt = new SingleCryptText("my secret passphrase");

const encrypted = await crypt.encrypt("Sensitive message!");
const decrypted = await crypt.decrypt(encrypted);

console.log(decrypted); // "Sensitive message!"

Functional-oriented API

Functional exports for direct cryptographic operations.

createSymmetricKeyFromText(
  key: string,
  extractable?: boolean,
  textEncoder?: TextEncoder
): Promise<CryptoKey>
  • key: The secret string to use as a key (should be high-entropy, such as a 32-byte random string).
  • extractable (optional): Whether the generated key is extractable. Defaults to false.
  • textEncoder (optional): Optionally reuse your own TextEncoder instance.

Returns a Promise<CryptoKey> containing the derived symmetric key (SHA-256 hash).

Throws:

  • TypeError if there are problems with the text key.

encryptTextSymmetrically(
  key: CryptoKey,
  text: string,
  urlSafe?: boolean,
  textEncoder?: TextEncoder
): Promise<string>
  • key: A symmetric key previously generated with createSymmetricKeyFromText.
  • text: String value to encrypt.
  • urlSafe (optional): Use base64url encoding if true (default: true). If false, uses regular base64.
  • textEncoder (optional): Optionally reuse your own TextEncoder instance.

Returns a Promise<string> containing the encrypted value as a Base64 string.

Throws:

  • DOMException if the key is invalid or if the operation failed (e.g., large payload).

decryptTextSymmetrically(
  key: CryptoKey,
  ciphertext: string,
  textDecoder?: TextDecoder
): Promise<string>
  • key: A symmetric key previously generated with createSymmetricKeyFromText.
  • ciphertext: The string value to decrypt (encrypted with compatible methods/settings).
  • textDecoder (optional): Optionally reuse your own TextDecoder instance.

Returns a Promise<string> containing the decrypted value.

Throws:

  • TypeError: if the second parameter is not a string.
  • SyntaxError: if the input contains characters outside the Base64 alphabet.
  • DOMException: if the key is invalid or if the operation failed.

Created by SSbit01.