前端面試題:如何用 WebRTC Encoded Transform 實作端到端加密?
題干
請為多人 WebRTC 會議設計瀏覽器端端到端加密:媒體伺服器只轉發 RTP,無法讀取音視頻;發送端與接收端在 Worker 處理編碼影格。說明 RTCRtpScriptTransform、RTCRtpScriptTransformer、金鑰分發、關鍵影格、效能、失敗恢復與相容性邊界,並區分編碼影格變換和傳輸層 TLS。
面試官在考察什麼
題目考察你能否掌握瀏覽器媒體管線邊界:變換位於編碼後、解碼前,影格依序從 readable 流向 writable,密碼運算在 Worker 執行,並處理金鑰輪換、新成員關鍵影格、丟影格與不支援 API 的瀏覽器。
先確認這些問題
- 要保護哪些參與者和媒體伺服器?伺服器是否只轉發?
- 只支援視頻還是音訊也要加密?是否包含螢幕分享和錄製?
- 金鑰由端到端信令分發,還是已有群組金鑰服務?如何撤銷離會成員?
- 目標瀏覽器和最低版本是什麼?不支援時拒絕、降級或關閉 E2EE?
30 秒回答框架
TLS 只保護傳輸鏈路,媒體伺服器仍可能看到明文;E2EE 要在發送端編碼後加密、接收端解密後交給解碼器。回答分為能力偵測、Worker 影格管線、金鑰與 nonce、關鍵影格和重試、降級與觀測。API 為 Baseline 2025,但仍要按瀏覽器矩陣驗證。
逐步拆解方案
1. 能力偵測與掛接時機
建立 RTCRtpScriptTransform 並傳入 Worker、方向標識與可轉移 MessagePort。發送端掛到 RTCRtpSender.transform,接收端掛到 RTCRtpReceiver.transform,要早於第一個影格。能力偵測失敗要記錄,不能把未加密媒體靜默當成功。
2. Worker 中的影格流
Worker 監聽 rtctransform,從 event.transformer.readable 讀取編碼影格,通過 TransformStream 後寫入 event.transformer.writable。要保持順序、恰好一次入隊,錯誤時關閉流並上報;主執行緒只傳設定和金鑰句柄。
3. 加密格式與金鑰生命週期
按會議、發送者與金鑰 epoch 建立上下文;nonce 以影格序號、SSRC 或計數器構成,禁止重用。密文攜帶版本、epoch 和認證標籤,接收端驗證後才解密。金鑰透過已驗證的端到端信令分發,輪換時短暫容納雙 epoch,成員離會立即撤銷新影格權限。
4. 關鍵影格與新成員
新成員可能先收到 delta frame,無法重建畫面。接收端變換在獲得新金鑰或無法解碼時呼叫 sendKeyFrameRequest();發送端可呼叫 generateKeyFrame()。兩者回傳 Promise,需確認方向與視頻狀態並限流。
5. 效能與背壓
控制記憶體複製和 GC,盡量重用影格緩衝;Worker 使用固定併發,避免無界佇列。統計每影格耗時、佇列深度、丟影格率與關鍵影格請求率。超出延遲預算時降低品質或暫停軌道,不能阻塞主執行緒。
6. 錯誤、重連與恢復
金鑰過期、標籤驗證失敗、Worker 崩潰與瀏覽器拒絕呼叫都進入可觀測狀態機。短暫失敗可重啟 Worker 並恢復當前 epoch;無法恢復時停止該軌道並提示。重新協商 PeerConnection 後要重新掛接 transform。
7. 相容性與安全邊界
MDN 將 Encoded Transform 標為 Baseline 2025,但舊瀏覽器和部分裝置可能缺少。產品需明確拒絕、關閉 E2EE 或只允許受信媒體伺服器轉碼。W3C 文件是 Working Draft,不能隱藏介面穩定性與實作差異。
合格回答示例
「我會在 sender 編碼後、receiver 解碼前掛接 RTCRtpScriptTransform,Worker 從 transformer 的 readable 讀編碼影格,經認證加密後寫入 writable。金鑰由端到端信令按會議、成員和 epoch 管理,nonce 使用不可重複計數器,接收端驗證標籤才解密。新成員或換鍵無法解碼時,接收端限流呼叫 sendKeyFrameRequest,發送端必要時 generateKeyFrame。監控耗時、佇列、丟影格與驗證失敗;恢復失敗就停止軌道。上線前依能力偵測決定拒絕、降級或關閉 E2EE,並標示 Baseline 2025 與 W3C Working Draft 狀態。」
常見失分點
- 把 TLS 當媒體端到端加密。
- 在主執行緒逐影格加密,或處理原始影格而不是編碼影格。
- 不驗證認證標籤、重用 nonce,沒有 epoch 和離會撤銷。
- 忽略關鍵影格、Worker 崩潰、重連和瀏覽器差異。
- 只說支援 WebRTC,沒有確認 Encoded Transform 介面。
追問方向
為何在編碼後處理?
編碼影格較小且保留 RTP 管線,變換可在解碼前後插入;原始影格會增加複製與計算成本。
sendKeyFrameRequest() 一定會送出嗎?
不一定。使用者代理可能判斷不需要,Promise 仍會完成,因此產品要處理等待與逾時。
金鑰如何傳給 Worker?
透過 options 或可轉移 MessageChannel 傳短期句柄,避免長期金鑰暴露給無關腳本。
不支援 API 能否靜默降級?
不能。必須向使用者和會議策略清楚標示媒體是否 E2EE。
如何驗證伺服器沒有明文?
在測試環境擷取轉發節點資料,確認只有密文影格,並審計信令、Worker、金鑰服務與錄製權限。
參考資料
MDN《Using WebRTC Encoded Transforms》、MDN《RTCRtpScriptTransformer》與 W3C《WebRTC Encoded Transform》規範草案。