--- tags: Encryption --- # Implementatie Encryption This implementation is an example for a private chat using the signal protocol. ? What to do with login? For now: ## 0. Setting up an account on Device (User A) - [x] When registering account needs to get unique ID - Email & username for userscomfort - Internally everything **uID** - Server needs to save **uID, email & password**? - ``` // **Deze bovenste hebben wij zelf al** const registrationId = KeyHelper.generateRegistrationId(); // Store registrationId somewhere durable and safe... Or do this. storeSomewhereSafe(store)(`registrationID`, registrationId); ``` - [ ] Device generates Unique Identity keypair - ``` export interface KeyPairType<T = ArrayBuffer> { pubKey: T privKey: T } export class Keyhelper { static generateIdentityKeyPair(): Promise<KeyPairType> { return Internal.crypto.createKeyPair() } } ``` - ``` const identityKeyPair = await KeyHelper.generateIdentityKeyPair(); // Store identityKeyPair somewhere durable and safe... Or do this. storeSomewhereSafe(store)("identityKey", identityKeyPair); ``` - **privKey stored safely** - [ ] Device generates one-time use prekey and a signed pre-key, storing both locally - ``` const baseKeyId = Math.floor(10000 * Math.random()); const preKey = await KeyHelper.generatePreKey(baseKeyId); store.storePreKey(`${baseKeyId}`, preKey.keyPair); const signedPreKeyId = Math.floor(10000 * Math.random()); const signedPreKey = await KeyHelper.generateSignedPreKey( identityKeyPair, signedPreKeyId ); store.storeSignedPreKey(signedPreKeyId, signedPreKey.keyPair); ``` - [ ] Upload associated public keys and signatures to server so other users can access them. - ``` const publicSignedPreKey: SignedPublicPreKeyType = { keyId: signedPreKeyId, publicKey: signedPreKey.keyPair.pubKey, signature: signedPreKey.signature, }; // Now we register this with the server so all users can see them const publicPreKey: PreKeyType = { keyId: preKey.keyId, publicKey: preKey.keyPair.pubKey, }; directory.storeKeyBundle(name, { registrationId, identityPubKey: identityKeyPair.pubKey, signedPreKey: publicSignedPreKey, oneTimePreKeys: [publicPreKey], }); ``` ## 1. Setting up a session (User A to User B) - [ ] First thing is look up B on server and get prekey bundle. - ``` // get Brünhild's key bundle const brunhildeBundle = directory.getPreKeyBundle("brünhild"); ``` - [ ] Build signal session for this recipient in our local store - ``` const recipientAddress = new SignalProtocolAddress("brünhild", 1); // Instantiate a SessionBuilder for a remote recipientId + deviceId tuple. const sessionBuilder = new SessionBuilder(adalheidStore, recipientAddress); ``` - [ ] Now we can use this session to process the prekey bundle for this session. - ``` // Process a prekey fetched from the server. Returns a promise that resolves // once a session is created and saved in the store, or rejects if the // identityKey differs from a previously seen identity for this address. await sessionBuilder.processPreKey(brunhildeBundle!); - [ ] With the session built, we are ready to create a SessionCipher and encrypt a message. We'll just send a fixed first message, starterMessage, here but it could be any message you like. Since it is the first message in the session, it will be a PreKeyWhisperMessage. - ``` const starterMessageBytes = Uint8Array.from([ 48, 61, 6c, 6c, 6f, 21 ]); // Now we can send an encrypted message const adalheidSessionCipher = new SessionCipher( adalheidStore, recipientAddress ); const ciphertext = await adalheidSessionCipher.encrypt( starterMessageBytes.buffer ); `` - [ ] Finaly we send it over whatever channel we like. - ``` sendMessage("brünhild", "adalheid", ciphertext); ``` ## 2. A stuurt B nog een bericht - [ ] First, we create a new SessionCipher for the recipient using our local store. - ``` const cipher = SessionCipher(store, recipientAddress); }; ``` - [ ] Then we can encrypt the message, this time producing a WhisperMessage. - ``` const ciphertext = await cipher.encrypt( new TextEncoder().encode(message).buffer); ``` - [ ] And now we can send the message over any channel we like, Here to and from are addresses strings. - ``` sendMessage(to, from, ciphertext); }; ```