This page provides detailed technical information about the cryptographic mechanisms and data anonymisation used by Pain Recorder.
Pain comments are encrypted client-side before transmission using the Web Crypto API, which is built into all modern browsers.
| Algorithm | RSA-OAEP |
| Key size | 4096-bit |
| Hash function | SHA-256 |
| Encryption location | Client-side (in browser) |
| Server receives | Base64-encoded ciphertext only |
The server acts as a transparent storage layer. It receives the opaque ciphertext and stores it as-is. It never has access to the plaintext content or the encryption key material.
An asymmetric RSA key pair is generated in the browser at registration time:
The
non-extractable
flag is a Web Crypto API feature that makes it impossible for any
JavaScript code (including malicious scripts) to export the raw private
key bytes. The key can only be used for decryption operations through
the browser's built-in cryptographic engine.
The private key never leaves the device. It is not transmitted to the server, not included in API requests, and cannot be extracted from IndexedDB.
User identifiers are pseudonymised before being stored alongside pain records in the time series database:
SHA-256 is a one-way cryptographic hash function. Given the hash output, it is computationally infeasible to recover the original UUID. This limits data correlation if the time series database is ever compromised.
All communication uses HTTPS (TLS). WebAuthn authentication requires HTTPS in production, ensuring that all data — including already-encrypted comments — is protected by an additional transport-layer encryption.
The server stores the following data in its time series database:
| Field | Format | Readable? |
|---|---|---|
| Pain level | Integer (0–4) | Yes (low sensitivity) |
| Timestamp | UTC microseconds | Yes |
| Comment | Base64 ciphertext | No |
| User identity | SHA-256 hash | No |
Pain Recorder is fully open source under the BSD licence. You can audit every line of code yourself.
View the source code on GitLab →