A privacy-first web-based period tracker?
Is it even possible?
User Benedicte
Developer Benedicte


Don't be evil
vs.
Can't be evil


Thank you Jeffrey Goldberg!
@jpgoldberg on Twitter
Caveat
Encryption
Cyphertext
KEY
Plaintext
Entropy
A long random sequence of characters has high entropy, a short human memorable password has low entropy.
Encryption in the browser
const key = await window.crypto.subtle.generateKey(
{
name: "AES-GCM",
length: 256
},
true,
["encrypt", "decrypt"]
);Key generation
AES-GCM
Advanced Encryption Standard
with Galois Counter Mode
const note = "A very secret note";
const noteBuffer = new TextEncoder("utf-8").encode(note);
const nonce = window.crypto.getRandomValues(new Uint8Array(12));
const cyphertext = await window.crypto.subtle.encrypt(
{
name: "AES-GCM",
iv: nonce
},
key,
noteBuffer
);Encryption
const plaintext = await window.crypto.subtle.decrypt(
{
name: "AES-GCM",
iv: nonce
},
key,
cyphertext
);
const decoder = new TextDecoder("utf-8")
const decryptedNote = decoder.decode(new Uint8Array(plaintext))
console.log(decryptedNote); // A very secret noteDecryption

Local Storage
const password = "The user's secret password"
const enc = new TextEncoder();
const passwordAsKey = await window.crypto.subtle.importKey(
"raw",
enc.encode(password),
{name: "PBKDF2"},
false,
["deriveBits", "deriveKey"]
);Import key
PBKDF2
Password-Based Key Derivation Function 2
const salt = window.crypto.getRandomValues(new Uint8Array(12));
const key = await window.crypto.subtle.deriveKey(
{
name: "PBKDF2",
salt: salt,
iterations: 100000,
hash: "SHA-256"
},
passwordAsKey,
{ name: "AES-GCM", length: 256},
true,
[ "encrypt", "decrypt" ]
);
Derive key
Password
Salt
Cyphertext
Key
Plaintext
Encryption
Password
Salt
Plaintext
Key
Cyphertext
Decryption
The cloud
End-to-end encryption
Can I use a traditional BaaS
The challenge with traditional authentication
Secure Remote Password
Password
Salt
Cyphertext
Key
Plaintext
Encryption
Password
Salt
Plaintext
Key
Cyphertext
Decryption
Sharing
Cyphertext
KEY
A
Plaintext
KEY
B
Cyphertext
KEY
B
Plaintext
KEY
A
Cyphertext
Public
KEY
Plaintext
Private
KEY
const keyPair = window.crypto.subtle.generateKey(
{
name: "RSA-OAEP",
modulusLength: 4096,
publicExponent: new Uint8Array([1, 0, 1]),
hash: "SHA-256"
},
true,
["encrypt", "decrypt"]
);Key generation
Password
Salt
Encrypted
Private KEY
Key
Private
KEY
Blockstack
Is it possible?
Thank you!
Twitter: @raae
Instagram: @raae.codes
A privacy-first web-based period tracker?
By Benedicte Raae
A privacy-first web-based period tracker?
Slides from Javazone, 2019
- 173