jsencrypt vs crypto-js vs node-forge vs openpgp vs tweetnacl
Client-Side Cryptography: Choosing the Right Library for Web Security
jsencryptcrypto-jsnode-forgeopenpgptweetnaclSimilar Packages:

Client-Side Cryptography: Choosing the Right Library for Web Security

These five libraries provide essential cryptographic primitives for JavaScript developers, but they serve vastly different purposes. crypto-js offers a broad collection of classic algorithms like AES and SHA for general hashing and symmetric encryption. jsencrypt is a lightweight wrapper specifically for RSA key generation and simple encrypt/decrypt operations. node-forge is a comprehensive toolkit implementing TLS, PKI, and ASN.1 parsing, often used for certificate handling. openpgp brings the full OpenPGP standard (RFC 4880) to the browser for secure email and file signing. Finally, tweetnacl provides a minimal, high-security set of modern elliptic curve functions focused on simplicity and safety.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
jsencrypt537,5436,805901 kB146a year agoMIT
crypto-js016,408487 kB2793 years agoMIT
node-forge05,3321.65 MB4656 months ago(BSD-3-Clause OR GPL-2.0)
openpgp05,96617.4 MB324 months agoLGPL-3.0+
tweetnacl01,923-77 years agoUnlicense

Client-Side Cryptography: A Deep Dive into JS Libraries

Choosing a cryptography library in JavaScript is not just about picking an algorithm; it is about selecting a security model that fits your architecture. The five libraries discussed hereβ€”crypto-js, jsencrypt, node-forge, openpgp, and tweetnaclβ€”solve different problems. Some are Swiss Army knives for legacy standards, while others are precision instruments for modern elliptic curve cryptography. Let's break down how they handle real-world engineering challenges.

πŸ” Symmetric Encryption: AES and Data Privacy

