بلاگ

Baby Monitor Timmy میں محفوظ جوڑا بنانا

ECDH، SAS نمبر، اور خفیہ سگنلنگ ایک ساتھ کیسے کام کرتے ہیں۔

Baby Monitor Timmy آڈیو اور ویڈیو بھیجنے سے پہلے، دونوں ڈیوائسز کو ایک دوسرے کو ڈھونڈنا اور ایک دوسرے پر بھروسا کرنا ہوتا ہے۔ یہ جوڑا بنانے کا مرحلہ پورے عمل کا سب سے اہم لمحہ ہے۔ یہاں میں بتاتا ہوں کہ Timmy جوڑا کیسے بناتا ہے، اس کے پیچھے کون سی کرپٹوگرافی ہے، اور قریب موجود حملہ آور کو کنکشن پر خاموشی سے قبضہ کرنے سے کیوں روکا جاتا ہے۔

مسئلہ: میری ڈیوائس کو کیسے معلوم ہو کہ وہ کس سے بات کر رہی ہے؟

جب دو ڈیوائسز پہلی بار جڑتی ہیں تو بنیادی سوال یہ ہوتا ہے: کیا ڈیوائس A واقعی ڈیوائس B سے بات کر رہی ہے، یا کوئی درمیان میں موجود ہے؟ کرپٹوگرافی میں اسے مین-اِن-دی-مڈل حملہ (MITM) کہا جاتا ہے۔

Timmy اس مسئلے کو Elliptic Curve Diffie-Hellman (ECDH) کلید کے تبادلے کے ذریعے Firebase پر، اور صارف کی بصری تصدیق.

کے ساتھ حل کرتا ہے۔ درج ذیل خاکہ ایک نظر میں جوڑا بنانے کا مکمل عمل دکھاتا ہے:

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
      

جوڑا بنانے کے مکمل پروٹوکول کی ترتیب — قابلِ ترمیم ماخذ: docs/diagrams/pairing-sequence.mmd

مرحلہ 1: ہر ڈیوائس کلیدوں کا ایک جوڑا بناتی ہے

جوڑا بنانے کی اسکرین کھولتے وقت، ہر ڈیوائس ایک عارضی ECDH کلیدوں کا جوڑا P-256 کرو (secp256r1) پر بناتی ہے:

کلیدیں کرپٹوگرافی کے لحاظ سے محفوظ رینڈم نمبر جنریٹر (Random.secure()) سے بنائی جاتی ہیں اور یہ صرف اسی ایک بار کے جوڑا بنانے کی کوشش کے لیے درستہیں۔ ہر نئی کوشش کے لیے نئی کلیدیں بنائی جاتی ہیں۔

مرحلہ 2: Firebase کے ذریعے عوامی کلیدوں کا تبادلہ

دونوں ڈیوائسز کو ایک دوسرے کو ڈھونڈنے دینے کے لیے، Timmy ایک 4 حروف کے کوڈ کو ملاقات کے نقطۂ آغاز کے طور پر استعمال کرتا ہے۔ یہ کوڈ خودکار طور پر Nearby Connections (Bluetooth Low Energy) کے ذریعے دریافت کیا جا سکتا ہے یا دستی طور پر درج کیا جا سکتا ہے۔ اس کی کوئی کرپٹوگرافک اہمیت نہیں؛ یہ صرف دونوں ڈیوائسز کو Firebase Firestore کی ایک ہی دستاویز تک پہنچاتا ہے۔

جب دونوں ڈیوائسز کو کوڈ معلوم ہو جاتا ہے، تو ہر ایک اپنی عوامی ECDH کلید ایک مشترک Firestore دستاویزمیں لکھتی ہے۔ پھر ہر ڈیوائس اسی دستاویز سے دوسری ڈیوائس کی عوامی کلید پڑھتی ہے۔

اہم بات: صرف عوامی کلید بھیجی جاتی ہے۔ نجی کلید کبھی ڈیوائس سے باہر نہیں جاتی۔ Firebase کا ٹریفک دیکھنے والا شخص عوامی کلیدیں تو دیکھ سکتا ہے، لیکن ان سے مشترک راز نہیں نکال سکتا ۔ یہ Elliptic Curve Discrete Logarithm Problem (ECDLP) کی دشواری پر منحصر ہے۔

مرحلہ 3: مشترک راز کا حساب

جب دونوں ڈیوائسز ایک دوسرے کی عوامی کلید دریافت کر لیتی ہیں، تو وہ الگ الگ ایک ہی مشترک راز:

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

کا حساب لگاتی ہیں۔ بیضوی کرو کے ریاضیاتی اصول اس بات کی ضمانت دیتے ہیں کہ دونوں حساب کا نتیجہ ایک جیسا ہوگا، اگرچہ ہر ڈیوائس کو صرف اپنی نجی کلید اور دوسری کی عوامی کلید معلوم ہوتی ہے۔

مرحلہ 4: تصدیقی نمبر (SAS)

مشترک راز سے ایک Short Authentication String (SAS) نکالی جاتی ہے — ایک دو ہندسوں کا نمبر جو دونوں ڈیوائسز پر دکھایا جاتا ہے:

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

دونوں ڈیوائسز ایک ہی نمبر دکھاتی ہیں — مثلاً، 42۔ صارف اسکرینوں پر موجود نمبروں کو دیکھ کر ملاتا ہے، پھر ہر ڈیوائس پر الگ الگ تصدیق کرتا ہے۔

حملہ آور اسے جعلی کیوں نہیں بنا سکتا

