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:
- Gizli açar — yalnız cihazda qalır
- Açıq açar — Firebase üzərindən mübadilə edilir
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:
- Firestore sənədində saxlanılan həqiqi açıq açarları öz açarları ilə əvəz etməlidir
- 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:
- Cihazların gizli açarlarını bilmir
- SHA-256 geri çevrilə bilən deyil
- Təsadüfi uyğunluq ehtimalı cəmi 100-də 1-dir
İ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:
- A 64 simvollu qoşalaşdırma açarı (256 bit) ortaq sirdən əldə edilir:
SHA-256("pair:" + sharedSecret) → pairingKey - Sənəd açarı
SHA-256("doc:" + pairingKey)kimi əldə edilir və Firestore sənəd açarı kimi istifadə olunur - Ş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 - 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ı:
- WebRTC cihazdan cihaza (qalın xətt): Səs, video və DataChannel birbaşa cihazlar arasında ötürülür — DTLS-SRTP ilə şifrələnir. Heç bir server bu məlumatı görmür.
- Firebase Firestore (düz xətt): Qoşalaşdırma məlumatları (ECDH açarları) və siqnallaşma (SDP/ICE) Firestore üzərindən keçir — AES-256-GCM ilə başdan-başa şifrələnir. Firebase məlumatların şifrəsini aça bilmir.
- STUN serveri: Birbaşa cihazdan-cihaza əlaqə qurmaq üçün hər iki cihaz öz açıq IP ünvanını aşkar edir.
- TURN relesi: Birbaşa əlaqə mümkün olmadıqda (məsələn, mobil internetdə), seçilmiş yerli və ya Cloudflare TURN serveri şifrələnmiş medianı ötürür. Qısa müddətli giriş məlumatları (24 saat) Firebase Cloud Functions vasitəsilə alınır.
- Bluetooth LE (nöqtəli xətt): Nearby Connections yaxınlıqdakı cihazları avtomatik aşkar edir — yalnız görüş kodu ötürülür, açar materialı yox.
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ı.