把敏感檔案打成帶密碼的 ZIP 再外發,預設加密、檔名和未加密條目還可能留下什麼

外發薪資表、憑證包或匯出設定時,最省事的動作常常是「先壓縮、設個密碼,再丟進郵件或 Google 雲端硬碟」。對方連按兩下要輸入密碼,看起來整包都鎖住了。ZIP 的加密旗標寫在每一條檔案上;傳統加密被規格寫成弱;檔名和未加密條目常常還在明文檔頭裡。下面按 PKWARE、WinZip 和 7-Zip 自己寫得出來的分層,把「設了密碼之後還剩什麼」收成可以當場核對的範圍。

「設了密碼」不是「整包都鎖住了」

很多人把帶密碼的 ZIP 當成一個上了鎖的箱子:箱子在誰手裡都沒關係,沒有鑰匙就看不見裡面。實際格式更碎。ZIP 先是一份目錄,再是一條條檔案。加密旗標掛在每一條檔案的本地檔頭和中央目錄上,不掛在「整個 .zip 檔案」這一層。你設了密碼,只說明至少有一條檔案的壓縮資料流按某種演算法罩住了;不等於目錄不可讀,也不等於包裡每一條都用了同一種演算法、同一句密碼。

財務報表、身分證掃描檔、SSH 私鑰、資料庫傾印、未遮罩的客戶名單,都屬於不該在「目前這一個資料夾」以外多留幾份明文線索的內容。要處理的不是「這個壓縮軟體聰不聰明」,而是「這一次打包有沒有把不該離開目前檔案的內容,以明文檔名、明文條目或弱加密流的形式交出去」。上一篇寫過:把未加密檔案直接丟進雲端硬碟,服務商、同步用戶端和秒傳還可能看到原文。先打一個帶密碼的 ZIP 再上傳,只是把問題從「雲端看不看得見檔案」換成「這個容器到底鎖了哪一層」。

本文以 PKWARE 的 APPNOTE.TXT 6.3.10(2022-11-01)、WinZip AES 規格 AE-1 / AE-27-Zip 對 7z 格式 AES-256 的說明為主,因為分層寫得清楚,也好對照本機輸出。企業政策、線上「加密壓縮」網頁和舊版本介面會再疊一層。換工具時應對著那一版的加密選項再看一遍 Method,不要把下面的 ZipCrypto 句子直接套到已經勾了 AES-256 或開啟了「加密檔案名稱」的壓縮檔上。

傳統加密、AES 擴充、檔名加密:三層不是同一層

把「ZIP 有沒有加密」聽成一個是或否,會漏掉至少三層。第一層是傳統 PKWARE 加密,也就是軟體裡常標成 ZipCrypto 或 Zip 2.0 的那一種。APPNOTE 第 6 節把它的對象寫得很窄:PKZIP 加密的是壓縮後的資料流。每一條被加密的檔案,資料區開頭多 12 位元組加密頭;三組 32 位元金鑰用密碼初始化,再用和 ZIP 相同的 CRC-32 去更新。副檔名還是 .zip,檔案總管或舊解壓縮程式往往能跳出密碼輸入框,相容性好,強度是另一回事。

第二層是後來加進 ZIP 容器的 AES。WinZip 不改基本結構,只加一件事:壓縮方法寫成十進位 99,再在本地檔頭和中央目錄各放一段額外欄位 0x9901,一共 11 位元組,廠商代號是 ASCII AE。強度位元組 0x01 / 0x02 / 0x03 分別對應 128、192、256 位元金鑰。真正的壓縮方法(例如 Deflate 的 8)挪進這段額外欄位。不解 AES 的舊工具通常會報「不支援的壓縮方法 99」,而不是誤把密文當明文解出來。這一層保護的是檔案內容,預設並不把中央目錄裡的檔名改成密文。

第三層是「連目錄一起罩住」。ZIP 的 Strong Encryption 把中央目錄加密寫成可選項,還要用 general purpose bit 6、bit 13 等旗標;傳統 ZipCrypto 沒有這一層。7-Zip 的 .7z 格式走另一條路:官方頁寫明用 AES-256,金鑰由基於 SHA-256 的派生函式從密碼算出來,並且用大量迭代提高窮舉代價。命令列的 -mhe=on 會加密檔名。沒開啟這一項時,即使內容是 AES,列出壓縮檔仍可能先看到名字。

