Skip to content
View DeCastro4code's full-sized avatar

Block or report DeCastro4code

Block user

Prevent this user from interacting with your repositories and sending you notifications. Learn more about blocking users.

You must be logged in to block users.

Maximum 250 characters. Please don’t include any personal information such as legal names or email addresses. Markdown is supported. This note will only be visible to you.
Report abuse

Contact GitHub support about this user’s behavior. Learn more about reporting abuse.

Report abuse
DeCastro4code/README.md

Secure Chat

A WhatsApp-style Flutter app with:

  • End-to-end encryption per contact, via the Signal Protocol (X3DH + Double Ratchet)
  • Encrypted voice/video calls via WebRTC (DTLS-SRTP)
  • Screenshot & screen-recording protection (full block on Android, detect+react on iOS)
  • Firebase for auth/signaling only — your server never sees plaintext or private keys

Project layout

lib/
  main.dart                     — app entry: global screenshot protection, crypto init on cold start
  services/
    crypto_service.dart         — Signal Protocol: identity, prekeys, sessions, encrypt/decrypt
    firestore_service.dart      — all server I/O: prekey bundles, contacts, ciphertext relay, call signaling
    security_service.dart       — screenshot/recording block + detection
    call_service.dart           — WebRTC peer connection setup for calls
    auth_service.dart           — firebase_auth phone sign-in; bootstraps crypto on first sign-in
    local_store.dart            — SQLCipher-encrypted local chat history
  models/models.dart            — Contact, ChatMessage
  screens/
    login_screen.dart           — phone number + SMS code
    contacts_screen.dart        — live contact list, incoming-call listener
    add_friend_screen.dart      — where Signal sessions get established
    chat_screen.dart            — encrypt on send, decrypt on receive, persists locally
    call_screen.dart            — WebRTC UI, handles both caller and callee signaling
android/app/src/main/AndroidManifest.xml   — permissions
ios/Runner/Info-additions.plist.md         — permission strings to merge in

How "only encrypted for added friends" actually works

This isn't just a UI restriction — it's structural:

  1. Each device generates a Signal identity key pair + prekeys (CryptoService.init, called on sign-in and on every cold start via AuthGate in main.dart).
  2. Public prekey bundles get published to Firestore (AuthService._onSignedIn).
  3. Adding a friend (add_friend_screen.dart) fetches their bundle from FirestoreService.fetchPrekeyBundle and runs the X3DH handshake, creating a session in the local Signal store.
  4. encryptMessage()/decryptMessage() require an existing session — there's no code path to encrypt or decrypt for someone you haven't added, because the session simply doesn't exist. Symmetrically, when a friend's first message arrives as a PreKeySignalMessage, decrypting it establishes your side of the session automatically (this is inherent to X3DH — no separate "add back" step is required to reply).

Setup steps to actually run this

  1. Install Flutter (3.19+) and run flutter create . in this directory once, to generate the platform boilerplate this repo doesn't include (ios/Runner/Info.plist, android/build.gradle, etc.) — merge, don't overwrite, since this repo's lib/, pubspec.yaml, and android/app/.../AndroidManifest.xml are already written.
  2. Firebase: create a Firebase project, enable Phone sign-in under Authentication and Cloud Firestore, then run flutterfire configure to generate lib/firebase_options.dart. Uncomment the Firebase.initializeApp line in main.dart.
  3. Firestore security rules: lock these down before shipping — at minimum, a user should only be able to write their own prekey_bundles/{uid} and users/{uid}/contacts/*, and only append (not edit/delete) messages in a chats/{chatId} they're a participant of. The scaffold's rules are permissive by default (whatever your Firebase project ships with) — don't run this in production without writing real rules.
  4. iOS permissions: merge the keys from ios/Runner/Info-additions.plist.md into ios/Runner/Info.plist.
  5. flutter pub get
  6. TURN server: add your TURN credentials in call_service.dart (see caveat below) before testing calls across real networks.
  7. flutter run — test with two devices/accounts to exercise add-friend, messaging, and calling end-to-end.

What's wired up vs. still open

Piece Status
Signal Protocol key generation, session building, encrypt/decrypt Real, functional logic
Firestore signaling: prekey bundles, contacts, message relay, call offer/answer/ICE Wired up (firestore_service.dart)
Phone auth (firebase_auth) Wired up (auth_service.dart, login_screen.dart)
Encrypted text chat end-to-end (send → Firestore → decrypt → persist) Wired up (chat_screen.dart)
Local encrypted message storage (SQLCipher) Wired up (local_store.dart)
WebRTC offer/answer/ICE flow, both caller and callee paths Wired up (call_screen.dart)
Incoming call ringing while not in an open chat Wired up (contacts_screen.dart)
Screenshot/recording protection Real plugin wiring
Firestore security rules Not written — see setup step 3
Screenshot notice sent to the peer (not just shown locally) Not implemented — TODO in chat_screen.dart
Removing/blocking a contact, deleting message history Not implemented
Push notifications for messages/calls while the app is backgrounded Not implemented
Multi-device (same account on phone + desktop) Not implemented — see caveat below

A few honest caveats

  • TURN server: STUN alone (in call_service.dart) won't work for every network. You'll want a TURN server (e.g. coturn, self-hosted or a paid service) for reliable connections behind restrictive NATs — uncomment and fill in the turn: entry in _iceServers.
  • iOS screenshots can't be blocked, only detected — see the note in Info-additions.plist.md.
  • One-time prekey reuse: this scaffold publishes a single prekey (preKeyId: 1) and never rotates it. In production, publish a batch of one-time prekeys and remove each one from the store after a friend consumes it — otherwise multiple people establishing sessions with you concurrently could reuse prekey material, weakening forward secrecy for that first message.
  • Mutual contact add: FirestoreService.addContact adds the contact to both users' lists at once, so the person you add doesn't need a separate "accept" step to see the chat. A production app would probably want an explicit friend-request/accept flow instead.
  • Multi-device support (using the same account on phone + desktop) adds real complexity to the Signal session model — this scaffold assumes one device per user for simplicity (deviceId: 1 throughout).
  • This is a scaffold, not a security audit. Before handling real user data, get the crypto implementation and Firestore security rules reviewed by someone with Signal Protocol / Firebase security experience.

Popular repositories Loading

  1. vscode-java-pack vscode-java-pack Public

    Forked from microsoft/vscode-java-pack

    VS Code extensions for Java developers.

    TypeScript

  2. DeCastro4code DeCastro4code Public

    Config files for my GitHub profile.

    Dart

  3. vscode-data-wrangler vscode-data-wrangler Public

    Forked from microsoft/vscode-data-wrangler

  4. documentation documentation Public

    Forked from AutomaApp/documentation

    Documentation for automa chrome extension

  5. MailRipV3 MailRipV3 Public

    Forked from DrPython3/MailRipV3

    SMTP and IMAP checker / cracker for mailpass combolists with a user-friendly GUI, automated inbox test and many more features.

    Python