@glorhythm/crypt
v1.0.0-beta
Published
Glorhythm library for encryption and decryption
Downloads
7
Maintainers
Readme
@glorhythm/crypt
A small, opinionated encryption/decryption helper for Node.js using AES-256-GCM.
It derives a 256-bit key from your application secret via @glorhythm/config-loader and exposes a simple static API.
Installation
npm install @glorhythm/crypt @glorhythm/config-loaderor with yarn:
yarn add @glorhythm/crypt @glorhythm/config-loaderNote:
@glorhythm/config-loadermust be configured so thatConfig("app.key")returns a strong secret string.
🧱 Folder Structure
Expected project layout:
<project>/
│── src/
| ├── configs/
| │ └── app.ts
| └── index.ts
├── .env
├── package.jsonHow it works
- Uses the Node.js
cryptomodule with:- Algorithm:
aes-256-gcm - IV: 12 random bytes per encryption
- Auth tag: GCM authentication tag for integrity
- Algorithm:
- Key derivation:
key = sha256(Config("app.key"))- Result is a 32-byte buffer used directly as the AES key
- Output format:
ivHex:encryptedHex:authTagHex(all hex-encoded, colon-separated)
This makes it easy to store encrypted values in a single string (DB column, config value, etc.).
Basic Usage
import Crypt from "@glorhythm/crypt";
// Encrypt a string
const plainText = "my-secret-value";
const encrypted = Crypt.encrypt(plainText);
console.log("Encrypted:", encrypted);
// Example: 9a3f...:d823...:a1b2...
// Decrypt back
const decrypted = Crypt.decrypt(encrypted);
console.log("Decrypted:", decrypted); // "my-secret-value"API
Crypt.encrypt(data: string): string
Encrypts a UTF-8 string and returns a single colon-separated string containing:
<ivHex>:<cipherTextHex>:<authTagHex>Parameters:
data– Plain text string to encrypt.
Returns:
- A string that contains the IV, encrypted data, and auth tag, all hex-encoded, separated by
:.
Behavior:
- Get key via
Config("app.key"), hashed with SHA-256. - Generate a random 12-byte IV with
randomBytes(12). - Create an AES-256-GCM cipher with
createCipheriv. - Encrypt the data and retrieve the auth tag via
cipher.getAuthTag(). - Serialize as
iv:encrypted:authTag(hex).
Crypt.decrypt(data: string): string
Decrypts a string produced by Crypt.encrypt and returns the original UTF-8 string.
Parameters:
data– Encrypted string in the formativHex:encryptedHex:authTagHex.
Returns:
- The decrypted UTF-8 string.
Behavior:
- Split the input by
:. - Decode
ivHex,encryptedHex, andauthTagHexfrom hex into buffers. - Create an AES-256-GCM decipher with the same derived key and IV.
- Set the auth tag via
decipher.setAuthTag. - Decrypt and return the plain text string.
If the ciphertext is tampered with or the key/IV/auth tag does not match, decipher.final() will throw.
Configuration & Key Management
This library expects @glorhythm/config-loader to provide the encryption key:
import Config from "@glorhythm/config-loader";
const secret = Config("app.key");Recommendations:
- Use a long, random string (at least 32+ characters) for
app.key. - Store it in a secure location:
- Environment variable (
APP_KEY) - Secrets manager (AWS Secrets Manager, GCP Secret Manager, HashiCorp Vault, etc.)
- Environment variable (
- Do not commit the key to version control.
- Changing
app.keywill make previously encrypted data undecryptable.
Example: Encrypting Data Before Saving to DB
import Crypt from "@glorhythm/crypt";
import db from "./db"; // your DB client
interface User {
id: number;
email: string;
secretTokenEncrypted: string;
}
async function saveToken(userId: number, token: string) {
const encrypted = Crypt.encrypt(token);
await db.user.update({
where: { id: userId },
data: { secretTokenEncrypted: encrypted },
});
}
async function loadToken(userId: number): Promise<string | null> {
const user: User | null = await db.user.findUnique({ where: { id: userId } });
if (!user?.secretTokenEncrypted) return null;
return Crypt.decrypt(user.secretTokenEncrypted);
}Error Handling
Decryption can throw if:
- The input is not in the correct
iv:cipher:tagformat. - The hex strings are invalid.
- The key differs from the one used in encryption.
- The ciphertext or auth tag has been modified.
Wrap decryption in try/catch if you expect potentially invalid or untrusted input:
try {
const decrypted = Crypt.decrypt(encryptedStringFromClient);
// use decrypted value
} catch (err) {
console.error("Failed to decrypt:", err);
// handle error (e.g., reject request, mark data as invalid)
}TypeScript
The package ships with type declarations:
main:dist/index.jstypes:dist/index.d.tsexportsconfigured for both CJS and ESM.
Example TS usage:
import Crypt from "@glorhythm/crypt";
const encrypted = Crypt.encrypt("hello");
const decrypted = Crypt.decrypt(encrypted);Security Notes
- AES-256-GCM provides both confidentiality and integrity (via auth tag).
- The strength of your encryption depends heavily on the secrecy and randomness of
app.key. - Do not reuse or log the encryption key or decrypted sensitive data.
- For very high-security use cases, consider:
- Rotating keys and storing key metadata.
- Using a dedicated KMS (Key Management Service).
- Adding versioning to your encrypted payloads.
License
MIT © Glorhythm