分層 通常鎖住什麼 預設仍可能看見什麼 怎麼當場認
ZipCrypto / 傳統 PKWARE 該條檔案的壓縮資料流 檔名、未加密條目、包結構 7z l -slt 裡 Method 含 ZipCrypto
WinZip AES(AE-1 / AE-2) 該條檔案內容(AES + HMAC) 檔名;同一包裡未加密的其他條目 壓縮方法 99,額外欄位 0x9901,Method 含 AES-
7z + 加密檔名 內容和目錄檔頭 未開啟 -mhe=on 時仍可能先看到檔名 7-Zip 對話方塊裡的「加密檔案名稱」,或命令列 -mhe=on

產品頁或右鍵選單寫「AES-256」只回答內容用了什麼演算法,不回答檔名在不在明文檔頭裡,也不回答包裡有沒有沒設密的條目。核對時先看 Method 和檔名列表,再看密碼有多長。

ZipCrypto:規格自己寫成弱,擋不住已知明文這條研究線

傳統加密不是「民間誤傳很弱」,是格式定義者自己降過級。APPNOTE 6.0.1 的原文是:這種形式 considered weak by today's standards,只建議用於低安全需求,或為了相容更老的 ZIP 程式。演算法骨架也寫在同一節:金鑰初值是 305419896591751049878082192 三組 32 位元整數;update_keys 每處理一個密碼位元組就呼叫一次 CRC-32;資料區開頭 12 位元組加密頭用來繼續攪動金鑰,最後 1 或 2 個位元組對照 CRC 高位,用來判斷密碼對不對。這是串流密碼,不是 AES-GCM 那種帶驗證標籤的區塊模式。

規格裡寫過:12 位元組頭的目的是「讓針對資料的明文攻擊變得無效」。公開文獻走的是另一條路。Eli Biham 與 Paul C. Kocher 在 1994 年發表 A Known Plaintext Attack on the PKZIP Stream Cipher,說明在知道一段明文的條件下可以還原內部狀態。Michael Stay 在 2002 年的 ZIP Attacks with Reduced Known Plaintext 把所需明文量又壓低。壓縮檔裡經常自帶可預測前置碼:PDF 的 %PDF、Office 文件的固定檔頭、XML 宣告、PNG 簽章。攻擊細節不屬於本文範圍;重點是:弱點在演算法,不在「你的密碼只有 6 位」。密碼再長,也改變不了「傳統加密被規格寫成弱、並且存在已知明文這條研究線」這件事。

相容性解釋了它為什麼還在。Windows 檔案總管可以建立和開啟普通 ZIP,但沒有原生「幫 ZIP 設密」的介面;Microsoft Q&A 上的獨立顧問回覆寫過:要設密得用 7-Zip 這類第三方工具,檔案總管對第三方打出來的 ZipCrypto 包往往還能跳出密碼輸入框。macOS Finder 的「壓縮」同樣沒有密碼選項。於是不少軟體把 ZipCrypto 留作預設,好讓對方連按兩下就能解。你圖的是「對方不用另外裝軟體」,付的是規格自己承認的弱加密。7-Zip 打 ZIP 時可以改成 AES-256;改完之後,只認 ZipCrypto 的系統解壓縮程式可能直接打不開。這是相容和強度之間的取捨,不是「兩種都叫加密所以一樣」。

檔名、CRC 和未加密條目:沒進密文流的東西還在明文裡

即使內容層換成了 AES,ZIP 預設仍是「能列出目錄的容器」。本地檔頭和中央目錄裡的 FileName 是明文字段;general purpose bit 0 只表示這一條的資料流加密了。bit 11 表示檔名用 UTF-8,不表示檔名被加密。Tadayoshi Kohno 在 2004 年對 WinZip 加密方案的分析裡,把三件格式事實寫得很清楚:加密檔案的中繼資料會外洩、檔名未經驗證、同一壓縮檔可以同時包含加密和未加密檔案。這些不是實作缺陷,是容器允許的形狀。

