jsencrypt
A tiny (18.5 kB gzip), zero-dependency, Javascript library to perform OpenSSL RSA Encryption, Decryption, and Key Generation.
Top Related Projects
A native implementation of TLS in Javascript and tools to write crypto-based and network-heavy webapps
JavaScript library of crypto standards.
Stanford Javascript Crypto Library
Fast Elliptic Curve Cryptography in plain javascript
A pure JavaScript implementation of the AES block cipher and all common modes of operation for node.js or web browsers.
Generate RFC-compliant UUIDs in JavaScript
Quick Overview
JSEncrypt is a JavaScript library that implements RSA encryption and decryption for use in web applications. It provides a simple interface for encrypting and decrypting messages using public and private keys, making it easier to implement secure communication in browser-based environments.
Pros
- Easy to use with a straightforward API
- Supports both encryption and decryption operations
- Compatible with most modern browsers
- Lightweight and has minimal dependencies
Cons
- Limited to RSA encryption, not suitable for large data encryption
- May have performance issues with very large keys or frequent operations
- Relies on the security of the client-side environment
- Not actively maintained (last commit was in 2020)
Code Examples
Generating a new key pair:
const jsencrypt = new JSEncrypt({default_key_size: 2048});
const publicKey = jsencrypt.getPublicKey();
const privateKey = jsencrypt.getPrivateKey();
Encrypting a message:
const encrypt = new JSEncrypt();
encrypt.setPublicKey(publicKey);
const encrypted = encrypt.encrypt("Hello, World!");
Decrypting a message:
const decrypt = new JSEncrypt();
decrypt.setPrivateKey(privateKey);
const decrypted = decrypt.decrypt(encrypted);
Getting Started
- Include the JSEncrypt library in your HTML file:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jsencrypt/3.2.1/jsencrypt.min.js"></script>
- Create a new JSEncrypt instance and use it to encrypt or decrypt:
const encrypt = new JSEncrypt();
encrypt.setPublicKey('-----BEGIN PUBLIC KEY-----...');
const encrypted = encrypt.encrypt("Message to encrypt");
const decrypt = new JSEncrypt();
decrypt.setPrivateKey('-----BEGIN PRIVATE KEY-----...');
const decrypted = decrypt.decrypt(encrypted);
Note: Replace the ellipsis (...) with actual public and private keys.
Competitor Comparisons
A native implementation of TLS in Javascript and tools to write crypto-based and network-heavy webapps
Pros of Forge
- More comprehensive cryptographic library with a wider range of algorithms and functions
- Active development and maintenance, with regular updates and bug fixes
- Better performance for certain cryptographic operations
Cons of Forge
- Larger file size and potentially more complex to integrate
- Steeper learning curve due to its extensive feature set
- May be overkill for projects that only require basic RSA encryption
Code Comparison
Forge (RSA encryption):
var publicKey = forge.pki.publicKeyFromPem(publicKeyPem);
var encrypted = publicKey.encrypt(plaintext);
JSEncrypt (RSA encryption):
var encrypt = new JSEncrypt();
encrypt.setPublicKey(publicKeyPem);
var encrypted = encrypt.encrypt(plaintext);
Both libraries provide similar functionality for RSA encryption, but Forge offers a more extensive API for various cryptographic operations. JSEncrypt is more focused on RSA encryption and decryption, making it simpler for basic use cases.
Forge is better suited for projects requiring a wide range of cryptographic functions, while JSEncrypt is ideal for simpler implementations focusing primarily on RSA encryption.
JavaScript library of crypto standards.
Pros of crypto-js
- Broader range of cryptographic functions (AES, DES, TripleDES, etc.)
- Supports various modes of operation (ECB, CBC, CFB, OFB, CTR)
- Active development and regular updates
Cons of crypto-js
- Larger file size due to comprehensive feature set
- May have a steeper learning curve for beginners
- Performance can be slower for certain operations compared to specialized libraries
Code Comparison
jsencrypt (RSA encryption):
var encrypt = new JSEncrypt();
encrypt.setPublicKey(publicKey);
var encrypted = encrypt.encrypt(message);
crypto-js (AES encryption):
var encrypted = CryptoJS.AES.encrypt(message, secretKey);
var decrypted = CryptoJS.AES.decrypt(encrypted, secretKey);
var originalText = decrypted.toString(CryptoJS.enc.Utf8);
Summary
jsencrypt focuses specifically on RSA encryption, making it lightweight and easy to use for RSA operations. crypto-js, on the other hand, offers a comprehensive suite of cryptographic functions, including symmetric and asymmetric encryption, hashing, and more. While crypto-js provides greater flexibility, it may be overkill for projects that only require RSA encryption. The choice between the two depends on the specific cryptographic needs of your project and the desired balance between functionality and simplicity.
Stanford Javascript Crypto Library
Pros of SJCL
- Offers a broader range of cryptographic functions, including symmetric encryption, hashing, and key derivation
- Provides a more comprehensive cryptographic library with various modes of operation
- Actively maintained with regular updates and contributions
Cons of SJCL
- Larger file size and potentially higher overhead due to its comprehensive nature
- May have a steeper learning curve for developers who only need basic encryption functionality
- Requires more setup and configuration for simple use cases
Code Comparison
SJCL (Symmetric encryption example):
var plaintext = "Hello, World!";
var password = "secret";
var ciphertext = sjcl.encrypt(password, plaintext);
var decrypted = sjcl.decrypt(password, ciphertext);
JSEncrypt (RSA encryption example):
var encrypt = new JSEncrypt();
encrypt.setPublicKey(publicKey);
var encrypted = encrypt.encrypt("Hello, World!");
var decrypt = new JSEncrypt();
decrypt.setPrivateKey(privateKey);
var decrypted = decrypt.decrypt(encrypted);
The code examples demonstrate the different focus of each library. SJCL provides symmetric encryption with a simple API, while JSEncrypt specializes in RSA encryption and decryption. SJCL offers a more versatile set of cryptographic functions, whereas JSEncrypt is more focused on RSA operations.
Fast Elliptic Curve Cryptography in plain javascript
Pros of elliptic
- Supports a wider range of elliptic curve cryptography operations
- Generally faster performance for ECC operations
- More actively maintained with regular updates
Cons of elliptic
- Steeper learning curve due to more complex API
- Lacks built-in support for RSA encryption (focus is on ECC)
Code Comparison
elliptic:
const EC = require('elliptic').ec;
const ec = new EC('secp256k1');
const key = ec.genKeyPair();
const publicKey = key.getPublic('hex');
const signature = key.sign('message').toDER('hex');
jsencrypt:
const encrypt = new JSEncrypt();
encrypt.setPublicKey('-----BEGIN PUBLIC KEY-----...');
const encrypted = encrypt.encrypt('message');
const decrypt = new JSEncrypt();
decrypt.setPrivateKey('-----BEGIN RSA PRIVATE KEY-----...');
const decrypted = decrypt.decrypt(encrypted);
Summary
elliptic is more focused on elliptic curve cryptography, offering a broader range of ECC operations with better performance. It's actively maintained but has a steeper learning curve. jsencrypt, on the other hand, provides a simpler API primarily for RSA encryption and decryption, making it easier to use for basic public-key cryptography tasks but with limited functionality compared to elliptic.
A pure JavaScript implementation of the AES block cipher and all common modes of operation for node.js or web browsers.
Pros of aes-js
- Focused specifically on AES encryption, providing a lightweight solution
- Supports various modes of operation (ECB, CBC, CFB, OFB, CTR)
- Pure JavaScript implementation, making it easy to use in browser environments
Cons of aes-js
- Limited to AES encryption, lacking support for other cryptographic algorithms
- May require additional libraries for key generation and management
- Less actively maintained compared to jsencrypt
Code Comparison
aes-js:
var aesjs = require('aes-js');
var key = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
var text = 'Text may be any length you wish, no padding is required.';
var textBytes = aesjs.utils.utf8.toBytes(text);
var aesCtr = new aesjs.ModeOfOperation.ctr(key, new aesjs.Counter(5));
var encryptedBytes = aesCtr.encrypt(textBytes);
jsencrypt:
var encrypt = new JSEncrypt();
encrypt.setPublicKey('-----BEGIN PUBLIC KEY-----...');
var encrypted = encrypt.encrypt('Hello World!');
var decrypt = new JSEncrypt();
decrypt.setPrivateKey('-----BEGIN RSA PRIVATE KEY-----...');
var uncrypted = decrypt.decrypt(encrypted);
The code examples demonstrate the different focus of each library. aes-js provides low-level AES operations, while jsencrypt offers higher-level RSA encryption with key management.
Generate RFC-compliant UUIDs in JavaScript
Pros of uuid
- Focused on generating UUIDs, providing a simple and specific functionality
- Lightweight and efficient, with minimal dependencies
- Supports multiple UUID versions (v1, v3, v4, v5) and namespaces
Cons of uuid
- Limited to UUID generation, lacking encryption capabilities
- May require additional libraries for more complex cryptographic operations
- Not designed for handling RSA encryption or decryption tasks
Code Comparison
uuid example:
import { v4 as uuidv4 } from 'uuid';
const id = uuidv4();
console.log(id); // e.g. '1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed'
jsencrypt example:
var encrypt = new JSEncrypt();
encrypt.setPublicKey('-----BEGIN PUBLIC KEY-----...');
var encrypted = encrypt.encrypt('Hello, World!');
console.log(encrypted);
Summary
uuid is a specialized library for generating UUIDs, while jsencrypt focuses on RSA encryption. uuid is more lightweight and efficient for its specific task, but lacks the broader cryptographic capabilities of jsencrypt. The choice between them depends on whether you need UUID generation or RSA encryption functionality in your project.
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
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.
ð 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:
- Local development:
http://localhost:4000/test/
(when running Jekyll) - Online: https://travistidwell.com/jsencrypt/test/
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 Component | jsbn Variable |
---|---|
modulus | n |
public exponent | e |
private exponent | d |
prime1 | p |
prime2 | q |
exponent1 | dmp1 |
exponent2 | dmq1 |
coefficient | coeff |
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
- 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
Top Related Projects
A native implementation of TLS in Javascript and tools to write crypto-based and network-heavy webapps
JavaScript library of crypto standards.
Stanford Javascript Crypto Library
Fast Elliptic Curve Cryptography in plain javascript
A pure JavaScript implementation of the AES block cipher and all common modes of operation for node.js or web browsers.
Generate RFC-compliant UUIDs in JavaScript
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot