Bloq

Baby Monitor Timmy-də təhlükəsiz qoşalaşdırma

ECDH, SAS nömrəsi və şifrələnmiş siqnallaşmanın necə birlikdə işlədiyi.

Baby Monitor Timmy səs və videonu ötürməzdən əvvəl iki cihaz bir-birini tapmalı və bir-birinə etibar etməlidir. Bu qoşalaşdırma mərhələsi bütün prosesin ən vacib anıdır. Burada Timmy-nin necə qoşalaşdırıldığını, bunun arxasında hansı kriptoqrafiyanın dayandığını və yaxınlıqdakı hücumçunun əlaqəni gizlicə ələ keçirə bilmədiyini izah edirəm.

Problem: Cihazım kimlə danışdığını necə bilir?

İki cihaz ilk dəfə qoşulanda əsas sual budur: A cihazı həqiqətən B cihazı ilə danışır, yoxsa arada kimsə var? Kriptoqrafiyada buna ortadakı adam hücumu (MITM) deyilir.

Timmy bunu Firebase üzərindən aparılan Elliptik Əyri Diffie-Hellman (ECDH) açar mübadiləsi ilə istifadəçinin vizual yoxlamasını.

birləşdirərək həll edir. Aşağıdakı diaqram bütün qoşalaşdırma prosesini bir baxışda göstərir:

sequenceDiagram
    autonumber
    participant A as 📱 Device A
    participant F as ☁️ Firebase
    participant B as 📱 Device B

    Note over A,B: Phase 1 — Discovery

    A->>A: Generate ECDH key pair (P-256)
    B->>B: Generate ECDH key pair (P-256)

    alt Auto-Pairing (Nearby BLE)
        A-->>B: BLE broadcast: SBM:XKQM
        B-->>A: BLE broadcast: SBM:R7NP
        Note over A,B: Lower code wins → determines creator/joiner
    else Manual Pairing
        A->>A: Display 4-char code
        Note right of A: User reads code
        B->>B: User enters code
    end

    Note over A,B: Phase 2 — ECDH Key Exchange

    A->>F: Write public key (PubA) to meeting doc
    B->>F: Write public key (PubB) to meeting doc
    F-->>B: Read PubA
    F-->>A: Read PubB

    Note over A,B: Phase 3 — Shared Secret

    A->>A: sharedSecret = ECDH(privA, PubB)
    B->>B: sharedSecret = ECDH(privB, PubA)
    Note over A,B: Both compute identical 32-byte secret

    A->>A: SAS = SHA-256("sas:" + sort(PubA,PubB) + secret) → 2-digit number
    B->>B: SAS = SHA-256("sas:" + sort(PubA,PubB) + secret) → 2-digit number

    Note over A,B: Phase 4 — Visual Verification

    A->>A: Display SAS: 42
    B->>B: Display SAS: 42
    Note over A,B: 👤 User compares numbers on both screens

    A->>A: User confirms ✓
    B->>B: User confirms ✓

    Note over A,B: Phase 5 — Key Derivation

    A->>A: pairingKey = SHA-256("pair:" + secret)
    B->>B: pairingKey = SHA-256("pair:" + secret)
    A->>A: docKey = SHA-256("doc:" + pairingKey)
    A->>A: encKey = SHA-256("enc:" + pairingKey)

    Note over A,B: ✅ Paired — all future signaling encrypted with AES-256-GCM
      

Tam qoşalaşdırma protokolu ardıcıllığı — redaktə edilə bilən mənbə: docs/diagrams/pairing-sequence.mmd

Addım 1: Hər cihaz açar cütü yaradır

Qoşalaşdırma ekranı açıldıqda hər cihaz müvəqqəti ECDH açar cütü P-256 əyrisi (secp256r1) üzərində yaradır:

Açarlar kriptoqrafik cəhətdən təhlükəsiz təsadüfi ədəd generatoru (Random.secure()) ilə yaradılır və yalnız bu bir qoşalaşdırma cəhdi üçün keçərlidir. Hər yeni cəhd üçün yeni açarlar yaradılır.

Addım 2: Açıq açarların Firebase üzərindən mübadiləsi

İki cihazın bir-birini tapması üçün Timmy 4 simvollu koddan görüş nöqtəsi kimi istifadə edir. Bu kod Nearby Connections (Bluetooth Low Energy) vasitəsilə avtomatik aşkar edilə və ya əl ilə daxil edilə bilər. Onun heç bir kriptoqrafik dəyəri yoxdur; sadəcə hər iki cihazın eyni Firebase Firestore sənədini tapmasına kömək edir.

Hər iki cihaz kodu bildikdən sonra hər biri öz açıq ECDH açarını ortaq Firestore sənədinəyazır. Sonra hər cihaz həmin sənəddən digər cihazın açıq açarını oxuyur.