WinZip 自己的 AES 說明把「混合包」寫成正式許可:沒有要求一個 ZIP 裡的檔案全部加密,也沒有要求加密檔案用同一種方法或同一句密碼;一個包可以任意組合未加密檔案,以及 Zip 2.0、AES-128、AES-192、AES-256。資料夾條目甚至被建議不要加密,以減少體積。結果是:你把 薪資-2026-09.xlsxreadme.txt 打進同一個包,可能只有試算表問密碼,說明檔和目錄名稱誰都能讀。外發時對方、郵件閘道、雲端硬碟預覽和同步用戶端,先看到的常常是這張目錄,不是解開後的儲存格。

明文檔頭裡還有體積和校驗。WinZip 寫明:AE-1 在 ZIP 檔頭裡存放未加密內容的 CRC,AE-2 把 CRC 寫成 0,改用 10 位元組驗證碼查完整性。原因寫在 FAQ:對只有四個位元組或更短的檔案,CRC 本身就能幫助推斷原文,與用哪種加密無關。WinZip 11 起對大多數檔案改回 AE-1 以多做一次完整性核對,但對未壓縮大小小於 20 位元組的檔案,以及自帶校驗的 BZIP2,仍用 AE-2、不存 CRC。金鑰派生是 PBKDF2(RFC 2898),迭代 1000 次,偽隨機函式是 HMAC-SHA1;規格也寫了 HMAC-SHA1 輸出 160 位元,因此 192 / 256 位元 AES 的有效搜尋空間不能按理論金鑰長度去理解。這些數字不需要你去「破解」才能核對——它們已經寫在公開規格裡。

當場核對:不解出原文,先看 Method 和檔名

口號寫「我設了密碼所以安全」沒辦法證明。把核對拆成可以在本機做完的幾步,每一步只回答一個問題。不要對真實薪資表、憑證或私鑰做實驗。

不要用正在使用的證件掃描檔、正式環境金鑰或真實員工表打包「看看長什麼樣」。準備一份可以丟棄的金絲雀,例如檔名 canary-payroll-20260905.txt、正文只寫一行一次性標記。核對的是目錄和 Method,不是把真檔再壓縮一遍。

  1. 用記事本寫一份金絲雀文字,檔名故意帶業務含義,例如 canary-payroll-20260905.txt。需要隨機密碼時,用密碼產生器抽出 6–128 位(預設 16;低於 8 位會提示較弱),只把這串當成壓縮檔密碼,不要當成新的登入口令。
  2. 按你平時外發的方式打一個 ZIP:有的軟體預設 ZipCrypto,有的要手動選 AES-256。不要改檔名去「隱藏」主題。再另外打一份 7z,分別開啟和關掉「加密檔案名稱」,方便對照。
  3. 不要輸入密碼。用 7-Zip 開啟或在終端機執行 7z l -slt canary.zip。看檔名列表是否已經出現 canary-payroll-20260905.txt。再找 Method = 這一列:出現 ZipCrypto 就是傳統加密;出現 AES-256 才是內容層 AES。不解出正文也能讀到這兩項,說明它們不在「必須先輸入密碼」那一層。
  4. 對 7z 再列一次。沒開檔名加密時,名字往往仍在列表裡;開了 -mhe=on 之後,未輸入密碼應看不到那條金絲雀檔名。這是第三層在不在的對照,不是「7z 一定比 ZIP 神祕」,差在目錄檔頭有沒有被罩住。
  5. 把金絲雀壓縮檔丟進你平時用的雲端硬碟或郵件草稿(不要寄給別人)。看預覽或網頁版是否直接列出內部檔名。上一篇寫過:未加密檔案的秒傳和預覽要看到原文;這裡即使內容鎖住,目錄名稱仍可能先被索引。核對結束後刪除金絲雀壓縮檔和原始檔,並檢查資源回收筒。

第一段核對的細節——本機有沒有把明文正文交給壓縮軟體——和線上加密安全嗎?怎麼當場核對明文沒有離開本機不同:壓縮軟體幾乎一定會在本機讀入原文才能打包。本文要核對的是「打包之後,沒進密文流的東西還剩什麼」。金絲雀檔名若在未輸入密碼時就出現在 7z l -slt 或雲端硬碟預覽裡,說明信任邊界比「對方沒有密碼」大。Method 仍是 ZipCrypto,說明你圖的是相容,不是規格意義上的強加密。

用開啟即用的檔案加密盒,把「整份檔案」和「壓縮檔密碼」分開

