Virp
Encrypted Messaging Platform
Developer
Elle J
Category
Web App
Live Site
Source Code
Release Year
2020
Virp is a privacy-focused web-based messaging platform allowing users to chat via end-to-end encrypted (E2EE) messages. Users can control self-destruction timers for outgoing messages, manage notifications, settings, active chats, as well as their contacts list by searching, adding, removing, or blocking other users.
Table of Contents
Vision
1.1 Background
Basic peer-to-peer communication is a central part of belonging to the animal species. Whether it’d be through symbols in cave paintings as in 30,000 B.C., or by fax or telephone as were invented in the 1800’s, having a means of communication is a uniting and vital factor in our lives. As computers emerged along with the ability to send messages seemingly instantaneously to someone on the opposite side of the globe, we found ourselves ever more connected. In modern days, this type of communication has become ingrained in our everyday lives and so has the collection of the data and metadata that we send. This information tells a better story for every day about who you are as a person and what choices you may be more prone to make, creating value from that data.
Whenever there is something of value we should also protect it accordingly in order to prevent it from being abused or stolen. As the careless handling of people’s personal data unfortunately becomes conspicuous at times, so does the need for data security and privacy. The number of people acknowledging the importance of privacy protection is ever growing, regardless of technical background. This is also true for governments around the world now enforcing different kinds of data protection laws and regulations. Various services and applications focusing on this issue have seemingly gotten more attention from ordinary people, signifying a market for privacy oriented applications that can still offer a solution for our basic human need to communicate.
1.2 The Product and Target
The software to be developed is called Virp--an encrypted web based chat application. Virp provides a secure platform for users to chat privately via end-to-end encrypted messages by default and to control self destruction timers for each message sent. Through a modern dark theme user interface, users are able to sign up and get access to all of the features available.
Virp is developed to meet the needs of those who demand a higher standard of care for their personal data. This application offers a way to communicate with friends, family, or colleagues in an easily accessible way (i.e. via the browser) without any permanent records. This is also what differentiates us from other privacy-focused messaging applications available on the market today, as the most well-known brands are mobile-based (see section 1.3). Moreover, by simply being “yet another privacy app” we aspire to shine a little more light on the growing demand for control of our own data. Our primary target group are people in the ages 15-40 who actively value the right to privacy and want reliable messaging through a clean easy-to-use UI.
All messages stored in the database are encrypted and self-destruct after 30 days by default. When sending a message, a user has the option to select when the message should self-destruct and thereby be deleted from the database. The options available are: 1min, 5min, 30min, 1h, 6h, 12h, 1d, 7d, 30d. The encrypted messages being received automatically get decrypted, although the user may choose to decrypt (or unlock) a message only once the user actively chooses to. Apart from the actual content of the message, each user is able to see the date and time of it, as well as the time left before destruction. Sending and receiving emojis are also possible.
In regards to user information, Virp only stores a username and password, thus no name or email. This is in order to preserve the higher level of privacy that we aspire to keep. Changing username and/or password is possible when logged in, as well as deleting the account. A user may also view its list of currently active chats and next to each chat see the time (if same day), day (if same week), or date (if older than 1 week) of the most recent message. The number of unread messages in a specific chat is also displayed. If a new message is received, the user is alerted via a notification box. Notifications can be turned off. The user can open its contact list, search for other users via username, and add or remove them to or from their list. Blocking and unblocking specific users from initiating a chat conversation is also possible.
The overall look and feel is a modern, minimalistic, spacious, and dark theme application.
1.3 Similar Products
Messaging apps focusing on privacy and security:
- Mobile & Desktop
- Wickr (wickr.com)
- Protocol: WMP (developed by Wickr)
- Signal (signal.org)
- Protocol: Signal (developed by Signal)
- Telegram (telegram.org)
- Protocol: MTProto (developed by Telegram)
- WhatsApp (whatsapp.com)
- Protocol: Signal (developed by Signal)
- Wickr (wickr.com)
- Browser
- Cyph (cyph.com)
- Protocol: Castle (based on the Signal protocol)
- Cyph (cyph.com)
All of the above products use end-to-end encryption (E2EE) by default; however, only Wickr allows anonymous account creation as we do. Wickr, Signal, and Telegram all target a more privacy conscious target group whereas WhatsApp targets a more general, or mainstream, population that merely needs a means of easy communication.
What differentiates the products from one another are in most cases which cryptographic protocol is being used when relaying messages. Wickr, Signal, and Telegram all use their own developed protocol. Signal is open sourced and its protocol is thus used by both WhatsApp and Cyph. All protocols, however, follow certain underlying principles and protocols deriving from best practice guidelines regarding encryption, decryption, storage, and transmission techniques. Our application, Virp, will also be applying some of these techniques in order to enforce E2EE.
Other than protocols, another main difference is the UIs of the products. Virp stands out in the way that it is more minimalistic and simplistic, as well as being the only one where no messages are permanently stored (a default self destruction of 30 days). Out of the ones mentioned, we are also the only browser-based product with anonymous signup. Wickr is anonymous yet not available in the browser, and Cyph is browser-based yet not anonymous. (Anonymous meaning no sign-up via phone number, email account, or other personally identifiable information.) WhatsApp does offer a browser-based version, although it can only be accessed via the mobile application first (one has to start it through the mobile application).
1.4 Technologies
Technologies used in development:
- Node.js
- Event-driven JavaScript runtime
- Express.js
- Library for creating an HTTP server in Node.js
- MongoDB
- NoSQL database
- Socket.io
- Library for real-time communication over the WebSocket protocol
- React.js
- Frontend library for building the UI
- Jest
- JavaScript testing framework
Requirement Specification
2.1 Product Backlog
ID | Category | Item | Description |
---|---|---|---|
Priority: Essential | |||
1 | Usability | Web based | The application can be accessed via a web browser |
2 | Functional | Communication between users | User can send and receive a text-based message to and from another user |
3 | Functional | Log in | User can log in with username and password |
4 | Functional | Sign up | User can sign up with only username and password |
5 | Reliability | E2EE | Messages sent between users are end-to-end encrypted |
6 | Reliability | Store messages encrypted | All stored messages are encrypted |
7 | Reliability | User anonymity | The only user-provided information that is stored in the database are username and password |
8 | Functional | Default self-destruction | Messages stored in the database have a default expiration time of 30 days |
9 | Functional | Self-destructing messages | User can assign a self-destruction timer to a message before sending (min. options: 1min, 5min, 30min, 1h, 6h, 12h, 1d, 7d, 30d) |
10 | Functional | Active chats | User can view a list of currently active chats and remove chats |
11 | Usability | Easy access | Logging in/signing up requires less than 2 navigations from home page |
12 | Usability | Simple and dark theme UI | The UI is spacious, simplistic, minimalistic, and dark themed |
13 | Supportability | Code consistency | The code structure, naming, and syntax choice are consistent throughout the code base |
14 | Reliability | Testing | Automated code coverage on the backend is at least 80% |
15 | Functional | Search users | User can search for another registered user by username |
16 | Functional | Multi-device access | User can log in on different devices and still be able to read previously sent messages |
17 | Functional | Add contacts | User can add another user to its contact list |
18 | Functional | View contacts | User can view its list of contacts |
19 | Functional | Remove contacts | User can remove a user from its contact list |
Priority: Useful | |||
20 | Performance | Speed of unlocking message | User can unlock/decrypt a received message in less than 2 seconds |
21 | Functional | Unread messages notification | The number of unread messages in a chat is visible next to each chat in the active chats list |
22 | Functional | Message information | The date and time received, and time until destruction of each message is visible within an opened chat |
23 | Functional | Block user | User can block a specific user from starting a chat conversation |
24 | Functional | Unblock user | User can unblock a blocked user |
25 | Supportability | Research & documentation | Research and document necessary functionality and info |
Priority: Desirable | |||
26 | Functional | Chat information | Next to each active chat, user can see the time (if same day), day (if same week), or date (if longer than 1 week) of the most recent message |
27 | Functional | Remove account | User can permanently delete its account |
28 | Functional | Change username | User can change username when logged in |
29 | Functional | Change password | User can change password when logged in |
30 | Functional | New message notification | User can be alerted via a notification box when a new message is received |
31 | Functional | Turn on/off notifications | User can turn on/off new message notification |
32 | Usability | Responsiveness | UI is responsive down to 375px width (mobile browsers) |
33 | Functional | Emojis | User can send and receive emojis |
2.2 Use Case Modeling
Figure 1 below is a UML Use Case diagram and illustrates the main functional use cases of the chat application. Do note that these are only dynamic functionalities and, thus, no non-functional or static requirements are shown.
Figure1
Privacy & Security
3.1 End-to-End Encryption Background
When data is sent over the internet it travels through many points in between the source and the destination, such as routers, servers, and devices. This creates vulnerabilities in terms of the privacy and security of the data, and malicious actors may try to access and tamper with the data along the way. Because of this possibility we first make the data unreadable prior to sending it so that in case it ends up somewhere other than our intended destination it becomes useless. Once it arrives safely, the intended receiver (and only the intended receiver) can make that specific data readable again. This is the overall idea of a system that implements end-to-end encryption, or E2EE.
3.2 Overview of the Application’s E2EE System
As stated in section 3.1, end-to-end systems send unreadable, or encrypted, data from one source to another, only to be made readable, or decrypted, by the intended receiver at arrival. This is achieved through asymmetric encryption. In asymmetric encryption systems, different keys are made for encrypting and decrypting data, usually known as private and public keys, in contrast to symmetric encryption which uses the same key for both encryption and decryption. Private keys are for decrypting incoming data whereas public keys are for encrypting data. Each client holds both of these keys. Imagine a box with a lock on it, and a specific key to unlock that specific box. One may view the public key as the box and the private key as the key to the box. You can give the box to anyone who wants to talk to you who then puts their message in that box, locks it, and sends it off. Since you are the only one with the key to unlock the box, you are ideally the only one who can find out what is in it.
To further explain the general idea of E2EE, Figure 2 shows a general overview of how this application implements E2EE. If a client (the sender) wants to send a message to another client (the recipient), the sender first has to obtain the recipient’s public key since that key is used to encrypt the message (lock the box). All public keys are stored in the database and can be retrieved, so the server sends the sender the recipient’s public key, the sender encrypts the message with that key, sends the encrypted message back to the server which then sends it to the recipient who decrypts the message with its private key.
Thus one can see from Figure 2 that only encrypted messages are sent back and forth, leaving the decryption up to each client.
Figure2
3.3 AES and RSA Encryptions
The Advanced Encryption Standard (AES) is an encryption technique that became the US federal standard in 2002 and is now the world standard for encrypting data symmetrically. This encryption technique uses an algorithm called Rijndael that is based on a key of length 128 bits, 192 bits, or 256 bits. The different lengths will determine how many iterations the encryption process will make, making it more secure as the bit length increases. This application is using 128-bit AES which is still considered high standard. 192-bit and 256-bit AES slows down the time to encrypt/decrypt the messages and is often used by governments, military, or organisations handling highly classified information. Since AES is symmetric, the key used for encryption is the same as the key used for decryption.
The RSA algorithm was invented in 1978 by Rivest, Shamir, and Adleman, thereby the name. RSA is one of the most used, if not the most used, asymmetric encryption technique for transferring data securely. This technique requires more computing power than AES encryption and is based on public and private keys (one for encryption, one for decryption) of length 1024 bits, 2048 bits, or 4096 bits. This application is using 2048-bit RSA keys.
3.4 Security Implementations of Client-to-Client Communication
3.4.1 Overview of Creating and Retrieving the RSA Private Key
In order for a user to be able to read any of its messages, the private key belonging to that user needs to reside on the client side as we only want the client to perform the decryption. However, storing the key on the client in, for instance, local storage would not allow it to be stored permanently as it will be deleted if local storage is cleared. A safer and more optimal approach would be storing the private key on the user’s local machine, but this will make for a big decrease in user experience in our case (see section 3.5 for further read). Another approach is to store the private key in the database, but, of course, encrypted client-side so that we maintain our E2EE system. This application uses the latter technique (again, see section 3.5 for understanding potential security threats) using AES and RSA (see section 3.3).
When a user successfully logs in to the application the server needs to send the encrypted private key to the user so that the user can decrypt the private key and then use it for decrypting messages sent from other users. This scenario is only valid if the private key has already been created (at some earlier point in time) and stored in the database. Figure 3 further below walks us through these two either-or scenarios:
The user does not have a private key stored so we generate a public-private key-pair and save it in the database (e.g. at first-time logins) (see 3.4.2 for a text explanation)
The user has already stored a private key so we retrieve it and decrypt it (to use later whenever we want to decrypt a message) (see 3.4.3 for a text explanation).
3.4.2 Scenario: Creating and Storing the RSA Private Key
Upper half of Figure 3: The RSA key-pair is generated on the client using a cryptographic library. The RSA private key needs to be encrypted using AES before it is sent to the server, so an AES key is generated based on the result of hashing and salting the user’s password. Now the client AES encrypts the RSA private key and sends it, along with the public key and salt, to the server which inserts them in the database.
3.4.3 Scenario: Retrieving the RSA Private Key
Lower half of Figure 3: The client requests the encrypted RSA private key and salt from the server which queries the database and returns the result to the client. The client then generates the AES key needed to decrypt the RSA private key by hashing and salting the user’s password with the same algorithm used for creating the AES encryption key (they are the same since it is symmetric). The client now AES decrypts the RSA private key.
Figure3
3.4.4 Sending, Receiving, and Reading Messages
Assuming a client now has its RSA key-pair, a secure communication can be initiated. The box-and-key analogy presented in section 3.2 which describes the usage of public and private keys is illustrated in more detail in Figure 4 as it pertains to this specific application.
Figure 4 shows the scenario of Client1 writing a secret message to Client2. Client2 reads the secret message, writes a secret reply, and sends it back to Client1 who reads the reply. Going from top to bottom, the first block (the “break” block) prevents users from sending or receiving messages from blocked users. The second block (the “opt” block) is triggered if Client1 does not have Client2’s public key, in which case Client1 requests the key from the server who queries it from the database and returns it to the client.
Client1 RSA encrypts the message using Client2’s public key. The encrypted message along with Client1’s public key (later used by Client2 to encrypt the reply) is sent to the server (via the WebSocket protocol). Since the application requires messages to be accessible at a later time on different devices, we also save each encrypted message in the database (for as long as it has not self-destructed). The server passes on the data to Client2 who RSA decrypts the message using its private key. Client2 replies by RSA encrypting the reply with Client1’s public key, sends it to the server who inserts it into the database, then passes it on to Client1. To finish the scenario, Client1 RSA decrypts the reply using its private key.
Figure4
3.5 Security Threats
Some applications are surely more secure than others, however, there is no such thing as guaranteed security or a completely secure piece of software. Possible security threats include for instance: man-in-the-middle attack for intercepting the user’s password on signup and login; a database breach where malicious actor tries to decrypt password in order to try to decrypt the private key (low probability of success); malicious actor gets access to server and tries to decrypt private keys or messages (low probability of success due to E2EE). Even though the private key is well encrypted, from a security point of view it is more optimal to store the key in a file on the user’s local machine or in the operating system’s key store, as compared to in a database accessed by the server. That would prevent it from ever having to leave the client. Although, considering this is a web-based JavaScript application, we cannot automatically read and write to files on the user’s computer without requiring active engagement from the user. Other requirements for this software are an easy-to-use UI and multi-device access, whereby opting for the database was made so as to maintain the UI/UX quality and facilitate being able to read stored messages on different machines while not sacrificing too much security.
Risk Assessment
4.1 Risk Rating Scale
The risk rating scale is based on the probability of the risk occurring and the impact of the risk in the event that it occurs, each on a scale from 1 (very low) to 5 (very high). The assigned risk score (r) is the product of the probability (p) and the impact (i), which could also be used to assign the priority of managing the risk.
Calculate risk score: r = p * i
Probability / Impact | Very Low 1 | Low 2 | Medium 3 | High 4 | Very High 5 |
---|---|---|---|---|---|
Very High 5 | 5 | 10 | 15 | 20 | 25 |
High 4 | 4 | 8 | 12 | 16 | 20 |
Medium 3 | 3 | 6 | 9 | 12 | 15 |
Low 2 | 2 | 4 | 6 | 8 | 10 |
Very Low 1 | 1 | 2 | 3 | 4 | 5 |
Acceptable | Undesirable | Unacceptable | Severe |
---|---|---|---|
green | yellow | orange | red |
4.2 Risks
ID | Short Description | Impact | Probability | Priority | Risk Level |
---|---|---|---|---|---|
1 | Shortage of developers | 5 | 3 | 15 | Severe |
2 | Time estimation errors | 3 | 4 | 12 | Unacceptable |
3 | Time before deadline too short | 4 | 3 | 12 | Unacceptable |
4 | Growth in requirements | 4 | 2 | 8 | Undesirable |
5 | Lack of sufficient experience | 4 | 2 | 8 | Undesirable |
6 | Incorrect prioritization | 4 | 2 | 8 | Undesirable |
7 | Too much time on low priority tasks | 4 | 2 | 8 | Undesirable |
8 | Database malfunction | 5 | 1 | 5 | Acceptable |
9 | Third-party library deprecation | 4 | 1 | 4 | Acceptable |
4.3 Risk Management
ID | Full Description | Monitoring Strategy | Impact Strategy | Probability Strategy |
---|---|---|---|---|
1 | Having a minimal amount of developers creates a very high dependency on very few people | Monitor the health and well-being of the developer(s) | Negotiate with the client about postponing the deadline | Developer(s) should make healthy daily choices |
2 | The estimated time to complete tasks deviates significantly from actual time | Continually monitor the time taken during development | Postpone features to later iterations or versions | Learn from previous iterations and adjust future estimates accordingly |
3 | The time to finish the project with all features is too short | Continually monitor how many features are completed each iteration | Postpone features to later iterations or versions | Utilize the time for each iteration as much as possible |
4 | Time consuming features are added to the list after planning is done | Listen to client’s feedback | Reprioritize the product backlog and modify sprints accordingly | Communicate a lot with the client beforehand to confirm certainty |
5 | Some knowledge needed to develop the software is lacking | Keep track of what technologies will be needed for upcoming sprints | Research solutions, discuss with the client about alternatives | Research the product and technologies needed |
6 | The items in the product backlog is incorrectly prioritized | Continually evaluate if priorities remain the same | Reprioritize the items, postpone items if too much time was lost | Continually evaluate if priorities remain the same |
7 | The time spent on low priority tasks exceeds the reasonable amoun | Continually check whether or not there is time for the low priority task | Refocus on higher priorities, postpone features if needed | Organize sprints so that tasks of higher priority are executed first |
8 | The database stops working or malfunctions | Stay up to date with the database provider | Keep database backups, select a different provider | The database is out of scope for this application |
9 | Central third-party libraries used become deprecated | Stay up to date with the libraries | Have other similar options in mind, version the app | Third-party libraries are out of scope |
Test Specification
5.1 Test Plan
5.1.1 Objective
The testing to be performed will be to ensure a higher degree of quality in the product by validating and verifying certain parts of the application. Additionally, testing is also undertaken in order to expose potential bugs within the system and correct them. Carefully written tests will help conclude if the tested product requirements meet the set expectations or not and could lead to new or modified requirements. The goal in terms of automated tests is to have at least 80% code coverage on the backend.
5.1.2 Requirements to Be Tested
The following table shows what features of the application will be tested (referenced by the requirement ID in the product backlog in section 2.1) and what type of tests are done.
Requirement ID | Item | Type of Test |
---|---|---|
1 | Web based / Accessed through browser | Manual |
2 | Communication between users | Manual |
3 | Log in | Automated |
4 | Sign up | Automated |
6 | Store messages encrypted | Manual |
8 | Default self-destruction of 30 days | Manual |
9 | Assigning self-destruction timers | Automated |
10 | Load active chats | Automated |
11 | Easy access to login/signup pages | Manual |
15 | Search users | Automated |
16 | Multi-device access | Manual |
17 | Add contacts | Automated |
18 | View contacts | Automated |
19 | Remove contacts | Automated |
21 | Unread messages notification | Automated |
23 | Block user | Automated |
24 | Unblock user | Automated |
27 | Remove account | Automated |
30 | New message notification | Manual |
31 | Turn on/off notifications | Automated |
5.1.3 Technologies
Technologies used for testing:
- Jest
- A testing framework used for writing automated tests for JavaScript applications
- jestjs.io
- Supertest
- A library used together with Jest for testing HTTP requests hitting the API endpoints
- github.com/visionmedia/supertest
Future Features
6.1 Potential Upcoming Features
- Group chat
- Encrypted voice calls
- Encrypted video calls
- Image upload
- Burn-on-read setting for messages
- Implementation of the Signal protocol for the E2EE system
- Desktop notifications
- iOS and Android versions
- Desktop version