用戶端把工作區加密上傳後,為什麼你解不開這份本機密文

2026 年 9 月 18 日,開發者 ferstar 在清理磁碟時發現:登入狀態下的 AI 程式設計用戶端會把整個工作區打成加密包,再嘗試直傳物件儲存。包是密文,用來包金鑰的 RSA 公鑰卻由伺服器當場下發,對應私鑰從不落到這台電腦。於是出現一句反直覺的話:磁碟上那幾百 MB「已加密」檔案,你解不開,用戶端也解不開。9 月 21 日廠商宣布開源並拆除上傳鏈路,但「加密上傳」四個字本身並沒有因此變成零知識。

先記結論:「已加密」只說明打包後的位元組不是工作區明文。它不能說明你持有解密能力,也不能說明雲端讀不到內容。信封加密裡,對稱金鑰用伺服器下發的公鑰包一層,私鑰留在雲端,設計目標就是讓雲端能解開。能當場核對的是三件事:這份密文你自己能不能打開、Network 裡有沒有工作區明文、介面開關關掉之後是否仍出現新的待傳包。不要把「本機做了 AES」讀成「只有我能解密」。

一句話先回答搜尋意圖

傳輸層加密和「你擁有金鑰」不是同一層。用戶端可以在本機用 AES 把工作區打成密文,再把密文傳到物件儲存;若包金鑰的公鑰來自伺服器,私鑰從未進入這台電腦,這份檔案就不是給你還原用的備份。它是一封只有雲端能拆的信封。鏈路竊聽者看不到明文,持有私鑰的伺服器看得到。

這篇文章給剛看到「用戶端加密上傳工作區」新聞、想分清「密文在磁碟上」和「零知識」的人,以及要把儲存庫或金鑰交給同事、又不願把解密權交給廠商的開發者。它不代替廠商通報,也不寫成某一款編輯器的解除安裝指南。你要帶走的是:信封加密把金鑰放在誰手裡、清單明文已經寫出了多大範圍、「立即銷毀」證明不了什麼,以及你怎麼在本機對照「這份密文我能不能解開」。

這次拆解把哪幾層寫清楚了

2026 年 9 月 18 日,ferstar 公開了調查紀錄。起因不是抓包競賽,而是清理磁碟:本機 ~/.zcode 佔了七百多 MB,其中 v2/checkpoints/ 裡有一份約 313 MB 的 .enc,旁邊的狀態檔寫明工作區約 345 MB、kind 為 baseline、failureCount 為 564。儲存庫本身約 10 GB,去掉相依套件後剩下的 345 MB,幾乎都是專案核心檔案。

他把用戶端裡的上傳流程還原成兩步。第一步,用戶端向 zcode.z.ai 請求 POST /api/v1/snapshot/upload-credential,伺服器傳回快照編號、物件儲存表單簽章、大小上限,以及這一輪的 RSA 公鑰。第二步,本機打 tar.gz,用一次性對稱金鑰做 AES-256-CTR,再用 RSA-OAEP-SHA256 包住這把對稱金鑰,最後把 tar.gz.enc 以表單 POST 直傳到阿里雲 OSS,由儲存回呼廠商後端登記。應用伺服器不經手這份密文檔案,但登記權和私鑰仍在雲端。

範圍也不只是目前工作樹。本機明文清單列出 42,411 個檔案:.git/lfs/ 約 196.1 MB(56.8%),.git/objects/ 約 102.2 MB(29.6%),.git/logs/ 約 0.6 MB,原始碼與文件約 46.2 MB(13.4%)。.git 合計 86.6%。上傳若成功,雲端拿到的是提交歷史、已刪除但仍留在物件庫裡的金鑰、尚未推送的本機分支名稱,以及 .git/config 裡的內網主機。另有一份跨工作區的額外清單,會給全域設定做雜湊並一併帶走。

9 月 18 日 17:44,廠商在使用者社群發情況說明,承認上傳來自預設開啟的程式碼庫索引,用於工作階段檢查點、版本回溯和 Repo Wiki,並稱 Wiki 產生後資料立即銷毀。9 月 21 日《每日經濟新聞》報導:ZCode 宣布開源;中國信通院評測稱 zcode-prod 儲存貯體為零資料;綠盟科技稱貯體與物件已刪除;用戶端 v3.14.0 已拆除快照產生與上傳鏈路。ferstar 補充:那份 313 MB 商業專案因超過大小限制、重試 564 次,並未傳出區域網路;另一份 538 個檔案的公開儲存庫工作區,壓縮加密後約 15 KB,狀態為伺服器端已接受。所以「有沒有東西離開過這台機器」——至少那一份小的,離開過。

