PoC e2ee of data with PGP in python and JavaScript
Go to file
Andrea Blankenstijn 8242c77a51 add license 2021-05-15 12:08:20 +02:00
.gitignore initial commit with WiP code 2021-01-01 12:40:42 +01:00
LICENSE add license 2021-05-15 12:08:20 +02:00
README.md README update 2021-01-18 08:57:54 +01:00
admin.html fix reencrypt 2021-01-10 16:45:08 +01:00
config.js default front SRV to document.location.host 2021-01-17 09:02:48 +01:00
data.html basic features working (?) 2021-01-08 19:26:38 +01:00
database.py basic features working (?) 2021-01-08 19:26:38 +01:00
forms.html basic features working (?) 2021-01-08 19:26:38 +01:00
public.js basic features working (?) 2021-01-08 19:26:38 +01:00
register.html basic features working (?) 2021-01-08 19:26:38 +01:00
registered.js basic features working (?) 2021-01-08 19:26:38 +01:00
server.py Format python with black 2021-02-07 17:45:48 +01:00
websocket.py Format python with black 2021-02-07 17:45:48 +01:00

README.md

PoC WebSocket PGP JSON

This PoC shows a way to encrypt e2e data collected from forms for one or more users using PGP

Requirements

  • Recent Python 3
  • Python 3 binding for GPGME (python3-gpg)
  • OpenPGP.js (openpgp.min.js)

Run

./server.py [port] [listen address] [datadir]

  • default port: 8000
  • default listen address: 127.0.0.1
  • default data directory: random temporary one and in memory database

If you are running the server on a different address/port than the default one, you have to edit config.js SRV constant.

Once the server is running you can browse:

  1. Server root (/) to generate user keys and upload the public key to the server. First one is admin.
  2. /admin.html to set forms keys for encryption and reencrypt data after keys change.
  3. /forms.html to collect data.
  4. /data.html to view collected data.

Protocol brief overview

API request from registered users

  1. Client fetch the server public key (for this particular step we assume the link is secure)
  2. Client encrypt with server key and sign with its own key a JSON of the format { request: "api/request", payload: "optional payload" } and send it over WebSocket
  3. Server checks if it knows the client key. Then answer with the same JSON but without payload with an added random nonce encrypted for client and signed.
  4. Client checks if the JSON request field is the same and server signature is valid. Then sign and encrypt the message with the nonce and send it back to the server.
  5. Server checks if the nonce is the same and the signature from the client is valid and recent enough and then execute the request and answer it if needed and close the connection.

Public request

Simply done over basic HTTP with fetch. Again we trust that the link is secure

Notable missing feature

On key deletion there is no notification that data may needs to be reencrypted.