@chatereum/react-e2ee v3.0.1
React E2EE
An end-to-end encryption package that is basically a wrapper package of SubtleCrypto library for browsers. See MDN.
Installation
Use the package manager npm to install react-e2ee.
npm install @chatereum/react-e2eeRun test cases
npm run testWhat's New? :fire:
Changelogs v3.0.0
encrypt,decrypt,encryptFileanddecryptFilefunctions are now deprecated. However, you can still use these functions.- added
encryptPlaintext,decryptForPlaintext,encryptFileBufferanddecryptFileBufferfunctions to replace corresponding deprecated functions. These functions will be improved in terms of performance and better error handling in future releases. - added test cases using
jest - added better typescript documentation and intellisense
Usage
General usage
import E2EE from '@chatereum/react-e2ee';
//generates a RSA-OAEP private key and public key in PEM format
const keys = await E2EE.getKeys();
/*
would return something like:
{
private_key : "-----BEGIN PRIVATE KEY-----...", //PEM
public_key : "-------BEGIN PUBLIC KEY-----...." //PEM
}
*/
//encrypts any string format message
//if you want to encrypt a format other than string, convert it into string first
const message = "Made with 💙 by Arjis Chakraborty";
const encrypted = await E2EE.encryptPlaintext({
public_key: keys.public_key,
plain_text: message,
});
/*
would return something like:
{
cipher_text: /hfan3ulskxzkjr20mckmicurj38rmdkalclalor\dj3*, //base64
aes_key: 9r2hnankal92/*gawaoaowrj38jma/daun, //base64
iv: 1hnfkalmnfinfkeif874fsf&bbdajwk9dkacam //base64
}
you can now wire this entire object to the recipient through eg: WebSockets
*/
//on the receiver's end
//decrypting an encrypted message
const decrypted = await E2EE.decryptForPlaintext({
encrypted_text: encrypted,
private_key: keys.private_key,
});
/*
would return the original message:
decrypted = "Made with 💙 by Arjis Chakraborty"
you can now show this message on the recipient's frontend
*/End-to-end encrypting files
import E2EE from '@chatereum/react-e2ee';
//encrypts any buffer format file
const file_buffer = new ArrayBuffer(16); //this should be the file in buffer format
const encrypted = await E2EE.encryptFileBuffer({
public_key: keys.public_key,
file_buffer,
});
/*
would return something like:
{
cipher_buffer: ArrayBuffer { byteLength: 16 }, //ArrayBuffer
aes_key: 9r2hnankal92/*gawaoaowrj38jma/daun, //base64
iv: 1hnfkalmnfinfkeif874fsf&bbdajwk9dkacam //base64
}
you can now wire this entire object to the recipient through eg: WebSockets
*/
//on the receiver's end
//decrypting an encrypted file
const decrypted = await E2EE.decryptFileBuffer({
encrypted_buffer: encrypted,
private_key: keys.private_key,
});
/*
would return the original message:
decrypted = ArrayBuffer { byteLength: 16 }
you can now use this ArrayBuffer to show maybe an image by converting it to a base64 data URL
*/Note: If you are using deprecated functions in your code, check out the documentation for v2.0
How it works
We generate a private and public
RSA-OAEPkeys usinggetKeys()functionWe get the raw string message that needs to be encrypted (usually referred to as
plainText)We then call the
encrypt()function to encrypt ourplainTextwith the RSApublic keyof the recipient.Internally, a lot of things are going on in the
encrypt()function.We first
encodetheplainTextusing anencoder()function. Let's call thisencoded.Then we generate a
Diffie-Hellmanshared secret key using theAES-CBCcipher of length256. This also requires aivpadding which is of typeUint8Arrayof size16. Ultimately, we get anAESkey back. Let's call this keyAESand theivpadding asIV.Now we take
encodedand encrypt it usingAES. This gives us back the encryptedplainText. Let's call thisencrypted_text.Now we use the
public keyof the recipient to encrypt theAESkey. Let's call thisencrypted_AES.To finish the
encryptionprocess, we return an object containingencrypted_text,encrypted_AESandIV. We send backIVbecause we need this indecrypt().
Now that we have our encrypted message, we can pass this entire object onto our server to further be passed on to the recipient client.
On the recipient client, we call the
decrypt()function.Again, internally, we have a lot of stuff going on:
The recipients takes its
private keyand tries to decrypt theencrypted_AES. Let's call thisAES.It then tries to use the
AESkey alongwith theIVto decryptencrypted_text. Let's call thisencoded_text.Once we have our
encoded_text, we need to decode this into human-readable format (UTF-8).We run a
decoderfunction to decode theencoded_text.Finally, we have our decoded, human-readable
plainText.
This
plainTextis what is displayed to the recipient's frontend.You can read more about
End-to-end encryptionhere.
Prerequisites
These are some important requirements that you need to make sure before you can use this library:
:exclamation: The website on which you intend to use this library must have a TLS or SSL certificate installed, i.e. it must have support for HTTPS. Alternatively, for testing purposes, you should access your site over localhost or else the library won't work.
:exclamation: This library is strictly for browser based Node.js frameworks and specifically for React as the name already suggests.
:exclamation: DO NOT ever share your private key over the "wire". You can only share your public key to the server side or even directly to your recipient client.
Good to know
:blue_heart: This library uses the SubtleCrypto library which is embedded in the browser. A down side to SubtleCrypto is that it can't run on an http connection that doesn't have any TLS or SSL certificates. However, localhost seems to be an exception. You can learn more about the library here.
:blue_heart: This library is primarily made for React and some other browser based Node.js frameworks but you can fork this repository and use the code on any browser based application you like that supports SubtleCrypto.
:blue_heart: I am working on a few examples to demonstrate the full working of this library. Until then, SubtleCrypto has a lot of documentation to offer.
Contributing
This repository is open to any contributions to make the library a hassle free solution to End-to-End Encryption in browsers.
Made with :blue_heart: by Arjis Chakraborty