Skip to content

k18k/node-rpgp

Repository files navigation

node-rpgp

Synchronous Node.js PGP API backed by Rust rPGP.

Install

npm install node-rpgp

Stability

node-rpgp is stable for the documented synchronous RSA and ECC PGP subset.

Unsupported PGP features fail with stable UNSUPPORTED_FEATURE errors instead of being silently accepted.

Supported v1 Subset

Feature Status
RSA key generation Supported for 2048, 3072, and 4096-bit keys
ECC default profile Supported: Ed25519 primary key plus X25519 encryption subkey
curve: "curve25519" Supported as the Ed25519/X25519 encryption-capable profile
curve: "ed25519" Supported as the Ed25519/X25519 encryption-capable profile
NIST ECC curves Unsupported, throws UNSUPPORTED_FEATURE
Passphrase-protected private key generation Supported for RSA and ECC
Armored public key parsing Supported through rPGP
Armored private key parsing Supported through rPGP
Multiple armored private key parsing Supported by parsing each complete armor block through rPGP
Armored message parsing Supported through rPGP
Public-key encryption Supported for one RSA or ECC recipient
Private-key decryption Supported for one RSA or ECC private key
Text roundtrip Supported
Binary plaintext roundtrip Supported through armored encrypted messages
Binary encrypted output Unsupported, throws UNSUPPORTED_FEATURE

Unsupported Features

These features currently throw UNSUPPORTED_FEATURE:

  • NIST ECC curves: nistP256, nistP384, nistP521
  • signing
  • signature verification
  • password-only message encryption/decryption
  • multiple encryption recipients
  • multiple decryption keys
  • binary encrypted output
  • binary message parsing with readMessage({ binaryMessage })

API Overview

const {
  createMessage,
  readMessage,
  readKey,
  readPrivateKey,
  readPrivateKeys,
  decryptKey,
  encrypt,
  decrypt,
  generateKey,
} = require("node-rpgp");

The public API is synchronous and does not expose Sync-suffixed function names.

Generate Keys

const { generateKey, readKey, readPrivateKey } = require("node-rpgp");

const generated = generateKey({
  type: "rsa",
  rsaBits: 2048,
  userIDs: [{ name: "Example User", email: "user@example.com" }],
});

const publicKey = readKey({ armoredKey: generated.publicKey });
const privateKey = readPrivateKey({ armoredKey: generated.privateKey });

Generate the default ECC profile:

const generated = generateKey({
  type: "ecc",
  curve: "curve25519",
  userIDs: [{ name: "Example User", email: "user@example.com" }],
});

curve: "ed25519" currently selects the same Ed25519/X25519 profile. Ed25519 is used for the primary signing/certification key; X25519 is used for the encryption subkey.

Passphrase-Protected Keys

const { generateKey, readPrivateKey, decryptKey } = require("node-rpgp");

const generated = generateKey({ type: "ecc", passphrase: "change me" });
const locked = readPrivateKey({ armoredKey: generated.privateKey });
const unlocked = decryptKey({ privateKey: locked, passphrase: "change me" });

unlocked.decrypted is true.

Passphrase-protected private keys must be unlocked with decryptKey() before decrypt().

Encrypt and Decrypt Text

const { createMessage, decrypt, encrypt, generateKey, readKey, readMessage, readPrivateKey } = require("node-rpgp");

const generated = generateKey();
const publicKey = readKey({ armoredKey: generated.publicKey });
const privateKey = readPrivateKey({ armoredKey: generated.privateKey });

const encrypted = encrypt({
  message: createMessage({ text: "Zażółć gęślą jaźń" }),
  encryptionKeys: publicKey,
});

const decrypted = decrypt({
  message: readMessage({ armoredMessage: encrypted }),
  decryptionKeys: privateKey,
});

console.log(decrypted.data);

Binary Plaintext

const encrypted = encrypt({
  message: createMessage({ binary: new Uint8Array([0, 1, 2, 127, 128, 255]) }),
  encryptionKeys: publicKey,
});

const decrypted = decrypt({
  message: readMessage({ armoredMessage: encrypted }),
  decryptionKeys: privateKey,
  format: "binary",
});

decrypted.data is a Uint8Array.

Errors

Thrown errors use stable code strings where possible:

type NodeRpgpErrorCode =
  | "INVALID_INPUT"
  | "INVALID_PUBLIC_KEY"
  | "INVALID_PRIVATE_KEY"
  | "INVALID_MESSAGE"
  | "INVALID_PASSPHRASE"
  | "DECRYPTION_FAILED"
  | "ENCRYPTION_FAILED"
  | "KEY_GENERATION_FAILED"
  | "UNSUPPORTED_FEATURE";

Security Notes

This package delegates implemented PGP operations to rPGP. It does not implement cryptographic primitives in JavaScript.

The API is synchronous and blocks the event loop. Do not use it with untrusted huge inputs on latency-sensitive request paths without input limits.

No security audit is claimed.

Native Platform Notes

This is a native Node.js package. The release workflow targets Linux x64 glibc and Linux x64 musl artifacts.

License

MIT

About

Synchronous Node.js PGP API backed by Rust rPGP

Resources

License

Stars

Watchers

Forks

Contributors