مین-اِن-دی-مڈل حملہ آور کو Firebase میں کلیدوں کے تبادلے کو روکنا ہوگا۔ خاص طور پر، اسے یہ کرنا ہوگا:

  1. Firestore دستاویز میں محفوظ اصلی عوامی کلیدوں کو اپنی کلیدوں سے بدلنا
  2. ہر ڈیوائس کے ساتھ الگ مشترک راز قائم کرنا
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 کے مختلف ہونے سے مین-اِن-دی-مڈل کی شناخت — قابلِ ترمیم ماخذ: docs/diagrams/mitm-detection.mmd

اس صورت میں، حملہ آور S_A ڈیوائس A کے ساتھ ایک مشترک راز اور ایک مختلف مشترک راز S_B ڈیوائس B کے ساتھ بناتا ہے۔ چونکہ S_A ≠ S_B، ڈیوائسز مختلف تصدیقی نمبر.

نکالتی ہیں۔ حملہ آور نمبروں کو ایک جیسا نہیں بنا سکتا کیونکہ:

ہے۔ صارف کو اسکرینوں پر مختلف نمبر نظر آتے ہیں اور وہ جوڑا بنانا منسوخ کر دیتا ہے۔ اس موقع پر حملہ واضح ہو چکا ہوتا ہے۔

مرحلہ 5: جوڑا بنانا مکمل کرنا

صارف کی جانب سے دونوں ڈیوائسز پر تصدیق کرنے کے بعد ہی جوڑا بنانا مکمل ہوتا ہے:

  1. ایک 64 حروف کی جوڑا بنانے کی کلید (256 بٹس) مشترک راز سے اخذ کی جاتی ہے: SHA-256("pair:" + sharedSecret) → pairingKey
  2. دستاویز کی کلید یوں اخذ کی جاتی ہے SHA-256("doc:" + pairingKey) اور Firestore دستاویز کی کلید کے طور پر کام کرتی ہے
  3. رمز کاری کی کلید یوں اخذ کی جاتی ہے SHA-256("enc:" + pairingKey) اور خفیہ سگنلنگ کے لیے AES-256-GCM کلید فراہم کرتی ہے
  4. دونوں ڈیوائسز ایک ہی جوڑا بنانے کی کلید محفوظ کرتی ہیں اور موڈ منتخب کرنے کی اسکرین پر چلی جاتی ہیں

اس کے بعد، کنکشن کی ہر اگلی کوشش (Firestore سگنلنگ، WebRTC سیٹ اپ) مشترک AES-256-GCM کلید سے خفیہ ہوتی ہے۔ جوڑا بنانے کی کلید کبھی بیک اینڈ کو نہیں بھیجی جاتی؛ صرف اس کا SHA-256 ہیش دستاویز کے شناخت کنندہ کے طور پر استعمال ہوتا ہے۔

سسٹم آرکیٹیکچر

درج ذیل خاکہ جوڑا بنانے اور رابطے میں شامل اجزا دکھاتا ہے:

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

سسٹم آرکیٹیکچر کا جائزہ — قابلِ ترمیم ماخذ: docs/diagrams/pairing-architecture.mmd

رابطے کے راستوں کی تفصیل:

متبادل: کوڈ دستی طور پر درج کرنا

اگر Bluetooth دستیاب نہ ہو (مثلاً پرانی ڈیوائسز پر)، تو 4 حروف کا کوڈ دستی طور پر بھی لکھا جا سکتا ہے۔ دستی اندراج میں وہی ECDH کلیدوں کا تبادلہ اور وہی SAS تصدیق استعمال ہوتی ہے جو خودکار جوڑا بنانے میں ہوتی ہے۔ فرق صرف اتنا ہے کہ BLE سے دریافت ہونے کے بجائے کوڈ صارف پڑھ کر ٹائپ کرتا ہے۔

چونکہ دونوں صورتوں میں ECDH کلیدوں کا تبادلہ Firebase کے ذریعے ہوتا ہے، اس لیے سکیورٹی بالکل یکساںہے۔ 4 حروف کا کوڈ صرف ملاقات کا نقطہ ہے؛ اصل رمز کاری ECDH سے اخذ کی گئی 256 بٹ کلید پر مبنی ہے۔

خلاصہ

سکیورٹی طریقۂ کار کس سے تحفظ دیتا ہے
ECDH کلیدوں کا تبادلہ (P-256) کلیدوں کے تبادلے کے ٹریفک کی جاسوسی
عارضی کلیدوں کے جوڑے فارورڈ سیکریسی — پچھلے جوڑے محفوظ رہتے ہیں
بصری تصدیقی نمبر (SAS) کلیدوں کے تبادلے کے دوران مین-اِن-دی-مڈل (MITM)
دستاویز کی کلید کے طور پر SHA-256 ہیش Firestore سے کوڈ نکالنا
AES-256-GCM رمز کاری سگنلنگ ڈیٹا کی جاسوسی
دونوں طرف سے تصدیق صارف کے علم کے بغیر یک طرفہ جوڑا بنانا
DTLS-SRTP (WebRTC) آڈیو/ویڈیو کی جاسوسی

یہ حفاظتی پرتیں مل کر کام کرتی ہیں: ECDH کلیدوں کے تبادلے کو محفوظ رکھتا ہے، تصدیقی نمبر MITM سے بچاتا ہے، AES-256-GCM سگنلنگ کو محفوظ رکھتا ہے، اور WebRTC میڈیا کو محفوظ رکھتا ہے۔ حملہ آور کو ڈیوائسز یا والدین کو خبر ہوئے بغیر کئی جگہوں پر اس زنجیر کو توڑنا ہوگا۔


مزید مضامین