When you need to encrypt data locally (like saving a user's draft to LocalStorage) or secure a channel with a shared secret, you typically reach for AES. However, the implementation details vary wildly.

crypto-js provides a very approachable API for AES. It supports various modes, but developers often default to CBC without realizing they also need to manage Initialization Vectors (IVs) manually to ensure security.

// crypto-js: AES Encryption
import CryptoJS from 'crypto-js';

const message = "Secret Data";
const key = "MySecretKey12345"; // Must be 16, 24, or 32 chars

// Default is CBC mode. You MUST generate a random IV for production.
const iv = CryptoJS.lib.WordArray.random(128/8);
const encrypted = CryptoJS.AES.encrypt(message, key, { iv: iv });

console.log(encrypted.toString());

node-forge handles AES with a more verbose, low-level API that gives you explicit control over every byte. It is excellent when you need to match a specific legacy system's exact padding or mode requirements.

// node-forge: AES Encryption
import forge from 'node-forge';

const message = "Secret Data";
const key = forge.random.getBytesSync(16); // 128-bit key
const iv = forge.random.getBytesSync(16);

const cipher = forge.cipher.createCipher('AES-CBC', key);
cipher.start({ iv: iv });
cipher.update(forge.util.createBuffer(message, 'utf8'));
cipher.finish();

const encrypted = cipher.output.getBytes();

tweetnacl does not support raw AES. Instead, it forces you to use crypto_secretbox, which combines XSalsa20 encryption and Poly1305 authentication. This prevents common mistakes like using AES without integrity checks, which can lead to padding oracle attacks.

// tweetnacl: Authenticated Encryption
import nacl from 'tweetnacl';

const message = nacl.util.decodeUTF8("Secret Data");
const nonce = nacl.randomBytes(nacl.secretbox.nonceLength);
const key = nacl.randomBytes(nacl.secretbox.keyLength);

const encryptedBox = nacl.secretbox(message, nonce, key);
// The result includes the authentication tag automatically

openpgp handles symmetric encryption differently. It is designed to encrypt sessions or files using a passphrase, automatically handling the complex packet structure of the OpenPGP standard.

// openpgp: Symmetric Encryption
import * as openpgp from 'openpgp';

const message = await openpgp.createMessage({ text: "Secret Data" });
const encrypted = await openpgp.encrypt({
  message,
  passwords: ['my-secret-passphrase'] // Uses SKESK (Symmetric Key Encrypted Session Key)
});

console.log(encrypted); // Returns armored PGP string

jsencrypt does not support symmetric encryption directly. It is strictly for RSA. To encrypt large data, you would typically generate a random AES key, encrypt the data with crypto-js, and then encrypt the AES key with jsencrypt.

πŸ”‘ Asymmetric Keys: RSA vs. Elliptic Curves

Public-key cryptography is essential for key exchange and digital signatures. The choice here defines your security posture and compatibility.

jsencrypt is the simplest way to get RSA working in the browser. It generates keys and encrypts small strings instantly. It is perfect for sending a login password or a session key to a server that holds the private RSA key.

// jsencrypt: RSA Key Generation & Encryption
import { JSEncrypt } from 'jsencrypt';

const encryptor = new JSEncrypt();
const keys = encryptor.generateKey(1024); // Generates 1024-bit pair

encryptor.setPublicKey(keys.publicKey);
const encrypted = encryptor.encrypt("Sensitive Token");

// Note: RSA can only encrypt data smaller than the key size.

node-forge offers a full RSA implementation including key generation, encryption, and signing. It allows you to manipulate the raw components (modulus, exponents) if you need to interoperate with Java or .NET systems that export keys in specific formats.

// node-forge: RSA Encryption
import forge from 'node-forge';

const pair = forge.pki.rsa.generateKeyPair(2048);
const publicKeyPem = forge.pki.publicKeyToPem(pair.publicKey);

const publicKey = forge.pki.publicKeyFromPem(publicKeyPem);
const encrypted = publicKey.encrypt("Sensitive Token", 'RSA-OAEP');

tweetnacl rejects RSA entirely in favor of Curve25519 (for encryption) and Ed25519 (for signatures). These curves are faster and safer against side-channel attacks. The API uses "boxes" where you combine your private key with the recipient's public key.

// tweetnacl: Elliptic Curve Encryption
import nacl from 'tweetnacl';

const recipientKeyPair = nacl.box.keyPair();
const myKeyPair = nacl.box.keyPair();

const message = nacl.util.decodeUTF8("Secure Message");
const nonce = nacl.randomBytes(nacl.box.nonceLength);

// Encrypts using recipient's public key and our private key
const encrypted = nacl.box(message, nonce, recipientKeyPair.publicKey, myKeyPair.secretKey);

openpgp manages complex key rings. It doesn't just encrypt; it binds identities to keys. You can encrypt a message to multiple recipients, and the library handles the session key encryption for each person automatically.

// openpgp: Multi-recipient Encryption
import * as openpgp from 'openpgp';

const recipientKeys = await openpgp.readKey({ armoredKey: publicKeyArmored });
const message = await openpgp.createMessage({ text: "Hello Alice and Bob" });

const encrypted = await openpgp.encrypt({
  message,
  encryptionKeys: [recipientKeys] // Can pass an array of keys
});

crypto-js does not support asymmetric cryptography. It is strictly for symmetric algorithms and hashing. Trying to implement RSA with crypto-js would require importing additional, non-standard plugins that are often unmaintained.

✍️ Digital Signatures and Integrity

Verifying that data hasn't been tampered with is critical for software updates, financial transactions, and API requests.

tweetnacl makes signing incredibly simple with crypto_sign. It produces a signature that is attached to the message, ensuring both integrity and authenticity using Ed25519.

// tweetnacl: Signing
import nacl from 'tweetnacl';

const keyPair = nacl.sign.keyPair();
const message = nacl.util.decodeUTF8("Do not transfer funds");

const signedMessage = nacl.sign(message, keyPair.secretKey);
// signedMessage contains both the original message and the signature

const isValid = nacl.sign.open(signedMessage, keyPair.publicKey) !== null;

node-forge provides detailed control over signing, allowing you to choose hash algorithms (SHA-256, SHA-1) and padding schemes explicitly. This is necessary when verifying signatures from legacy Certificate Authorities.

// node-forge: Signing
import forge from 'node-forge';

const md = forge.md.sha256.create();
md.update("Data to sign", 'utf8');

const privateKey = forge.pki.privateKeyFromPem(pemString);
const signature = privateKey.sign(md);

// Verification requires re-hashing and comparing

openpgp creates detached signatures or cleartext signed messages that are compatible with GPG command-line tools. This is the standard for verifying software releases (e.g., verifying a Linux distro ISO).

// openpgp: Detached Signature
import * as openpgp from 'openpgp';

const signingKey = await openpgp.readPrivateKey({ armoredKey: privateKeyArmored });
const message = await openpgp.createMessage({ text: "Release v1.0" });

const signature = await openpgp.sign({
  message,
  signingKeys: signingKey,
  detached: true // Returns only the signature packet
});

crypto-js handles hashing (SHA-256, HMAC) but does not create public/private key signatures. You can create an HMAC if both parties share a secret, but you cannot prove identity to a third party without a private key.

// crypto-js: HMAC (Shared Secret Integrity)
import CryptoJS from 'crypto-js';

const hash = CryptoJS.HmacSHA256("Message", "SharedSecret");
// This proves integrity but not identity to outsiders

jsencrypt supports RSA signing, but it is basic. It is useful if you need to sign a challenge-response authentication token using an RSA key pair generated in the browser.

// jsencrypt: RSA Signing
import { JSEncrypt } from 'jsencrypt';

const encryptor = new JSEncrypt();
encryptor.setPrivateKey(privateKeyPem);

const signature = encryptor.sign("Data to sign", "SHA256", "PKCS1v1.5");

πŸ› οΈ PKI and Certificate Handling

This is where the libraries diverge most sharply. Most web developers never touch X.509 certificates in the browser, but when you do, there is really only one choice.

node-forge is the undisputed leader here. It can parse PEM files, read Certificate Revocation Lists (CRLs), and even act as a Certificate Authority (CA) to issue new certificates entirely in client-side code. No other library on this list comes close to this capability.

// node-forge: Parsing a Certificate
import forge from 'node-forge';

const certPem = "-----BEGIN CERTIFICATE-----...";
const cert = forge.pki.certificateFromPem(certPem);

console.log(cert.subject.getField('CN').value); // Extract Common Name
console.log(cert.validity.notAfter); // Check expiration

openpgp manages its own form of PKI via the "Web of Trust," which is different from the X.509 hierarchy used by TLS. It handles key revocation certificates and user IDs within the PGP standard.

// openpgp: Revocation
import * as openpgp from 'openpgp';

const privateKey = await openpgp.readPrivateKey({ armoredKey: keyArmored });
const revocationCert = await privateKey.getRevocationCertificate();
// This certificate can be published to prove the key is no longer valid

crypto-js, jsencrypt, and tweetnacl have zero support for X.509 certificates or PKI infrastructure. They operate purely on raw keys and data buffers.

🧩 Interoperability and Standards

If your frontend needs to talk to a specific backend ecosystem, your choice is often made for you.

  • Legacy Enterprise / .NET / Java: If your backend uses standard Java javax.crypto or .NET System.Security.Cryptography, crypto-js is often the easiest match for AES and SHA. node-forge is required if the backend exchanges X.509 certificates.
  • Modern Microservices / Go / Rust: These languages often favor modern curves. tweetnacl (or its wrapper nacl-fast) aligns perfectly with libsodium-based backends, offering better performance and security defaults.
  • Email / Security Tools: If you are building a secure email client or a tool that must verify gpg --verify output, openpgp is the only viable option.
  • Simple Handshakes: For a quick login flow where the browser encrypts a password with a server's public key, jsencrypt reduces boilerplate significantly.

πŸ“Š Summary Comparison

Featurecrypto-jsjsencryptnode-forgeopenpgptweetnacl
Primary FocusClassic AlgorithmsSimple RSAPKI & TLSOpenPGP StandardModern Elliptic Curves
Symmetric Encryptionβœ… AES, DES, RC4βŒβœ… AES, DESβœ… (via Session Keys)βœ… (XSalsa20-Poly1305)
Asymmetric EncryptionβŒβœ… RSAβœ… RSAβœ… RSA + ECCβœ… Curve25519
Digital Signatures❌ (HMAC only)βœ… RSAβœ… RSA, DSAβœ… RSA + EdDSAβœ… Ed25519
Hashingβœ… MD5, SHA, RIPEMDβŒβœ… SHA, MD5βœ… SHA-2, SHA-3βœ… SHA-512 (internal)
Certificate (X.509)βŒβŒβœ… Full Support❌ (Uses PGP Keys)❌
Ease of Use⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Security Defaults⚠️ Manual IV/Mode⚠️ Key Size Config⚠️ Complex APIβœ… Strong Defaultsβœ… Hardcoded Safe Defaults

πŸ’‘ The Architect's Recommendation

For new, security-critical applications, start with tweetnacl. Its API forces you into safe patterns (authenticated encryption) and uses modern math that is resistant to many attacks that plague older RSA/AES implementations. It is small, fast, and hard to misuse.

If you are building infrastructure tools that need to read certificates, generate CSRs, or interact with a traditional PKI, node-forge is your only real option in pure JavaScript. It is heavy, but it is the most powerful toolkit available.

Use openpgp strictly when you need compatibility with the PGP ecosystem (email, file signing). Do not use it for general-purpose HTTPS-style encryption; it is over-engineered for that.

Reserve crypto-js and jsencrypt for maintenance of legacy systems or for very specific, low-risk tasks like hashing a password before transmission (though HTTPS makes this redundant) or simple RSA handshakes where introducing a larger library is not justified. In greenfield projects requiring robust security, prefer the modern guarantees of tweetnacl or the comprehensive standards of openpgp.

How to Choose: jsencrypt vs crypto-js vs node-forge vs openpgp vs tweetnacl

  • jsencrypt:

    Select jsencrypt if your sole requirement is to perform simple RSA encryption in the browser, typically to secure a symmetric key or a small payload before sending it to a server. It is perfect for scenarios where you need to generate a key pair client-side and export the public key to a backend without dealing with complex ASN.1 structures. Do not use it for signing large documents or implementing full PKI workflows, as it is strictly limited to basic RSA operations.

  • crypto-js:

    Choose crypto-js when you need a quick, reliable implementation of standard algorithms like AES, DES, or SHA-256 for non-critical data obfuscation or legacy interoperability. It is ideal for hashing passwords before sending them over HTTPS or encrypting local storage data where key exchange is already handled by your backend. Avoid it for building new secure communication protocols, as it lacks modern authenticated encryption modes by default and requires careful configuration to prevent vulnerabilities.

  • node-forge:

    Opt for node-forge when your application requires heavy-duty PKI operations, such as parsing X.509 certificates, generating Certificate Signing Requests (CSRs), or handling TLS handshakes entirely in JavaScript. It is the go-to choice for tools that need to read PEM files, manage Certificate Authorities, or implement custom secure channels that rely on standard web PKI infrastructure. Be aware that its comprehensive feature set comes with a larger code footprint, making it less suitable for simple, lightweight tasks.

  • openpgp:

    Use openpgp when you need end-to-end encryption compatible with existing PGP/GPG ecosystems, such as secure email clients, file signing, or verifying software releases. It is the only choice here that fully implements the OpenPGP standard, supporting key rings, identity verification, and armored text formats. This library is essential if your users already possess PGP keys or if you need to interoperate with GNU Privacy Guard tools on the server side.

  • tweetnacl:

    Pick tweetnacl for modern applications requiring high-security, authenticated encryption using elliptic curves (Curve25519, Ed25519) with a minimal API surface. It is designed for developers who want to avoid configuration pitfalls by enforcing secure defaults, such as using crypto_box for sealed-box encryption or crypto_sign for digital signatures. Choose this for new security-critical features like secure messaging or wallet implementations where performance and resistance to side-channel attacks are paramount.

README for jsencrypt

JSEncrypt

A tiny (18.5kB gzip), zero dependency, JavaScript library to perform both synchronous and asynchronous OpenSSL RSA Encryption, Decryption, and Key Generation in both the Browser and Node.js.

npm version License: MIT

🌐 Documentation: https://travistidwell.com/jsencrypt
πŸ“¦ NPM Package: https://www.npmjs.com/package/jsencrypt
πŸš€ Interactive Demo: https://travistidwell.com/jsencrypt/demo

Why JSEncrypt?

When choosing an RSA encryption library for JavaScript, you need a solution that's reliable, secure, and fits seamlessly into your development workflow. JSEncrypt delivers on all fronts.

JSEncrypt stands out by providing enterprise-grade RSA encryption capabilities without the complexity and security concerns that come with heavy dependencies.

Key Benefits

  • ⚑ Tiny & Fast - Just 18.5 kB gzipped - minimal impact on your bundle size.
  • 🌐 Universal Compatibility - Works seamlessly in both Node.js server environments and browser applications
  • πŸ“¦ Zero Dependencies - No external dependencies means better security posture and reduced bundle size
  • ⚑ Flexible Execution - Supports both synchronous and asynchronous JavaScript patterns
  • πŸ”’ OpenSSL Compatible - Direct support for PEM-formatted keys generated with OpenSSL
  • πŸ›‘οΈ Proven Security - Built on Tom Wu's battle-tested jsbn library without modifying core algorithms
  • πŸš€ Production Ready - Lightweight, well-tested, and used by thousands of developers worldwide

Installation

Using npm

npm install jsencrypt

Using yarn

yarn add jsencrypt

Using CDN

Include JSEncrypt directly in your HTML:

<script src="https://cdn.jsdelivr.net/npm/jsencrypt@latest/bin/jsencrypt.min.js"></script>

Basic Usage

1. Import the Library

ES6 Modules

import { JSEncrypt } from 'jsencrypt';

CommonJS

const JSEncrypt = require('jsencrypt');

Browser Global

// JSEncrypt is available globally when using CDN
const crypt = new JSEncrypt();

2. Create RSA Keys

For the highest security, you'll need RSA key pairs to use JSEncrypt. Generate them using OpenSSL:

# Generate a 2048-bit private key
openssl genrsa -out private.pem 2048

# Extract the public key
openssl rsa -pubout -in private.pem -out public.pem

3. Basic Encryption/Decryption

// Create JSEncrypt instance
const crypt = new JSEncrypt();

// Set your private key (for decryption)
crypt.setPrivateKey(`-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA4f5wg5l2hKsTeNem/V41fGnJm6gOdrj8ym3rFkEjWT9u
U38KPhX7l3YXkLMfJj8sE3PUi0EaL6rN6rOUY8dq1fQhPhT1wfI6V8KQtQnq
1FKnNgQCVmQpCxK7qFR7Z+9MRWoJrPb8lZMmT1ELkKL6FBfkp3H3WcTl+BF0
XoZnLK0CfXfKzPJPm9jfKKE7dqnCsRiXYJbBwkNpQ5xo2lRKnNaH8GjPzJ4X
TZ5J7G6hDpXN1F3YzWZNVQRzfDfLB+w9FDaZ5kFhRc2PgB1Y8dNOhgK7RFJF
JDZhqBhSRnQ1YkLkQOnHq4Bz8l7YgRJkJHdIfTOO8l3YXkLMfJj8sE3PUi0E
qL6r9OOCzGJnVgQCVmQpCxK7qFR7Z+9MRWoJrPb8lZMmT1ELkKL6FBfkp3H3
...
-----END RSA PRIVATE KEY-----`);

// The public key is automatically derived from the private key
// Or you can set it explicitly:
// crypt.setPublicKey('-----BEGIN PUBLIC KEY-----...');

// Encrypt data
const originalText = 'Hello, World!';
const encrypted = crypt.encrypt(originalText);

// Decrypt data
const decrypted = crypt.decrypt(encrypted);

console.log('Original:', originalText);
console.log('Encrypted:', encrypted);
console.log('Decrypted:', decrypted);
console.log('Match:', originalText === decrypted); // true

Key Concepts

Public vs Private Keys

  • Public Key: Used for encryption. Safe to share publicly.
  • Private Key: Used for decryption. Keep this secret!
const crypt = new JSEncrypt();

// For encryption only (using public key)
crypt.setPublicKey(publicKeyString);
const encrypted = crypt.encrypt('secret message');

// For decryption (requires private key)
crypt.setPrivateKey(privateKeyString);  
const decrypted = crypt.decrypt(encrypted);

Key Generation

JSEncrypt supports two approaches for obtaining RSA keys: OpenSSL generation (recommended) and JavaScript generation (convenient but less secure).

Option 1: OpenSSL Key Generation (Recommended)

For production applications and maximum security, generate keys using OpenSSL:

# Generate a 2048-bit private key (recommended minimum)
openssl genrsa -out private.pem 2048

# Generate a 4096-bit private key (higher security)
openssl genrsa -out private.pem 4096

# Extract the public key
openssl rsa -pubout -in private.pem -out public.pem

# View the private key
cat private.pem

# View the public key  
cat public.pem

Why OpenSSL is more secure:

  • Uses cryptographically secure random number generators
  • Better entropy sources from the operating system
  • Optimized and audited implementations
  • Industry standard for key generation

Option 2: JavaScript Key Generation (Convenience)

JSEncrypt can generate keys directly in JavaScript, which is convenient for testing, demos, or non-critical applications:

// Create JSEncrypt instance
const crypt = new JSEncrypt();

// Generate a new key pair (default: 1024-bit)
const privateKey = crypt.getPrivateKey();
const publicKey = crypt.getPublicKey();

console.log('Private Key:', privateKey);
console.log('Public Key:', publicKey);

// You can also specify key size (512, 1024, 2048, 4096)
const crypt2048 = new JSEncrypt({ default_key_size: 2048 });
const strongerPrivateKey = crypt2048.getPrivateKey();
const strongerPublicKey = crypt2048.getPublicKey();

Asynchronous Key Generation

For better performance (especially with larger keys), use async generation:

// Asynchronous key generation (recommended for larger keys)
const crypt = new JSEncrypt({ default_key_size: 2048 });

crypt.getKey(() => {
    const privateKey = crypt.getPrivateKey();
    const publicKey = crypt.getPublicKey();
    
    console.log('Generated private key:', privateKey);
    console.log('Generated public key:', publicKey);
    
    // Now you can use the keys
    const encrypted = crypt.encrypt('Hello, World!');
    const decrypted = crypt.decrypt(encrypted);
});

Different Key Sizes

// 512-bit (fast but less secure - only for testing)
const crypt512 = new JSEncrypt({ default_key_size: 512 });

// 1024-bit (default - basic security)
const crypt1024 = new JSEncrypt({ default_key_size: 1024 });

// 2048-bit (recommended minimum for production)
const crypt2048 = new JSEncrypt({ default_key_size: 2048 });

// 4096-bit (high security but slower)
const crypt4096 = new JSEncrypt({ default_key_size: 4096 });

⚠️ Security Note: JavaScript key generation uses browser/Node.js random number generators which may have less entropy than dedicated cryptographic tools. For production applications handling sensitive data, prefer OpenSSL-generated keys.

πŸ’‘ Use Cases for JavaScript Generation:

  • Rapid prototyping and testing
  • Client-side demos and examples
  • Educational purposes
  • Non-critical applications
  • When OpenSSL is not available

Advanced Features

Digital Signatures

// Sign with the private key
const sign = new JSEncrypt();
sign.setPrivateKey(privateKey);
const signature = sign.signSha256(data);

// Verify with the public key
const verify = new JSEncrypt();
verify.setPublicKey(publicKey);
const verified = verify.verifySha256(data, signature);

OAEP Padding

// Encrypt with OAEP padding and SHA-256 hash
const encrypt = new JSEncrypt();
encrypt.setPublicKey(publicKey);
const encrypted = encrypt.encryptOAEP(data);

Supported Hash Functions

When using signatures, you can specify the hash type:

  • md2, md5, sha1, sha224, sha256, sha384, sha512, ripemd160

Browser Usage

For direct browser usage without a build system:

<!DOCTYPE html>
<html>
<head>
    <title>JSEncrypt Example</title>
    <script src="https://cdn.jsdelivr.net/npm/jsencrypt/bin/jsencrypt.min.js"></script>
</head>
<body>
    <script>
        const crypt = new JSEncrypt();
        crypt.setPrivateKey(crypt.getPrivateKey());
        
        // Use the library
        const encrypted = crypt.encrypt('Hello World!');
        const decrypted = crypt.decrypt(encrypted);
        
        console.log('Original:', 'Hello World!');
        console.log('Encrypted:', encrypted);
        console.log('Decrypted:', decrypted);
    </script>
</body>
</html>

Node.js Usage

For use within Node.js, you can use the following.

const JSEncrypt = require('jsencrypt');
const crypt = new JSEncrypt();
crypt.setPrivateKey(crypt.getPrivateKey());

// Use the library
const encrypted = crypt.encrypt('Hello World!');
const decrypted = crypt.decrypt(encrypted);

console.log('Original:', 'Hello World!');
console.log('Encrypted:', encrypted);
console.log('Decrypted:', decrypted);

Development & Testing

Running Tests

# Run all tests (Node.js + Browser)
npm test

# Run only Node.js tests  
npm run test:mocha

# Run only example validation tests
npm run test:examples

# Build the library
npm run build

# Build test bundle for browser testing
npm run build:test

Browser Tests

Visit the test page to run browser-based tests:

Documentation

For comprehensive documentation, examples, and API reference:

πŸ“– Visit the Documentation Site

Technical Background

This library provides a simple JavaScript wrapper around Tom Wu's excellent jsbn library. The core cryptographic functions remain untouched, ensuring security and reliability.

Key Format Support

JSEncrypt works with standard PEM-formatted RSA keys:

Private Key (PKCS#1):

-----BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQDHikastc8+I81zCg/qWW8dMr8mqvXQ3qbPAmu0RjxoZVI47tvs...
-----END RSA PRIVATE KEY-----

Public Key (PKCS#8):

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDlOJu6TyygqxfWT7eLtGDwajtN...
-----END PUBLIC KEY-----

RSA Variable Mappings

The library translates PEM key components to jsbn library variables:

PEM Componentjsbn Variable
modulusn
public exponente
private exponentd
prime1p
prime2q
exponent1dmp1
exponent2dmq1
coefficientcoeff

Contributing

Contributions are welcome! Please read our contributing guidelines and ensure all tests pass before submitting a pull request.

# Clone the repository
git clone https://github.com/travist/jsencrypt.git
cd jsencrypt

# Install dependencies
npm install

# Run tests
npm test

# Build the project
npm run build

License

This project is licensed under the MIT License - see the LICENSE.txt file for details.

Resources


Made with ❀️ by Travis Tidwell