信封加密為什麼不等於你能解密

AES-256-CTR 加 RSA-OAEP 是教科書裡的信封:內容用短命對稱金鑰加密,對稱金鑰再用公鑰包一層。演算法名稱看起來很硬,決定「誰能讀」的卻是公鑰從哪來、私鑰落在哪。調查紀錄寫明:公鑰在申請上傳憑證時由伺服器下發,對應私鑰從不進入這台電腦;用本機已有私鑰去拆這層信封,沒有成功。用戶端自己也解不開磁碟上那份密文。

這和「給我自己做一份可還原備份」是反著的。Time Machine、本機 Git 物件、你用口令加密後再拷走的檔案,解密材料都在你這邊:口令、本機金鑰,或你能打開的鑰匙圈。伺服器獨占私鑰時,設計目標換成了:傳輸途中第三者看不見,到達後雲端能拆開。ferstar 的原話把用途寫死了——一把只有伺服器能用的鑰匙,服務的是伺服器讀你的程式碼,不是給你做回溯。

上海交通大學資料法律研究中心何淵對《每日經濟新聞》說得更窄:加密是安全措施,不等於匿名化,也不能取代告知和最小必要;服務提供者仍掌握解密能力時,加密後的資料仍可能被還原和處理。「使用後立即刪除」只降低長期留存,回答不了最初蒐集是否必要。把這兩句放在一起:演算法強度證明不了金鑰歸屬,銷毀聲明證明不了蒐集範圍。

不要用正式儲存庫、真實雲端金鑰或客戶程式碼去「重現上傳」做實驗。核對的是本機是否已經出現待傳密文、狀態檔裡的路徑和失敗次數,以及你自己能不能解開這份檔案。把活的儲存庫再送一遍,不會讓私鑰回到你手裡。

清單明文已經把範圍寫出來了

密文打不開,不等於範圍只能猜。打包時產生的檔案清單留在本機,而且是明文。42,411 條紀錄把「目前原始碼」和「儲存庫的一生」拆開了:目前工作樹大約只佔 13.4%,其餘是 LFS 快取、完整物件庫和 reflog。目前工作區裡已經刪掉的 API 金鑰,只要曾經提交過,仍可能在 .git/objects 裡。尚未推送的分支名稱會暴露還沒發布的功能。內網 Git 主機名稱寫在 .git/config,不需要打開密文也能從清單側看見它被收進包。

介面上的兩個開關,名稱像總開關,程式裡不是。調查紀錄對照後的結果是:「最佳化體驗」只控制可否用於模型訓練;「儲存庫快照索引」只控制雲端是否建索引。打包和直傳在登入 JWT 有效時仍會走。擷取點寫在每次送出 Prompt 之前,以及工作結束時的 repo-wiki-update;單次使用中的工作階段最多記到 62 次擷取。手動刪掉待傳包後約半小時,會打出一份新的 313 MB 檔案,失敗計數從 564 變成 565。刪除檔案不是關閉開關。

9 月 18 日歸檔的隱私權政策,頁面仍寫最後更新於 2026-06-15,蒐集範圍寫的是對話裡提交的文字、檔案和程式碼,沒有寫「登入後自動打包完整工作區與 Git 歷史」。政策能支持的結論,是廠商聲明了工作階段提交;它不能支持:全量快照已經寫進你點過同意的那一頁。開關和隱私權政策都要對照實際產物:本機有沒有新的 .enc,狀態檔裡的 workspacePath 是不是你正在寫的商業專案。

「已加密」和「立即銷毀」各能證明什麼

把新聞裡的句子拆成「能支持 / 不能支持」,比跟著形容詞走要穩。密文在磁碟上,只能支持:打包後的位元組不是目錄樹明文。立即銷毀,只能支持:廠商聲稱 Wiki 產生後不再長期放那份物件。開源後的儲存庫裡搜不到 /api/v1/snapshot/upload-credential,只能支持:目前公開樹裡這條鏈路被拆掉了。儲存貯體被評測為零資料,只能支持:評測當時那個貯體是空的。

