Skip to main content
Image
Webscreen - End to End Encryption

Implementing Secure Messaging with WebScreen: An End-to-End Encrypted Solution

In today's digital age, privacy and security have become paramount. Inspired by Telegram's robust end-to-end encryption protocol, we are excited to introduce a new feature for WebScreen that allows users to send and receive secret messages securely. This feature leverages Cloudflare Workers for serverless architecture, Node.js for encryption, and Electron for cross-platform applications. Here’s a detailed breakdown of how this functionality is implemented.

Overview

The WebScreen feature enables users to send encrypted messages to a remote webscreen. These messages are encrypted on the sender's side, transmitted securely, and decrypted only on the receiver's end. The process ensures that no intermediaries can access the message content.

Key Components

Serverless Architecture with Cloudflare Workers: Provides a scalable, low-latency backend.

Client Applications: Built with Node.js and Electron, ensuring cross-platform compatibility.

WebSocket Communication: For real-time message delivery.

End-to-End Encryption: Based on Telegram’s MTProto protocol for secure message transmission.

Technical Architecture

1. Cloudflare Workers

Cloudflare Workers are used to handle API requests for sending and receiving messages. This serverless approach offers a scalable and cost-effective solution.

2. Node.js and Electron

Node.js is used for encryption and decryption processes, while Electron ensures the application can run on multiple platforms (Windows, macOS, and Linux).

3. WebSocket Communication

WebSockets are employed for real-time communication between the client application and the webscreen. This ensures instant delivery and display of messages.

4. Encryption Protocol

We utilize Telegram’s MTProto 2.0 protocol, which offers robust security features such as Perfect Forward Secrecy and secure key exchange mechanisms.

Implementation Details

Setting Up Cloudflare Workers

First, we set up Cloudflare Workers to create endpoints for handling message requests. Here’s a simplified version of the worker script:

addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request));
});

async function handleRequest(request) {
  const { pathname } = new URL(request.url);

  if (pathname.startsWith('/send')) {
    return handleSendMessage(request);
  } else if (pathname.startsWith('/receive')) {
    return handleReceiveMessage(request);
  }

  return new Response('Not Found', { status: 404 });
}

async function handleSendMessage(request) {
  // Handle sending message logic
}

async function handleReceiveMessage(request) {
  // Handle receiving message logic
}

Encryption and Decryption

Key Generation

Using Diffie-Hellman key exchange to generate a shared secret key:

const crypto = require('crypto');

function generateKeys() {
  const { publicKey, privateKey } = crypto.generateKeyPairSync('dh', {
    primeLength: 2048,
  });

  return { publicKey, privateKey };
}

function computeSharedSecret(privateKey, otherPublicKey) {
  return privateKey.computeSecret(otherPublicKey);
}
 

Encrypting Messages

function encryptMessage(sharedKey, message) {
  const iv = crypto.randomBytes(16);
  const cipher = crypto.createCipheriv('aes-256-cbc', sharedKey, iv);
  let encrypted = cipher.update(message, 'utf8', 'hex');
  encrypted += cipher.final('hex');
  return { iv: iv.toString('hex'), encrypted };
}

function decryptMessage(sharedKey, iv, encrypted) {
  const decipher = crypto.createDecipheriv('aes-256-cbc', sharedKey, Buffer.from(iv, 'hex'));
  let decrypted = decipher.update(encrypted, 'hex', 'utf8');
  decrypted += decipher.final('utf8');
  return decrypted;
}

Client Application with Electron

Setting Up Electron

const { app, BrowserWindow } = require('electron');
const path = require('path');

function createWindow() {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'),
    },
  });

  win.loadFile('index.html');
}

app.on('ready', createWindow);
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit();
  }
});
app.on('activate', () => {
  if (BrowserWindow.getAllWindows().length === 0) {
    createWindow();
  }
});

Handling WebSocket Communication

const WebSocket = require('ws');
const ws = new WebSocket('ws://webscreen-address');

ws.on('open', () => {
  console.log('Connected to WebScreen');
});

ws.on('message', (data) => {
  const { iv, encrypted } = JSON.parse(data);
  const decryptedMessage = decryptMessage(sharedKey, iv, encrypted);
  displayMessage(decryptedMessage);
});

function sendMessage(message) {
  const { iv, encrypted } = encryptMessage(sharedKey, message);
  ws.send(JSON.stringify({ iv, encrypted }));
}
 

WebScreen Integration

Initial Display with GIF

const lvgl = require('lvgl');
const rm67162 = require('rm67162');
const { notification } = require('./notification');

function setupDisplay() {
  rm67162.init();
  const gif = lvgl.createGif(notification);
  lvgl.align(gif, lvgl.ALIGN.CENTER);
  lvgl.show(gif);
}

setupDisplay();

Displaying Received Messages

ws.on('message', (data) => {
  const { iv, encrypted } = JSON.parse(data);
  const decryptedMessage = decryptMessage(sharedKey, iv, encrypted);

  lvgl.hide(gif);
  const label = lvgl.createLabel(decryptedMessage);
  lvgl.align(label, lvgl.ALIGN.CENTER);
  lvgl.show(label);
});

Conclusion

By leveraging Cloudflare Workers, Node.js, Electron, and Telegram’s MTProto protocol, WebScreen ensures secure and efficient messaging. This implementation guarantees that messages remain private and are only accessible by the intended recipient, offering robust end-to-end encryption.

For more detailed information on the encryption process, you can refer to the Telegram End-to-End Encryption documentation.

This feature not only enhances the security of WebScreen but also provides users with a seamless and intuitive way to send and receive secret messages. Stay tuned for more updates as we continue to enhance our platform’s security and functionality.