jsencrypt
A 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
Website
http://travistidwell.com/jsencrypt
Introduction
When browsing the internet looking for a good solution to RSA Javascript encryption, there is a whole slew of libraries that basically take the fantastic work done by Tom Wu @ http://www-cs-students.stanford.edu/~tjw/jsbn/ and then modify that code to do what they want.
What I couldn't find, however, was a simple wrapper around this library that basically uses the library practically untouched, but adds a wrapper to provide parsing of actual Private and Public key-pairs generated with OpenSSL.
This library is the result of these efforts.
How to use this library.
This library should work hand-in-hand with openssl. With that said, here is how to use this library.
- Within your terminal (Unix based OS) type the following.
openssl genrsa -out rsa_1024_priv.pem 1024
- This generates a private key, which you can see by doing the following...
cat rsa_1024_priv.pem
- You can then copy and paste this in the Private Key section of within index.html.
- Next, you can then get the public key by executing the following command.
openssl rsa -pubout -in rsa_1024_priv.pem -out rsa_1024_pub.pem
- You can see the public key by typing...
cat rsa_1024_pub.pem
- Now copy and paste this in the Public key within the index.html.
- Now you can then convert to and from encrypted text by doing the following in code.
<!doctype html>
<html>
<head>
<title>JavaScript RSA Encryption</title>
<script src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
<script src="bin/jsencrypt.min.js"></script>
<script type="text/javascript">
// Call this code when the page is done loading.
$(function() {
// Run a quick encryption/decryption when they click.
$('#testme').click(function() {
// Encrypt with the public key...
var encrypt = new JSEncrypt();
encrypt.setPublicKey($('#pubkey').val());
var encrypted = encrypt.encrypt($('#input').val());
// Decrypt with the private key...
var decrypt = new JSEncrypt();
decrypt.setPrivateKey($('#privkey').val());
var uncrypted = decrypt.decrypt(encrypted);
// Now a simple check to see if the round-trip worked.
if (uncrypted == $('#input').val()) {
alert('It works!!!');
}
else {
alert('Something went wrong....');
}
});
});
</script>
</head>
<body>
<label for="privkey">Private Key</label><br/>
<textarea id="privkey" rows="15" cols="65">-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDlOJu6TyygqxfWT7eLtGDwajtNFOb9I5XRb6khyfD1Yt3YiCgQ
WMNW649887VGJiGr/L5i2osbl8C9+WJTeucF+S76xFxdU6jE0NQ+Z+zEdhUTooNR
aY5nZiu5PgDB0ED/ZKBUSLKL7eibMxZtMlUDHjm4gwQco1KRMDSmXSMkDwIDAQAB
AoGAfY9LpnuWK5Bs50UVep5c93SJdUi82u7yMx4iHFMc/Z2hfenfYEzu+57fI4fv
xTQ//5DbzRR/XKb8ulNv6+CHyPF31xk7YOBfkGI8qjLoq06V+FyBfDSwL8KbLyeH
m7KUZnLNQbk8yGLzB3iYKkRHlmUanQGaNMIJziWOkN+N9dECQQD0ONYRNZeuM8zd
8XJTSdcIX4a3gy3GGCJxOzv16XHxD03GW6UNLmfPwenKu+cdrQeaqEixrCejXdAF
z/7+BSMpAkEA8EaSOeP5Xr3ZrbiKzi6TGMwHMvC7HdJxaBJbVRfApFrE0/mPwmP5
rN7QwjrMY+0+AbXcm8mRQyQ1+IGEembsdwJBAN6az8Rv7QnD/YBvi52POIlRSSIM
V7SwWvSK4WSMnGb1ZBbhgdg57DXaspcwHsFV7hByQ5BvMtIduHcT14ECfcECQATe
aTgjFnqE/lQ22Rk0eGaYO80cc643BXVGafNfd9fcvwBMnk0iGX0XRsOozVt5Azil
psLBYuApa66NcVHJpCECQQDTjI2AQhFc1yRnCU/YgDnSpJVm1nASoRUnU8Jfm3Oz
uku7JUXcVpt08DFSceCEX9unCuMcT72rAQlLpdZir876
-----END RSA PRIVATE KEY-----</textarea><br/>
<label for="pubkey">Public Key</label><br/>
<textarea id="pubkey" rows="15" cols="65">-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDlOJu6TyygqxfWT7eLtGDwajtN
FOb9I5XRb6khyfD1Yt3YiCgQWMNW649887VGJiGr/L5i2osbl8C9+WJTeucF+S76
xFxdU6jE0NQ+Z+zEdhUTooNRaY5nZiu5PgDB0ED/ZKBUSLKL7eibMxZtMlUDHjm4
gwQco1KRMDSmXSMkDwIDAQAB
-----END PUBLIC KEY-----</textarea><br/>
<label for="input">Text to encrypt:</label><br/>
<textarea id="input" name="input" type="text" rows=4 cols=70>This is a test!</textarea><br/>
<input id="testme" type="button" value="Test Me!!!" /><br/>
</body>
</html>
-
Look at how http://www.travistidwell.com/jsencrypt/demo works to get a better idea.
-
Signing and verification works in a similar way.
// Sign with the private key...
var sign = new JSEncrypt();
sign.setPrivateKey($('#privkey').val());
var signature = sign.sign($('#input').val(), CryptoJS.SHA256, "sha256");
// Verify with the public key...
var verify = new JSEncrypt();
verify.setPublicKey($('#pubkey').val());
var verified = verify.verify($('#input').val(), signature, CryptoJS.SHA256);
// Now a simple check to see if the round-trip worked.
if (verified) {
alert('It works!!!');
}
else {
alert('Something went wrong....');
}
- Note that you have to provide the hash function. In this example we use one from the CryptoJS library, but you can use whichever you want.
- Also, unless you use a custom hash function, you should provide the hash type to the
sign
method. Possible values are:md2
,md5
,sha1
,sha224
,sha256
,sha384
,sha512
,ripemd160
.
Other Information
This library heavily utilizes the wonderful work of Tom Wu found at http://www-cs-students.stanford.edu/~tjw/jsbn/.
This jsbn library was written using the raw variables to perform encryption. This is great for encryption, but most private keys use a Private Key in the PEM format seen below.
1024 bit RSA Private Key in Base64 Format
-----BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQDHikastc8+I81zCg/qWW8dMr8mqvXQ3qbPAmu0RjxoZVI47tvs
kYlFAXOf0sPrhO2nUuooJngnHV0639iTTEYG1vckNaW2R6U5QTdQ5Rq5u+uV3pMk
7w7Vs4n3urQ6jnqt2rTXbC1DNa/PFeAZatbf7ffBBy0IGO0zc128IshYcwIDAQAB
AoGBALTNl2JxTvq4SDW/3VH0fZkQXWH1MM10oeMbB2qO5beWb11FGaOO77nGKfWc
bYgfp5Ogrql4yhBvLAXnxH8bcqqwORtFhlyV68U1y4R+8WxDNh0aevxH8hRS/1X5
031DJm1JlU0E+vStiktN0tC3ebH5hE+1OxbIHSZ+WOWLYX7JAkEA5uigRgKp8ScG
auUijvdOLZIhHWq7y5Wz+nOHUuDw8P7wOTKU34QJAoWEe771p9Pf/GTA/kr0BQnP
QvWUDxGzJwJBAN05C6krwPeryFKrKtjOGJIniIoY72wRnoNcdEEs3HDRhf48YWFo
riRbZylzzzNFy/gmzT6XJQTfktGqq+FZD9UCQGIJaGrxHJgfmpDuAhMzGsUsYtTr
iRox0D1Iqa7dhE693t5aBG010OF6MLqdZA1CXrn5SRtuVVaCSLZEL/2J5UcCQQDA
d3MXucNnN4NPuS/L9HMYJWD7lPoosaORcgyK77bSSNgk+u9WSjbH1uYIAIPSffUZ
bti+jc1dUg5wb+aeZlgJAkEAurrpmpqj5vg087ZngKfFGR5rozDiTsK5DceTV97K
a3Y+Nzl+XWTxDBWk4YPh2ZlKv402hZEfWBYxUDn5ZkH/bw==
-----END RSA PRIVATE KEY-----
This library simply takes keys in the following format, and translates it to those variables needed to perform the encryptions used in Tom Wu's library.
Here are some good resources to investigate further.
- http://etherhack.co.uk/asymmetric/docs/rsa_key_breakdown.html
- http://www.di-mgt.com.au/rsa_alg.html
- https://polarssl.org/kb/cryptography/asn1-key-structures-in-der-and-pem
With this information, we can translate a private key format to the variables required with the jsbn library from Tom Wu by using the following mappings.
modulus => n
public exponent => e
private exponent => d
prime1 => p
prime2 => q
exponent1 => dmp1
exponent2 => dmq1
coefficient => coeff
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