Transmit sensitive data throughout your organization using PGP (with the help of the openpgp.js library)
Some organizations need to transmit sensitive data between their departments/users. Such data may be personal details, work evaluation or even medical conditions. It is important for such data to be delivered and be seen only by its recipient and not by anybody else.
One true and tested way for such data transmission is to use GPG. The data will be encrypted with the recipient's public key and only the recipient, using his private key will be able to decrypt and read it.
PGP is an old protocol that works fine with email and even after all these years if it considered by security experts as extremely secure. However it is heavily criticized because it is difficult to use properly leading to security breaches due to usage errors. Also, in order to properly use it and avoid mistakes the PGP user must understand some things about how the public key cryptography is working. This is not an easy task for the non technical user.
This web application wants to build on PGP's security but also offer a simple enough work flow to minimize errors and security breaches even for less security aware users.
The app contains a bunch of authorities each one with a bunch of users. Each authority that wants to receive data will need to generate a Private/Public key Pair which will then need to get the administration to approve using some OOB communication. Only the public key of the pair will be saved to the server. The private key and its encryption passphrase are saved only client side.
After the public key is approved the authority can receive data. The data is encrypted with its public key using OpenPGP.js on the client side and only the cipher (not the original data) is saved to the server. Since the original data never reaches the server we can be sure that even if the server was compromised somehow no sensitive data would be breached.
When a user of the receiving authority logs in he can choose to submit the authority private key so it can be used to decrypt the authority data.
If your server is compromised, the client-side (JS) code could be changed so it transmits the private key of the users over the network when they unlock it. This way the malicious user will get access to the data of all the users that unlock their key while the backdoor is undetected.
This can be resolved by using self-contained binaries that interact with the service and have their signature published.
This is a rather simple Django application. It has no external dependencies beyond Django and a database. You can even use sqlite3 if you wanted but I'd recommend something like Postgresql. All other dependencies are django packages that can be installed through the requirements/*.txt (there are different files for dev/uat/prod).
Here's how I would install this for a dev environment:
E:\>mkdir etsd
E:\>cd etsd
E:\etsd>py -3 -m venv venv
E:\etsd>venv\Scripts\activate
(venv) E:\etsd>git clone https://github.com/spapas/etsd
(venv) E:\etsd\etsd>pip install c:\Users\serafeim\Downloads\python_ldap-3.3.1-cp38-cp38-win32.whl
Processing c:\users\serafeim\downloads\python_ldap-3.3.1-cp38-cp38-win32.whl
[...]
(venv) E:\etsd\etsd>pip install -r requirements\dev.txt
Collecting crispy-bootstrap5==0.4 (from -r requirements\base.txt (line 1))
[...]
set DJANGO_SETTINGS_MODULE=etsd.settings.dev
copy local.py.template local.py
[Edit the local.py file and ldap_conf.py with your preferences]
E:\etsd\etsd>cd etsd\settings
dj migrate
dj createsuperuser
[...]
rsp
Now you can visit http://127.0.0.1:8000 and login with the superuser credentials.
If you see any errors during the requirements installation make sure that you are using the latest version of pip.
To install it for a production environment you can follow the instructions for any python/django web app.
You can override the templates used in this project by adding the corresponding files in the etsd/branding/template
folder. I've added a project that can be cloned in the etsd
folder (by removing the existing branding
folder) to keep my changes under version control.
Let's see how this works in practice. Please notice that all the following screens have much helpful text for the end user that should guide him properly in his actions. I am not including it here to keep the images a little smaller.
Suppose you have two deparments, HR and Marketing. Marketing would like to send some encrypted data to HR.
For starters, the HR must generate his key pair in order to be able to receive data:
The home screen after a user has logged in is this:
He enters his keyphrase, downloads the private key and presses submit to save the public key to the server. Only the public key will be saved to the server. The keyphrase is needed to encrypt the generated private key that he must then download to his computer:
He loads the private key to his session by using the Load Private Key option:
After submitting the private key file and passphrase both are saved to his browser (using local storage, they are not submitted to the server):
Now he can submit his key for approval to the administrators along with a proper document (the public key that will be submitted is validated with the loaded private key before sending it to make sure that the user has not made some mistake):
The public key must be approved by an administrator before it can be used to encrypt data.
After the public key is approved, the marketing user can send his data. First he selects the Messages list:
And starts a new Message where he selects the HR department as a recipient:
The new message is created as a draft (which can be deleted is something was wrong):
In order to send the message, the marketing user must add some data to it. The user just selects the files one by one. Each file is encrypted client-side and only the cipher is uploaded to the server. If there are mutliple receivers the message will be encrypted mutliple times, once for each receiver's public key.
After the user finished uploading the data he can send the message:
Now the HR user will receive an email informing him that he just got a new encrypted message.
He logs in to the app and sees the message in his message list:
He clicks the message id to see its data but he is not able because he has not loaded his private key:
He then loads his private key to his browser following the same procedure as before and now he is able to actually decrypt the data. Once again, the data is downloaded as a cipher and it is decrypted in his computer using his private key locally:
After he has downloaded and decrypted all the message data the message status is changed to Read and he can archive it:
He could also delete the cipher data from the server completely if he choses. The message will not be deleted but the data that was encrypted with his public key will be completely removed.