Vacib məqam: yalnız açıq açar göndərilir. Gizli açar cihazdan heç vaxt çıxmır. Firebase trafikinə baxan hər kəs açıq açarları görür, lakin onlardan ortaq sirri hesablaya bilməz Bu, Elliptik Əyri Diskret Loqarifm Probleminin (ECDLP) çətinliyinə əsaslanır.

Addım 3: Ortaq sirrin hesablanması

Hər iki cihaz bir-birinin açıq açarını aşkar etdikdən sonra müstəqil şəkildə eyni ortaq sirri:

sharedSecret = ECDH(myPrivateKey, remotePublicKey)
             → 32 bytes (identical on both devices)

hesablayır. Elliptik əyrilərin riyaziyyatı hər cihazın yalnız öz gizli açarını və digərinin açıq açarını bilməsinə baxmayaraq, hər iki hesablamanın eyni nəticəni verməsini təmin edir.

Addım 4: Yoxlama nömrəsi (SAS)

Ortaq sirdən Qısa Doğrulama Sətri (SAS) — hər iki cihazda göstərilən iki rəqəmli nömrə — əldə edilir:

hash   = SHA-256("sas:" + sort(pubkeyA, pubkeyB) + sharedSecret)
number = (hash[0] × 256 + hash[1]) mod 100   → 00 to 99

Hər iki cihaz eyni nömrəni göstərir — məsələn, 42. İstifadəçi hər iki ekrandakı nömrələrin eyni olub-olmadığını gözlə müqayisə edir, sonra hər cihazda ayrıca təsdiqləyir.

Niyə hücumçu bunu saxtalaşdıra bilmir

Ortadakı adam Firebase-dəki açar mübadiləsinə müdaxilə etməlidir. Bunun üçün o:

  1. Firestore sənədində saxlanılan həqiqi açıq açarları öz açarları ilə əvəz etməlidir
  2. Hər cihazla ayrıca ortaq sirr yaratmalıdır
sequenceDiagram
    autonumber
    participant A as 📱 Device A
    participant M as 🕵️ Attacker (MITM)
    participant B as 📱 Device B

    Note over A,B: Attacker intercepts the Firebase key exchange

    A->>A: Generate key pair (privA, PubA)
    B->>B: Generate key pair (privB, PubB)
    M->>M: Generate TWO key pairs (privM1, PubM1) + (privM2, PubM2)

    A->>M: Write PubA to Firebase
    M->>M: Replace PubA with PubM1
    M->>B: B reads PubM1 (thinks it is PubA)

    B->>M: Write PubB to Firebase
    M->>M: Replace PubB with PubM2
    M->>A: A reads PubM2 (thinks it is PubB)

    Note over A,B: Each device computes a DIFFERENT shared secret

    A->>A: secret_A = ECDH(privA, PubM2)
    M->>M: secret_A = ECDH(privM2, PubA)
    M->>M: secret_B = ECDH(privM1, PubB)
    B->>B: secret_B = ECDH(privB, PubM1)

    Note over A,M: secret_A ≠ secret_B

    A->>A: SAS_A = SHA-256("sas:" + sort(PubA,PubM2) + secret_A) → 73
    B->>B: SAS_B = SHA-256("sas:" + sort(PubM1,PubB) + secret_B) → 18

    rect rgb(255, 230, 230)
        Note over A,B: ❌ User sees DIFFERENT numbers!
        A->>A: Display: 73
        B->>B: Display: 18
        Note over A,B: 👤 User notices mismatch → cancels pairing
    end

    Note over A,B: 🛡️ Attack detected — MITM cannot force SAS match (P = 1/100)
      

SAS uyğunsuzluğu ilə ortadakı adam hücumunun aşkarlanması — redaktə edilə bilən mənbə: docs/diagrams/mitm-detection.mmd

Bu halda hücumçu bir ortaq sirri S_A A cihazı ilə, başqa bir ortaq sirri isə S_B B cihazı ilə hesablayır. Bu sirlər fərqli olduğuna görə S_A ≠ S_Bcihazlar fərqli yoxlama nömrələri hesablayır..

hesablayır. Hücumçu nömrələri eyniləşdirə bilmir, çünki:

İstifadəçi ekranlarda fərqli nömrələr görür və qoşalaşdırmanı ləğv edir. Həmin anda hücum görünən olur.

Addım 5: Qoşalaşdırmanın tamamlanması

Yalnız istifadəçi yoxlamanı hər iki cihazda təsdiqlədikdən sonra qoşalaşdırma tamamlanır:

  1. A 64 simvollu qoşalaşdırma açarı (256 bit) ortaq sirdən əldə edilir: SHA-256("pair:" + sharedSecret) → pairingKey
  2. Sənəd açarı SHA-256("doc:" + pairingKey) kimi əldə edilir və Firestore sənəd açarı kimi istifadə olunur
  3. Şifrələmə açarı SHA-256("enc:" + pairingKey) kimi əldə edilir və şifrələnmiş siqnallaşma üçün AES-256-GCM açarını təmin edir
  4. Hər iki cihaz eyni qoşalaşdırma açarını saxlayır və rejim seçiminə keçir

