Skip to content

gssasank/E2EE-Secure-Chat

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

E2EE Chat Application

Abstract

The task given to us was to create an End-to-End Encrypted Chat Application that could scale well. Encryption is an invaluable tool for journalists, activists, countries, businesses, and everyday people who need to protect their data from the threat of hackers, spies, and other malicious actors.

End to end encryption is a system of communication where only the end communicating users are able to read or listen to the messages. The main goal is to prevent any potential eavesdroppers like the Internet provider, telecom provider or any hackers from deciphering the messages.

This is achieved by applying encryption to messages on one device such that only the device to which it is sent can decrypt it. That is, messages and files are encrypted before they leave the phone or computer and aren't decrypted until they reach their destination. As a result, malicious cannot access data on the server because they do not have the private keys to decrypt the data. Instead, secret keys are stored with the individual user on their device which makes it much harder to access an individual’s data.

The security behind end-to-end encryption is enabled by the creation of a public-private key pair. This process, also known as asymmetric cryptography, employs separate cryptographic keys for securing and decrypting the message. Public keys are widely disseminated and are used to lock or encrypt a message. Private keys are only known by the owner and are used to decrypt the message.

Introduction

Types of Encryption

Based on the type of keys being used, encryption can be classified into two types:

Symmetric Encryption:

In Symmetric Encryption the same private key is used both at the sender and receiver side to both encrypt and decrypt the messages. It requires sending the key from one person to another, and hence exposing it to be compromised. It is therefore less effective as compared to asymmetric encryption for our use case as we will see.

Asymmetric Encryption:

In contrast to symmetric encryption, public key cryptography (asymmetric encryption) uses pairs of keys (one public, one private) instead of a single shared secret - public keys are for encrypting data, and private keys are for decrypting data.

A public key is like an open box with an unbreakable lock. If someone wants to send a message, they can place that message in the reciever's public box, and close the lid to lock it. The message can now be sent, to be delivered by an untrusted party without needing to worry about the contents being exposed. Once the reciever has received the box, they will unlock it with their private key - the only existing key which can open that box.

Exchanging public keys is like exchanging those boxes - each private key is kept safe with the original owner, so the contents of the box are safe in transit.

For our application we used an asymmetric encryption algorithm called the RSA encryption algorithm.

RSA Encryption

The RSA algorithm (named after those who invented it in 1978: Ron Rivest, Adi Shamir, and Leonard Adleman) is an asymmetric cryptography algorithm; this means that it uses a public key and a private key (i.e two different, mathematically linked keys). As mentioned earlier, a public key is shared publicly, while a private key is secret and must not be shared with anyone.

This example demonstrates the ideas behind public-key cryptography, though the concept is actually slightly different. In public-key cryptography. Alice encrypts her message using Bob's public key, which can only be decoded by Bob's private key.

In RSA, the public key is generated by multiplying two large prime numbers pp and qq together, and the private key is generated through a different process involving p and q. A user can then distribute his public key pq, and anyone wishing to send the user a message would encrypt their message using the public key. For all practical purposes, even computers cannot factor large numbers into the product of two primes, in the same way that factoring a huge co-prime number by hand is virtually impossible. However, multiplying two numbers is much less difficult, so a potential factorization can be verified quickly.

JSEncrypt

JSEncrypt is one of the most reputed JavaScript encryption libraries which was developed in Stanford. It is widely considered as one of the most secure implementations of the RSA encryption algorithm in JavaScript. This is the perfect library for our use case as it provides both enough flexibility and abstraction of functions implemented. We use this library in conjunction with web workers in order to maximize our thread utilization efficiency.

Tying it all together

We used parts of the JSEncrypt library to implement RSA in our application. The private keys of the individual are stored in the memory of the browser and the public keys are displayed on the left panel. The user can enter the chat room number they want to enter and start chatting securely.

Background and Related Work

Before working on the idea, we researched what E2EE is and if it was secure enough. We tried learning new concepts and increasing our knowledge about encryption algorithms, different types of cryptography etc. After gaining enough knowledge to start with the ideation of the app, we started planning on what algorithm to use and how to implement it. We used the RSA algorithm in this case. We first started working on the frontend part building up a basic yet interactive chat UI. After developing the same, we began implementing key generation and encryption techniques using the RSA algorithm and JSEncrypt library. We had to research the working of JSEncrypt, WebSocket, Express and Node.js to implement the key generation and exchange along with encryption technique. After implementing all the theories into practice, we started integrating it all with the frontend of our application. We have listed the references used for the building of the app in the References section later in this report.

A lot of research and planning went into the development of this project and most of our inspiration for the app came from the Signal open source project. We tried to implement a similar, yet simple protocol that would enable secure key and data exchange.

Technical details of the project

Tech Stack

  • Node js
  • Vue js
  • Express
  • socket.io
  • Tailwind CSS

What is done and how it is done?

For this demonstration, we created a web app. The main communication channel for the transmission of encrypted messages is through WebSocket, which is served by the express backend server.