若你要的是「先在本機把整份檔案打成密文,再決定用郵件還是雲端硬碟外發」,不必先註冊,也不必把檔案交給 MakePwd。開啟檔案加密盒,在目前分頁用 AES-256-GCM 分塊加密,下載 .lock.enc。密碼經 PBKDF2-HMAC-SHA256、100,000 次迭代派生,每個檔案獨立鹽值;單檔最大 5 GB。檔案、密碼和明文都不會作為業務資料上傳。全部工具開啟即用,沒有帳號,也沒有密碼庫替你保管這串密碼。

檔案加密盒回答的是「這一份位元組在離開瀏覽器之前有沒有變成密文」,不回答「ZIP 預設鎖不鎖檔名」。下載檔名由你決定,不必再用 薪資表-2026.xlsx.zip 這種自己洩漏主題的名字。密文可以走雲端硬碟或郵件;密碼請走另一條通道,例如閱後即焚:金鑰放在 URL 的 # 片段,不隨 HTTP 送給伺服器,建立與閱讀都公開,伺服器端只暫存密文。需要隨機密碼時,用密碼產生器抽出 6–128 位,只在本頁複製。把未加密檔案直接丟進雲端硬碟會怎樣,見上一篇;本文只把「帶密碼 ZIP 還剩什麼」收進結論。

常見問題

ZIP 設了密碼,是不是整包都加密了?

不是。PKWARE APPNOTE 把加密旗標寫在每一條檔案的 general purpose bit 0 上,加密的是該條壓縮資料流,不是整個容器。檔名寫在本地檔頭和中央目錄裡。WinZip 的 AES 說明寫明:同一 ZIP 可以混用未加密條目,以及 Zip 2.0、AES-128、AES-192、AES-256 四種方法,密碼也可以不同。

ZipCrypto 和 AES-256 ZIP 差在哪?

ZipCrypto 是 APPNOTE 第 6 節的傳統 PKWARE 加密:三組 32 位元金鑰、12 位元組加密頭、用 CRC-32 更新金鑰。規格自己寫成「以今天的標準來看是弱的」,只建議低安全需求或相容舊程式。WinZip AES 用額外欄位 0x9901、壓縮方法 99,以及鹽、密碼校驗值和 HMAC-SHA1 驗證碼。副檔名都是 .zip,必須看 Method,不能看副檔名。

不輸入密碼,能不能看到裡面有什麼檔案?

傳統 ZIP 和未開啟檔名加密的壓縮檔,通常可以。7-Zip 的 7z l -slt 會列出檔名和 Method,不需要先解出明文。7z 格式可以勾選「加密檔案名稱」(-mhe=on),那一層才會把目錄檔頭也罩住。Windows 檔案總管和 macOS Finder 的「壓縮」都沒有原生「幫 ZIP 設密」的介面。

帶密碼的 ZIP 和 MakePwd 檔案加密盒是同一件事嗎?

不是。壓縮檔密碼回答的是「這個容器用了哪一種 ZIP 加密」。檔案加密盒在目前分頁用 AES-256-GCM 加密整份檔案,輸出 .lock / .enc,單檔最大 5 GB,檔案與密碼不上傳,開啟即用。密碼應走另一條通道,例如閱後即焚連結的 # 片段。

下次打壓縮檔前記住的三件事

第一,「設了密碼」只說明至少有一條檔案的資料流按某種 ZIP 加密罩住了,不說明整包目錄不可讀,也不說明每一條都加密。第二,ZipCrypto(規格寫成弱、存在已知明文研究線)、WinZip AES(內容層更強,檔名預設仍在明文檔頭)和 7z 的檔名加密是三套不同的邊界;副檔名都叫 .zip.7z 說明不了你在哪一層。第三,用一次性金絲雀按 7z l -slt 的 Method 和未輸入密碼就能看到的檔名核對,不要用真實表格做實驗。

若你還要繼續追問「未加密檔案丟進雲端硬碟之後服務商還看得見什麼」,請讀把未加密檔案直接丟進雲端硬碟,服務商、同步用戶端和秒傳還可能看到什麼。產生或加密過程要當場核對明文沒有離開本機時,可讀線上加密安全嗎?怎麼當場核對明文沒有離開本機。密碼要另發給對方、又不想走郵件正文時,見URL 的井號後面為什麼適合放金鑰,以及什麼時候會失效。本文只把「打了帶密碼 ZIP 之後,預設加密、檔名和未加密條目還可能剩什麼」收成可以寫進結論的範圍。