這些句子都蓋不住另一面。密文不能支持你能還原工作區。立即銷毀不能支持銷毀前無人持有私鑰,也不能支持蒐集範圍等於你勾過的選項。壓成兩次提交的開源儲存庫,不能用來對照舊版 sidecar 是怎麼寫的。事後清空的貯體,不能倒推 9 月 18 日之前已接受的物件被誰解過、複製過。ferstar 寫過:檢查點回溯若真需要全量上雲,和「產生後立即銷毀」在時間上是對不上的;開源樹裡的檢查點實作,是本機 Git diff,中繼資料寫在 ~/.zcode/checkpoints/ 的 JSON,並不仰賴那條上傳鏈路。

你看見的說法 能支持的結論 不能支持的結論
磁碟上是 .enc,演算法寫著 AES-256 打包後的位元組不是工作區明文 只有你能解密,雲端讀不到內容
RSA 公鑰在申請憑證時由伺服器下發 拆信封的私鑰不在這台電腦 這是給你做跨裝置還原的備份
關掉「最佳化體驗」和「儲存庫索引」 訓練授權或雲端索引可能停了 打包和直傳一定一起停了
官方稱 Wiki 產生後立即銷毀 廠商聲明不長期留存該物件 最初打包範圍等於你點過的開關
評測稱儲存貯體為零資料 評測當時那個貯體是空的 更早收下的物件從未被解密或複製
313 MB 那份失敗了 564 次 這一份商業專案快照未傳出 沒有任何工作區離開過任何使用者的機器

當場能核對哪幾層

口號不能當證據。下面只核對應由你控制的三層:本機有沒有待傳產物、請求有沒有帶出工作區明文、這份密文你自己能不能打開。不要向正式儲存庫再灌一次「測試上傳」。

  1. 先看本機資料目錄,而不是先看宣傳頁。AI 程式設計用戶端常見的檢查點或快取目錄裡,若出現數百 MB 的 .enc 和一份寫著 workspacePath、encryptedSizeBytes、failureCount 的狀態檔,說明打包已經發生。路徑對得上你正在寫的專案,比「我們只傳對話上下文」更硬。
  2. 打開開發者工具或系統網路觀察,勾選 Preserve log。只看請求行和主機名稱:有沒有申請上傳憑證的介面,有沒有直連物件儲存的表單 POST。對照的是「密文是否離開這台機器」,不是把儲存庫再送一遍。請求體裡若出現原始碼、口令或 .pem 明文,這一層已經失敗。
  3. 問一句能落地的話:這份本機密文,我用自己的口令或本機私鑰能不能打開。打不開,且廠商也說用戶端解不開,金鑰歸屬就不在你這邊。打得開,才能談「這是給我自己的備份」。
  4. 關掉所有名稱像「隱私 / 索引 / 最佳化」的開關,等一個工作階段週期,再看檢查點目錄有沒有新的待傳包、失敗計數有沒有繼續加。開關文案證明不了總開關;新檔案才證明。
  5. 需要自己還能解開的檔案時,換一條計算邊界寫清楚的通道。打開 檔案加密盒,選一份可丟棄的金絲雀檔案,檔名寫成 canary-fp-20260922-vendor-key.txt,口令只留在這台電腦。打開 Network,勾選 Preserve log,點加密。請求行和請求體裡不應出現檔案內容、口令或完整檔名業務欄位;輸出是 .lock / .enc,單一檔案不超過 5 GB。用同一組口令在本機解密,金絲雀應還原。你能解開,是因為口令在你手裡,不是因為演算法名稱裡有 AES。

第五步不是讓檔案加密盒去取代程式設計用戶端。它只提供一個對照:同樣是「本機加密」,金鑰衍生和 AES-256-GCM 留在目前分頁,檔案和口令預設不作為業務資料上傳。密文你帶得走,也解得開。上一篇寫過的中繼站問題是另一層——HTTPS 只保護到代理這一跳;這一篇多出來的層是:密文離開之後,拆信封的人是誰。

完整口令和密文不要走同一條聊天。檔案加密盒的 .lock 可以拷到雲端硬碟,口令應另走已經核實過的管道,或把短口令放進閱後即焚連結的 # 後面。把鑰匙和鎖貼在同一則訊息裡,信封對「能看見這則訊息的人」已經沒了。

三種把「本地加密」讀過頭的情況

第一,把「在本機呼叫了 AES」讀成「只有我能解密」。呼叫發生在本機,只說明明文打包時還在這台電腦。公鑰從伺服器來、私鑰不落地時,解密權在雲端。演算法清單、金鑰長度、CTR 還是 GCM,都回答不了「私鑰在誰的行程裡」。