We used a JavaScript library called jsencrypt for message encryption and decryption, which secures the data using the RSA algorithm.

  • Generating Key-Pair

    const generateKeypair = () => {
      crypt = new JSEncrypt({ default_key_size: 2048 });
      privateKey = crypt.getPrivateKey();
      // return the public key
      // the private key is hidden and stored in memory
      return crypt.getPublicKey();
    }
    
  • Encryption

    const encrypt = (content, publicKey) => {
      crypt.setKey(publicKey);
      return crypt.encrypt(content);
    }
    
  • Decryption

    const decrypt = (content) => {
      crypt.setKey(privateKey);
      return crypt.decrypt(content);
    }
    

The private key is stored in the browser's memory, and the public key is sent to the chatroom via WebSocket.

  socket.on("PUBLIC_KEY", (key) => {
    socket.broadcast.to(currentRoom).emit("PUBLIC_KEY", key);
  });

The client then encrypts the message with this private key and sends the encrypted message over the WebSocket. Because the message is encrypted, no one other than the recipient can read it. The encrypted messages passing through the server are depicted in the figure below.

Server logs of Encrypted messages

As seen in the attached image, all of the messages are encrypted, and because we don't have access to the private key, we can't decrypt the messages and see it's content.

Proposed Changes

Refactoring the app in Flutter/React Native to develop a similar application for mobile platforms. We also plan on moving away from the Sockets.io library as it inroduces an additional risk vector by exposing the computer's ports. We can bypass this by maintaining a database in a peer-to-peer encrypted storage solution such as Gun.js. This makes sure that not all of our data is centrally stored and even if one of the computers on the P2P network get compromised, the integrity of the ledger remains uncompromised.

Relevant Statistics

Difference between Symmetric and Asymmetric Cryptography


A general explanation on how E2EE works


How End-to-End Encryption works in Whatsapp



E2EE security Analysis

Summary

To summarize our report, we first look at different types of cryptography namely Symmetric Cryptography which basically involves encrypting and decrypting with the same private key at both sender's and receiver's sides while the other one being asymmetric cryptography which involves a private-public key pair encrypting with the receivers public key on sender's end and decrypting with receiver's private key on receiver's end.

The end-to-end encryption technique is based on the asymmetric cryptography. The sent message is encrypted on the sender's device with the receiver's public key and stays encrypted until it reaches the receiver's device. On the receiver's device, the message is decrypted with the receiver's private key. Using RSA algorithm, in which the public key is generated by multiplying two large prime numbers pp and qq together, and the private key is generated through a different process involving p and q, we built this chat app with the help of a JavaScript library called JSEncrypt. The library, also considered as the as one of the most secure implementations of the RSA encryption algorithm in JavaScript, is the perfect library for our use case as it provides both, enough flexibility and abstraction of functions implemented. Apart from the library, we have used socket.io for key exchange and communication. The public key is exchanged with socket.io while the private key is stored on the device in browser's memory. Because of this, whenever the application is reloaded the previous private key is lost and a new private key is generated.

Inspired from Signal open Source project, we were able to create a fully working chat app that can be run on different devices, where users could join rooms to chat with each other in an end-to-end encrypted environment.

Conclusion

Accomplishments and Learnings

In the course of this project, we learned developing secure applications using the popular JSEncrypt library. We also learnt how to make a complete web application using Express and Sockets.io. We learnt about the drawbacks and benifits of using public cryptography libraries and we learnt implemeting the same in secure applications.

We read about how the popular open source messaging app Signal enables secure transfer of messages and we tried to use similar concpts in our application. We read about the latest innovations in asymmetric cryptography protocols that were relevant to our project such as Double Ratchet and Sesame. We also learnt about a more secure kind of Diffie-Hellman symmetric key exchange called X3DH (or Extended Triple Diffie-Hellman).

Different possible paths

Even though the End-to-End Encryption Technique is secure and efficient, it has a few alternatives which might have one advantage or other over E2EE and vice versa. One such technique is encryption-in-transit. The technique protects your data if communications are intercepted while data moves between your site and the cloud provider or between two services. The technique lies in the data enciphering through all transfer stages: from the user’s device to the server, then to the recipient’s device. While entering or exiting each of these stages, information is being enciphered and deciphered.

We can also have a completely decentralized solution by storing all our encrypted messages on a blockchain, which in itself is extremely resilient to malicious attacks. We can have users exchange messages using their private keys. Implementing a group chat and multimedia exhange along with native payments will be an extremely easy task.

Future Work

In the future, we plan on making this web app responsive to run on all devices. We plan on researching on enabling group chat and enable the same. Along with that, we also want to enable multimedia sharing in the application.

Another change is that, currently, we are using RSA to directly encrypt and decrypt messages, which vastly restricts the size of the message that can be sent but in the future, we are planning on encrypting the messages using AES and share the key using RSA encryption to ensure sharing of large pieces of data which is a shortcoming of RSA. Also, we want to integrate the system with an authentication system to enable user login.

References

  1. Understanding Cryptography by Christof Paar
  2. https://www.youtube.com/watch?v=ZPXVSJnDA_A
  3. https://websockets.readthedocs.io/en/stable/
  4. https://www.npmjs.com/package/jsencrypt
  5. https://signal.org/docs/
  6. http://www-cs-students.stanford.edu/~tjw/jsbn/
  7. https://signal.org/docs/specifications/x3dh/
  8. https://github.com/signalapp/libsignal-protocol-javascript

Releases

No releases published

Packages

No packages published