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.
π Documentation: https://travistidwell.com/jsencrypt
π¦ NPM Package: https://www.npmjs.com/package/jsencrypt
π Interactive Demo: https://travistidwell.com/jsencrypt/demo
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.
- β‘ 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
npm install jsencrypt
yarn add jsencrypt
Include JSEncrypt directly in your HTML:
<script src="https://cdn.jsdelivr.net/npm/jsencrypt@latest/bin/jsencrypt.min.js"></script>
import { JSEncrypt } from 'jsencrypt';
const JSEncrypt = require('jsencrypt');
// JSEncrypt is available globally when using CDN const crypt = new JSEncrypt();
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
// 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
- 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);
JSEncrypt supports two approaches for obtaining RSA keys: OpenSSL generation (recommended) and JavaScript generation (convenient but less secure).
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
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();
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); });
// 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 });
π‘ Use Cases for JavaScript Generation:
- Rapid prototyping and testing
- Client-side demos and examples
- Educational purposes
- Non-critical applications
- When OpenSSL is not available
// 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);
// Encrypt with OAEP padding and SHA-256 hash const encrypt = new JSEncrypt(); encrypt.setPublicKey(publicKey); const encrypted = encrypt.encryptOAEP(data);
When using signatures, you can specify the hash type:
md2,md5,sha1,sha224,sha256,sha384,sha512,ripemd160
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>
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);
# 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
Visit the test page to run browser-based tests:
- Local development:
http://localhost:4000/test/(when running Jekyll) - Online: https://travistidwell.com/jsencrypt/test/
For comprehensive documentation, examples, and API reference:
π Visit the Documentation Site
This library provides a simple JavaScript wrapper around Tom Wu's excellent jsbn library. The core cryptographic functions remain untouched, ensuring security and reliability.
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-----
The library translates PEM key components to jsbn library variables:
| PEM Component | jsbn Variable |
|---|---|
| modulus | n |
| public exponent | e |
| private exponent | d |
| prime1 | p |
| prime2 | q |
| exponent1 | dmp1 |
| exponent2 | dmq1 |
| coefficient | coeff |
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
This project is licensed under the MIT License - see the LICENSE.txt file for details.
- Tom Wu's jsbn library: http://www-cs-students.stanford.edu/~tjw/jsbn/
- RSA Key Breakdown: http://etherhack.co.uk/asymmetric/docs/rsa_key_breakdown.html
- RSA Algorithm Details: http://www.di-mgt.com.au/rsa_alg.html
- ASN.1 Key Structures: https://polarssl.org/kb/cryptography/asn1-key-structures-in-der-and-pem
Made with β€οΈ by Travis Tidwell