Bu andan etibarən bütün sonrakı qoşulma cəhdləri (Firestore siqnallaşması, WebRTC quraşdırması) ortaq AES-256-GCM açarı ilə şifrələnir. Qoşalaşdırma açarı heç vaxt backend-ə göndərilmir; sənəd identifikatoru kimi yalnız onun SHA-256 heşi istifadə olunur.

Sistem arxitekturası

Aşağıdakı diaqram qoşalaşdırma və rabitədə iştirak edən komponentləri göstərir:

flowchart TB
    BABY["📱 Baby Phone
Baby Mode"] PARENT["📱 Parent Phone
Parent Mode"] BABY <==>|"🔒 WebRTC Peer-to-Peer · DTLS-SRTP
Audio · Video · DataChannel"| PARENT BABY -.-|"🔵 Bluetooth LE · Nearby
Auto-Discovery"| PARENT subgraph FIREBASE["☁️ Firebase (Google Cloud)"] direction LR AUTH["🪪 Anonymous
Authentication"] FS["📄 Firestore
Pairing + Signaling"] CF["⚡ Cloud Functions
getTurnCredentials"] end BABY <-->|"🔐 AES-256-GCM encrypted
SDP · ICE · ECDH keys"| FS FS <-->|"🔐 AES-256-GCM encrypted
SDP · ICE · ECDH keys"| PARENT BABY -.->|Token| AUTH PARENT -.->|Token| AUTH STUN["📡 STUN server
stun.cloudflare.com:3478"] TURN["🔄 TURN relay
local or Cloudflare"] BABY & PARENT -->|Short-lived credentials| CF CF -->|local first, Cloudflare fallback| TURN BABY & PARENT -.->|NAT Traversal| STUN BABY -.->|"Relay Fallback"| TURN TURN -.->|"Relay Fallback"| PARENT style BABY fill:#FBF6F0,stroke:#B5734A,stroke-width:2px style PARENT fill:#FBF6F0,stroke:#B5734A,stroke-width:2px style FIREBASE fill:#fff5f5,stroke:#E9B44C,stroke-width:2px style AUTH fill:#E9B44C,stroke:#2B2D42 style FS fill:#E9B44C,stroke:#2B2D42 style CF fill:#E9B44C,stroke:#2B2D42 style STUN fill:#F6E3D2,stroke:#B5734A style TURN fill:#7BC47F,stroke:#2B2D42

Sistem arxitekturasına ümumi baxış — redaktə edilə bilən mənbə: docs/diagrams/pairing-architecture.mmd

Rabitə yolları ətraflı:

Alternativ: Kodu əl ilə daxil etmə

Bluetooth əlçatan olmadıqda (məsələn, köhnə cihazlarda), 4 simvollu kod əl ilə də daxil edilə bilər. Əl ilə daxil etmədə eyni ECDH açar mübadiləsi və eyni SAS yoxlaması avtomatik qoşalaşdırmadakı kimi istifadə olunur. Yeganə fərq odur ki, kod BLE vasitəsilə aşkar edilmək əvəzinə istifadəçi tərəfindən oxunur və yazılır.

Hər iki halda ECDH açar mübadiləsi Firebase üzərindən aparıldığından təhlükəsizlik eynidir. 4 simvollu kod yalnız görüş nöqtəsidir; həqiqi şifrələmə ECDH-dən əldə edilən 256 bitlik açara əsaslanır.

Xülasə

Təhlükəsizlik mexanizmi Nədən qoruyur
ECDH açar mübadiləsi (P-256) Açar mübadiləsi trafikinə qulaq asmaqdan
Müvəqqəti açar cütləri İrəliyə yönəlmiş məxfilik — əvvəlki qoşalaşdırmalar təhlükəsiz qalır
Vizual yoxlama nömrəsi (SAS) Açar mübadiləsi zamanı ortadakı adam hücumundan (MITM)
Sənəd açarı kimi SHA-256 heşi Firestore-dan kodun çıxarılmasından
AES-256-GCM şifrələməsi Siqnallaşma məlumatlarına qulaq asmaqdan
Hər iki tərəfin təsdiqi İstifadəçi xəbəri olmadan birtərəfli qoşalaşdırmadan
DTLS-SRTP (WebRTC) Səs/videoya qulaq asmaqdan

Bu qatlar birlikdə işləyir: ECDH açar mübadiləsini, yoxlama nömrəsi MITM hücumunu, AES-256-GCM siqnallaşmanı, WebRTC isə medianı qoruyur. Hücumçu cihazlar və ya valideynlər bunu hiss etmədən bu zənciri bir neçə yerdən qırmalı olardı.


Daha çox məqalə