打開一個「線上密碼產生器」,點產生,再打開開發人員工具的 Network 面板——如果請求主體或查詢參數裡出現了剛產生的口令,代表明文已經離開你的裝置。這一步不必相信任何品牌承諾,瀏覽器自己會把流量攤開。
把運算放在瀏覽器裡,不是為了聽起來更「去中心化」,而是為了把明文視窗壓在本機:少一層傳輸、少一份伺服器紀錄、少一次維運人員誤讀記憶體傾印的機會。下面依威脅模型、可核對步驟和能力邊界把這件事說清楚。PassAfer 的工具棧按這個原則設計;本文不講產品總覽,只回答一個問題:敏感運算為什麼不該預設交給伺服器。
伺服器代算會擴大什麼視窗
所謂明文視窗,指的是明文(或可直接還原明文的金鑰)在哪些環節真實存在。伺服器代算時,視窗通常不只是「你點了送出」那一瞬間,而是一條很難事後抹掉的鏈條:
- 瀏覽器到來源站的 TLS 工作階段——伺服器行程看到的是解密後的請求,不是密文。
- 反向代理、WAF、APM、錯誤追蹤裡的請求主體取樣;一次 500 就可能把表單打進當機報告。
- 應用程式紀錄、慢查詢、存取紀錄裡的 query string;有人習慣把金鑰放在
?key=,等於寫進 access log。 - 資料庫、物件儲存、暫存磁碟上的中間檔,以及備份與異地複本。
- 維運、客服、入侵者拿到上述任一複本的時間——視窗已經發生過,承諾「用完即刪」改變不了這一點。
法律管轄和供應商分包會讓「我們不會看」變成難以稽核的句子。你能核對的是協定與流量,不是對方機房裡的內部規範。
對密碼產生尤其刺眼:你要的是一串還沒在任何系統裡出現過的秘密。若產生發生在別人的機房,這串秘密的第一份複本就不在你手上。之後你把它貼進正式環境設定、CI 變數或密碼管理器,外洩源已經多了一個你看不見的節點。
對密碼稽核同樣:把常用密碼提交給遠端「測強度」,等於把最敏感的重複口令交給第三方。公開外洩庫查詢可以做成 k-anonymity 一類協定;PassAfer 的 Password Audit 選擇更硬的約束——待測密碼不上傳,強度估算與 Top 外洩列表比對都在瀏覽器本地完成。你要驗證的不是「對方聲稱沒存」,而是請求裡根本沒有這串口令。
對檔案加密,若走「上傳 → 伺服器加密 → 再下載」,口令與檔案內容至少在伺服器記憶體裡完整出現過。本地串流加密則讓伺服器沒有明文可接:它甚至不需要知道你加密的是照片還是磁碟映像。
不要把「用了 HTTPS」當成本地運算
TLS 保護的是傳輸路徑上的竊聽者,不是對端伺服器。伺服器代算時,對端本來就要讀明文。本地運算要解決的是:對端根本不該看到這份材料。
「本地」到底指哪一層
「本地」很容易被用成口號。需要拆開,否則雲端硬碟上的「僅你可見」也會被說成本地加密。
本機行程,而不是「存在某個雲端帳號裡」
PassAfer 所說的本地,指運算發生在你的瀏覽器分頁:亂數來自 crypto.getRandomValues,對稱加密走 Web Crypto API。金鑰材料在短生命週期的 CryptoKey 物件裡,預設不作為分析欄位外送。結果可以複製、匯出或下載到磁碟;頁面關掉後,記憶體中的明文依瀏覽器生命週期回收,而不是在遠端再留一份。
這和「把檔案丟進僅自己可見的雲端硬碟」不是一回事。雲端硬碟伺服器通常能讀物件明文,除非你先在本機封好再上傳密文。本地優先問的是:明文有沒有在你的裝置之外以可用形式出現過。
演算法與檔案上限是可核對的事實
初版對稱加密演算法只有 AES-256-GCM(驗證加密:密文被改過,解密會失敗)。檔案加密盒對單一檔案做串流處理,上限 5 GB,輸出 .lock(首選)或 .enc,避免把整份影片一次裝進記憶體。這些數字寫在需求裡,不是行銷形容詞;頁面上若出現未實作的演算法切換,應以產品說明為準,而不是自行腦補。
本地不等於「全部公開可用」
運算位置和登入權限是兩件事。未登入訪客可以使用隨機字元與可讀密碼(Passphrase)的產生、複製與匯出;Password Audit、隱私清洗、Burn-Link 建立、檔案加密盒和密碼庫需要登入後解鎖。把「本地」理解成「誰都能用所有工具」,會和權限矩陣衝突。
| 能力 | 未登入 | 敏感材料是否預設上傳 |
|---|---|---|
| 隨機/可讀密碼產生 | 可用 | 不上傳;在瀏覽器產生 |
| 新增至密碼庫 | 登入引導 | — |
| Password Audit | 登入引導 | 待測密碼不上傳;本地強度 + 外洩列表 |
| Clean Link/脫敏 | 登入引導 | URL 與文字本地處理;不寫 analytics |
| Burn-Link 建立 | 登入引導 | 上傳的是密文 blob,不是原文 |
| Burn-Link 閱讀 | 對接收方公開 | 金鑰在 URL 的 # fragment,不隨 HTTP 送給伺服器 |
| 檔案加密盒 | 登入引導 | 檔案與口令不上傳;本機串流 AES-256-GCM |
Burn-Link 是唯一需要伺服器暫存的路徑,但暫存的是密文。解密金鑰放在 URL 的 # 段:fragment 不會隨 HTTP 請求送給伺服器,access log 裡通常只有路徑。閱讀頁對接收方公開——否則對方還得先註冊,一次性傳密就做不成。首次閱讀後密文依設計焚毀。伺服器零知識不等於「什麼都不存」,而是「存了也解不開」。本篇只需建立這條約定。
用 Network 面板核對敏感內容是否外傳
口號無法自證。下面是一套不依賴信任的核對步驟,用瀏覽器自帶的開發人員工具即可。目標不是證明「全世界沒有側通道」,而是拆穿「點一下就把明文 POST 走」的線上工具。
從無需登入的密碼產生器開始。打開密碼產生頁,保持登出。隨機字元與可讀密碼都應能直接產生。這一步把「帳號體系」和「產生是否外傳」分開,避免把登入請求誤判成口令上傳。
打開 Network,勾選 Preserve log。Chrome/Edge/Firefox 均可。篩選器可先用 Fetch/XHR,再掃一遍全部請求。Preserve log 避免頁面跳轉清空紀錄。注意 sendBeacon 與 Service Worker 發起的請求也會出現在面板裡。
產生一串容易辨認的口令。把長度調長一些,產生後複製到記事本。在 Network 搜尋框貼上這串口令,或其中一段不會碰巧出現在 JS 原始碼裡的子字串。
看 URL、Query、Request Payload 有沒有命中。若沒有任何請求命中該子字串,代表至少在「產生」這一刻,明文沒有作為 HTTP 內容外傳。靜態指令碼裡出現無關字串不算;要找的是你剛產生的那一串。
登入後的工具用同一方法。Password Audit、隱私清洗、檔案加密盒需要登入。登入後用僅供測試的假密碼或小檔案再搜一遍。稽核頁不應把待測密碼發到遠端;清洗頁不應把原文 POST 出去;檔案盒不應把明文以 multipart 上傳。
Burn-Link 要看密文與 fragment。建立(需登入)時送往伺服器的應是密文,不是你輸入的原文。完整連結裡金鑰在 # 之後;去掉 fragment 再看 Network,請求路徑裡不應出現金鑰。接收方打開閱讀頁不必登入。
這一步能證明什麼,不能證明什麼
Network 驗證的是:這次操作有沒有把明文放進 HTTP。它看不到同源指令碼讀記憶體、惡意擴充功能,或已被 XSS 插入的頁面。對拆穿大量「線上工具」已經足夠;不要把它理解成形式化證明。
哪些運算必須本地,哪些例外要說清楚
必須留在本機的,是一旦外傳就不可撤回的材料:新產生的口令、待測的舊口令、待脫敏的原文、檔案明文、對稱金鑰。這些東西進了別人的紀錄,你刪頁面也刪不掉對方那份。
可以離開裝置的,只有在密碼學上對伺服器無用、或屬於帳號體系本身的資料。例如 Burn-Link 的密文 blob、登入所需的使用者名稱與登入密碼、以及不含秘密的靜態資源。不要把「登入」和「上傳工具明文」混為一談:登入是權限分級——未登入即可產生密碼,降低上手成本;稽核、清洗、焚鏈建立、檔案盒和密碼庫在登入後解鎖。登入憑證走的是帳號體系,與「產生出來的那串新密碼是否上傳」不是同一件事。
檔案加密盒的輸出是你下載到磁碟的 .lock/.enc。之後用雲端硬碟、USB 隨身碟或郵件傳的是密文檔。若你把密文傳到某雲端硬碟,該服務仍然看不到口令與原文——前提是口令沒有寫在同一次傳輸或同一封郵件的明文裡。本地加密改變的是「雲端硬碟管理員預設能打開你的照片」這件事,不是實體保管責任。
隱私清洗(Clean Link 與 Data Redaction)同樣把 URL 和文字留在瀏覽器裡處理:剝離 UTM/廣告參數、遮罩電話與證件號碼,結果給你核對後再外送。原文不上傳,也不作為 analytics 事件內容。若清洗過程把整段工單 POST 到伺服器再回傳「已脫敏」,明文視窗已經在伺服器打開過了,脫敏就只剩顯示層。
瀏覽器本地加密的邊界與誤區
本地優先降低的是伺服器與傳輸路徑上的暴露,不是一台被木馬控制的電腦。把邊界寫進預期,比把 AES 三個字母印在頁尾更有用。
頁面被插入惡意程式碼時,演算法幫不上忙
XSS 或被劫持的指令碼可以讀取輸入欄。Web Crypto 保護的是「誠實頁面裡的金鑰操作」,不是「惡意指令碼已經進了同源」。依賴的是同源政策、內容安全政策與前端供應鏈完整性。看到「AES-256-GCM」不要推導出「所以 XSS 無效」。
擴充功能、公司代理、肩窺
瀏覽器擴充功能和公司 SSL 解密代理仍可能看到頁面內容。Network 面板在「公司代理注入根憑證」時,你看到的是代理之後的世界。裝置遺失、螢幕分享、肩窺,本地運算無法防禦。這些是端點安全問題,應和「伺服器不該持有明文」分開處理。
「不上傳」不是「不上網」
頁面本身、指令碼、登入請求仍會發出。核對的是敏感欄位有沒有出現在請求裡,不是把網路線拔掉。PassAfer 也不會把待測密碼、清洗原文或檔案內容當作分析事件上報——事件裡不應出現秘密本身。
不要把能力寫過界
初版演算法就是 AES-256-GCM,不要指望頁面上出現可切換的 RSA 或未交付的國密選項。不要把 Burn-Link 閱讀頁寫成必須登入。不要聲稱伺服器也能看到明文或金鑰——那與產品事實相反。本地優先的誠實寫法是:敏感運算在瀏覽器完成;明文、金鑰、檔案預設不上傳;焚鏈伺服器只暫存密文。
想自己驗證時,可以從哪一步開始
若你只想先確認「產生這一刻有沒有外傳」,從密碼產生器開始最合適:無需登入,隨機字元與可讀密碼都能在本機完成,複製和匯出也一樣。打開 Network,按上文步驟搜一遍自己剛產生的字串。這一步成本最低,也最容易形成「明文視窗」的直覺。
常見替代做法的局限很具體。明文郵件和即時通訊會把金鑰留在雙方歷史紀錄、伺服器封存和裝置備份裡;雲端硬碟預設對伺服器可讀,除非你先在本機加密;把金鑰放在查詢參數裡,幾乎一定會進 access log。這些路徑不是「不夠方便」,而是明文視窗被設計進去了。
若你要備份一份不能直接放雲端硬碟的檔案,登入後使用檔案加密盒:在瀏覽器裡用 AES-256-GCM 串流加密,單一檔案不超過 5 GB,下載 .lock 或 .enc。再對加密過程抓包,確認沒有把原檔 POST 出去。需要一次性把短文字機密發給同事、又不希望金鑰出現在伺服器紀錄裡時,再用Burn-Link:本地加密,金鑰放在 # 段,伺服器只碰密文,閱讀頁對方不用註冊。本篇只要求你先能回答:這次點擊之後,明文還在不在你的分頁裡。
PassAfer 的口號是「本地加密,安全隨行」。隨行的前提是:運算發生在你正在看的這個分頁裡,並且你可以用瀏覽器自帶的面板把這一點核對一遍。