第二,把「直傳物件儲存、不經應用伺服器」讀成「廠商看不見」。檔案可以不經過應用伺服器,登記回呼和私鑰仍在廠商一側。跳過應用機房,減少的是應用程式日誌裡的明文副本,不是解密權。中繼站那篇寫過 HTTPS 擋不住應用層代理;這裡擋不住的是「持有私鑰的那一端」。

第三,把「立即銷毀 / 開源 / 儲存貯體已空」讀成「從未蒐集」。銷毀降低留存,開源讓你核對目前的程式碼樹,空的貯體說明評測當時沒有物件。它們都不自動等於:歷史物件沒有被解過,或當時的開關已經涵蓋全量 Git。需要寫進交接說明的,是本機是否還在產生待傳包,以及你自己能不能解開即將外傳的密文,而不是新聞標題裡的「已改正」。

常見問題

磁碟上已經是密文,是不是就等於本機零知識?

不是。密文只說明打包後的位元組不是明文工作區。若用來包金鑰的 RSA 公鑰由伺服器當場下發,對應私鑰從不落地,你和用戶端都解不開這份檔案。這是給雲端讀的信封,不是給你自己還原用的備份。

官方說上傳後立即銷毀,還能再核對什麼?

「立即銷毀」降低的是長期留存。它回答不了最初打包範圍是否超出你點過的開關,也回答不了銷毀前誰握著私鑰。事後清空儲存貯體,不能倒推 9 月 18 日之前已經收下的物件被誰解過、複製過。

介面上的「最佳化體驗」「儲存庫索引」關掉,上傳是不是一起停?

在被拆解的舊用戶端裡,這兩項分別管「可否用於訓練」和「雲端是否建索引」,都不切斷打包和直傳。要看的是有沒有獨立的「停止產生快照」開關,以及關掉之後本機是否仍出現新的待傳密文。

要把一份自己還能解開的檔案交給同事,該走哪條通道?

先在目前分頁用 AES-256-GCM 加密,口令只告訴已經核實過的接收方。打開 檔案加密盒 即可,單一檔案不超過 5 GB,輸出 .lock / .enc,檔案和口令預設不上傳,開啟即用,無需帳號。短秘密改走 閱後即焚,金鑰放在連結的 # 後面,形態是 s.html?id={id}#{key}。工單或日誌裡若還疊著手機號碼、證件號碼,先在 隱私清洗 做規則脫敏,原文不作為業務資料上傳。

需要自己能解開時,改走開啟即用的通道

若你希望用一個把計算邊界寫清楚的頁面來練習「密文我能解開、口令不進 Network」,打開 FastPwd 的 檔案加密盒 即可,無需註冊。選上面那份金絲雀,在目前分頁做 AES-256-GCM,再按第五節對照:請求裡不應出現檔案內容和口令,同一組口令應能在本機還原。輸出 .lock / .enc 可以拷到雲端硬碟;口令不要寫進同一條聊天,也不要寫進任何 AI 對話框。

還要把儲存庫片段交給雲端模型時,先假定接收端看得到你貼上的全文。中繼站會在 HTTPS 終止處留下明文呼叫包,上一篇已經寫過。這一篇多問一句:用戶端若先「加密」再上傳,拆信封的私鑰在不在你這邊。兩層都過不了,就不要把活的雲端金鑰、SSH 私鑰或客戶資料放進工作區再交給會打包的工具。規則脫敏只能掩碼常見欄位,整段金鑰應改走閱後即焚或根本不外傳。

下次再看見「我們本機加密後再上傳」這類說明,記住三件事。第一,問私鑰或口令在誰手裡,不要只問演算法名稱。第二,問清單有沒有覆蓋到不算目前檔案的 .git 歷史。第三,用一份你自己能解開的密文做對照,而不是用銷毀聲明做對照。能寫進交接說明的,只能是這三句,不能是「磁碟上是密文,所以雲端看不見」。

延伸閱讀

雲端硬碟上傳前給壓縮檔設密碼,擋不住檔名,也不是本機 AES-GCM,見 雲端硬碟上傳前,壓縮檔密碼能擋住什麼,為什麼它不是本機 AES-GCM。HTTPS 只加密到中繼站這一跳,擋不住 Prompt 裡的 SSH 金鑰,見 LLM 中繼站 6TB 呼叫包裡為什麼會出現 SSH 金鑰,HTTPS 擋不住哪一層。頁面上的「本地加密」怎麼用 Network 自己核對,見 瀏覽器本地加密怎麼核對明文沒有離開本機。