A tiny (18.5 kB gzip), zero-dependency, Javascript library to perform OpenSSL RSA Encryption, Decryption, and Key Generation.
See the codeA 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.
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
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:
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 });
⚠️ 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:
// 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, ripemd160For 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:
http://localhost:4000/test/ (when running Jekyll)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.
Made with ❤️ by Travis Tidwell
Overall
Maintained
Code review
npm
Latest release
Releases this year
24 followers · starred Mar 2016
630 followers · starred Feb 2017
959 followers · starred Mar 2017
396 followers · starred Jul 2017
A tiny (18.5 kB gzip), zero-dependency, Javascript library to perform OpenSSL RSA Encryption, Decryption, and Key Generation.
See the codeA 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.
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
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:
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 });
⚠️ 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:
// 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, ripemd160For 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:
http://localhost:4000/test/ (when running Jekyll)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.
Made with ❤️ by Travis Tidwell
Overall
Maintained
Code review
npm
Latest release
Releases this year
24 followers · starred Mar 2016
630 followers · starred Feb 2017
959 followers · starred Mar 2017
396 followers · starred Jul 2017