FR-169 · 需求討論稿 · 2026-10-29(v3 待審)

下載檔加密

下載下來的檔案本身帶密碼;密碼由系統當場產生、畫面只顯示一次;不裝軟體、不寄信;主系統與 Agent 同一套

報表、證據包從系統下載到電腦後是明文,別人走到這台電腦、雙擊就能看。本案讓每一份下載出去的檔自己帶鎖:Word、Excel、PDF 用檔案格式內建的開啟密碼,雙擊會先問密碼,Word、Acrobat、Chrome 都能直接開;證據包、圖片、log 這類多檔或非文件打成加密 7z。密碼由系統產生、按下載前在畫面上只顯示一次,不存、不寄信,忘了就重新匯出一份。加密邏輯寫成一支獨立小套件,主系統與 Agent 各自一行接上,Agent 離線照常可用。決策者已裁:不做撤銷、不做到期、不做 IRM/DRM。

已定:威脅是「別人坐到我電腦雙擊」、原生密碼不裝軟體、系統產密碼畫面顯示一次、不寄信、獨立小套件、不做撤銷與 IRM、使用者不能選不加密、管理員開關預設開且關閉有警示 待裁:D1~D4、D6~D8(套件名、密碼形態、多檔格式、浮水印、Agent 政策下發、線上看、密碼在哪產) 前作:FR-166/166.1 Agent 主控台與 file.download 權限、FR-133 錯誤追蹤遮罩、FR-145.3 結案報告浮水印 雛形:prototype/index.html(六個畫面)
§1

這案要解決什麼

明文16 支匯出端點吐出的檔落到電腦上都沒鎖

0 筆下載這件事現在沒有稽核紀錄,外流無法追責

2 邊主系統與 Agent 主控台各有下載出口,Agent 可能離線

0 套使用者要裝的軟體:Word、Acrobat、Chrome 本來就會問密碼

要擋的只有一件事:檔案下載到電腦後,別人走到這台電腦雙擊就能開。

不在這案的(決策者 2026-10-29 裁示):檔案離開系統後遠端收回、到期、禁轉傳、追蹤誰轉給誰——那是 IRM/DRM 的領地,要客戶裝 client,決策者原話「先不做撤銷」。螢幕截圖與拍照任何方案都擋不了,不假裝。

工研院那種要用解密軟體的我覺得很麻煩,才想說有沒有其他模式。 — 決策者原話(2026-10-29)

§2

分工概述(30 秒版)

整案:一支獨立加密套件 + 一個「密碼只顯示一次」對話框 + 安全政策多一段 + 每次下載寫稽核。主系統與 Agent 同一套。

期 做什麼 產出 完成怎麼判定(決策者檢查法)
一 先看到效果 新套件 jedi-file-protect(暫名,D1):產密碼、PDF/Office/7z 三種加密、浮水印;FE 匯出對話框;先接「稽核計畫匯出」與「結案報告」兩個端點 按匯出跳對話框、下載到的 PDF 雙擊要密碼 DEV 稽核計畫頁按匯出 Word,對話框顯示 16 碼密碼;複製後下載;雙擊檔案 Word 問密碼,貼上才開;按取消不產檔;再按一次匯出密碼不同
二 全部出口接上 主系統其餘 14 支匯出端點;Agent 主控台報告與檔案下載;證據包、診斷包改加密 7z 任何「匯出/下載」都走同一個對話框 翻一遍每個有下載鈕的頁面都跳對話框;拿 7z 用 7-Zip 開要密碼、用 Windows 內建解壓會說不支援(對話框有提醒);拔 Agent 網路後在主控台下載照常跳對話框
三 開關、稽核、浮水印 安全政策頁多一個「檔案下載保護」開關(預設開);關閉時寫稽核事件、安全政策頁與系統總覽常駐警示、每筆下載標「未加密」;開關值隨心跳下發 Agent;每次下載寫稽核事件;PDF/Word 蓋下載者浮水印 出貨就是全部加密;客戶 IT 真要關有一條正規、有紀錄、被看見的路 關掉開關後:匯出不跳對話框直接給檔、安全政策頁與總覽出現紅字「檔案下載保護已關閉」、稽核事件多一筆 SECURITY_POLICY_UPDATED、之後每筆下載事件標「未加密」;開回來全部恢復;Agent 下一次心跳後跟著變;開 PDF 每頁角落有下載者帳號與時間

依賴:一先做;二、三可以同時做。決策者功課:D1 套件名、D2 密碼形態、D4 浮水印要不要。

§3

完整走一次:稽核員下載稽核計畫

  1. 稽核員在稽核計畫頁按「匯出 Word」。
  2. 跳出對話框:「這份檔會加密。密碼只顯示這一次,請先複製再下載。」下方是 Kq7m-Xw2p-Rt9v-Bn4z,旁邊「複製」鈕。
  3. 按「複製」,再按「下載」。瀏覽器下載 audit-plan-2026-10-29.docx。
  4. 對話框關閉,密碼從畫面消失。系統寫一筆稽核事件:誰、何時、哪份、已加密。
  5. 稽核員把密碼貼進公司的密碼管理器。
  6. 下午同事走到這台電腦雙擊那個 docx,Word 跳出密碼框,開不了。
  7. 一週後稽核員忘了密碼,回系統再按一次匯出,拿到新檔新密碼。舊檔沒人開得了。

Agent 主控台走同一條,差別是第 4 步的稽核事件先寫在 Agent 本機、連線後跟其他事件一起回主系統。

%%{init: {'theme':'base','themeVariables':{'primaryColor':'#E2F0F1','primaryTextColor':'#14201F','primaryBorderColor':'#0E7C86','secondaryColor':'#EEF2F3','secondaryTextColor':'#14201F','tertiaryColor':'#FBFCFC','tertiaryTextColor':'#14201F','lineColor':'#4A5A5C','textColor':'#14201F','mainBkg':'#E2F0F1','nodeBorder':'#0E7C86','nodeTextColor':'#14201F','edgeLabelBackground':'#FBFCFC','titleColor':'#14201F','clusterBkg':'#FBFCFC','clusterBorder':'#E4EAEB','actorBkg':'#E2F0F1','actorTextColor':'#14201F','actorBorder':'#0E7C86','actorLineColor':'#C7D1D2','signalColor':'#4A5A5C','signalTextColor':'#14201F','labelBoxBkgColor':'#EEF2F3','labelBoxBorderColor':'#C7D1D2','labelTextColor':'#14201F','loopTextColor':'#14201F','noteBkgColor':'#F6EBD5','noteTextColor':'#14201F','noteBorderColor':'#9C6B12','activationBkgColor':'#EEF2F3','activationBorderColor':'#C7D1D2','sequenceNumberColor':'#FFFFFF'}}}%%
sequenceDiagram
    participant U as 使用者(瀏覽器)
    participant FE as 前端對話框
    participant BE as 主系統或 Agent
    participant P as jedi-file-protect
    U->>FE: 按「匯出」
    FE->>BE: 問政策(一律/可選/不加密)
    BE-->>FE: 一律加密
    FE->>FE: 在瀏覽器端產 16 碼密碼,顯示一次
    U->>FE: 複製密碼、按「下載」
    FE->>BE: GET /export?format=docx(密碼放 header,不放 URL)
    BE->>BE: 產出原本的 docx
    BE->>P: protect(bytes, 檔名, 密碼, 浮水印資訊)
    P-->>BE: 加密後 bytes、新檔名、是否需 7-Zip
    BE->>BE: 寫稽核事件(不含密碼)
    BE-->>FE: 檔案(Cache-Control: no-store)
    FE-->>U: 瀏覽器下載;對話框關閉,密碼清掉
圖 1 — 下載一次的時序;密碼不存、不進 log、不出伺服器任何其他通道
§4

已經定案的

威脅模型:擋「別人坐到我電腦雙擊」,不擋「檔案離開後收回」

決策者 2026-10-29 裁示先不做撤銷。IRM/DRM/自建 HTML 殼都因此排除。

檔案格式內建的開啟密碼,不裝軟體

Word、Excel、PDF 的規格本來就定義了加密方式,加密完還是正常的 .docx/.xlsx/.pdf,Word、Acrobat、Chrome、手機閱讀器自己跳密碼框。只有「開啟密碼」算加密;「限制編輯/禁列印」那種權限密碼內容仍是明文、一鍵可拆,不當保護宣稱。

密碼由系統產生、畫面只顯示一次、不存、不寄信

不要使用者自己想密碼。不存 DB、不進 log、不進錯誤追蹤站;忘了就重新匯出一份新檔新密碼,沒有「重寄」。不寄信的直接好處:Agent 離線照常可用,不必把通知模組搬進 Agent;密碼與檔案天然走不同通路。

使用者永遠不能選「不加密」;管理員有一個開關、預設開、關閉有警示(決策者 2026-10-29 兩輪後定)

對話框裡只有「複製密碼、下載」或「取消」。安全政策頁是一個開/關,不是三選一,出貨預設開。關閉是明確、有紀錄、被看見的管理員決定:寫稽核事件、安全政策頁與系統總覽常駐紅字「檔案下載保護已關閉」、之後每筆下載事件標「未加密」。為什麼留開關而不是寫死強制:我們自己的 e2e 回歸與教育訓練每天都在下載、客戶若已有 DLP 一落地就加密會變成兩層、匯出的 Excel 要餵別的系統時加密檔開不了——這三種情境要有正規出口,否則使用者會自己繞。反悔條件:上線後客戶普遍一裝就關,改成不可關。

獨立小套件,不放 jedi-file-upload、不塞 jedi-common

jedi-file-upload 帶整套資料庫與物件儲存相依,Agent 現在不依賴它,且記憶體現產的報表不經過它的簽票層;jedi-common 是 25 支套件的共同底,塞進 pypdf、Office 加密、7z 會讓用不到的套件都多裝。先例是 jedi-masking、jedi-integrity 這種「一件事、零框架相依」的小套件。未來診斷包、資料庫備份下載、授權檔匯出都會用到。

§5

待決策

D1 套件名稱

選項:jedi-file-protect(出檔前保護,含加密與浮水印)/jedi-file-crypto(只講加密)/jedi-export-guard。

建議:jedi-file-protect。它做的不只加密,浮水印也在裡面;「protect」對到 Office 選單上的「保護文件」,使用者語彙一致。

D2 密碼長什麼樣

檔案密碼可以離線用顯卡無限次試,所以不能照登入驗證碼做成六碼數字(幾分鐘破)。選項: ① 16 碼隨機英數分四段(Kq7m-Xw2p-Rt9v-Bn4z),約 95 位元強度; ② 五個隨機單字(tiger-maple-orbit-canvas-brick),好唸好抄,約 64 位元,單字表要自備; ③ 20 碼含符號,最強但難抄。

建議:①。分段好對照、純英數不會被 Word 密碼框吃掉符號、強度足夠(每秒十億次試要幾千年)。去掉易混字元 0/O/1/l/I。

D3 多檔與非文件(圖片、log、證據包)用哪種容器

選項: ① 加密 7z:檔名清單也加密、AES-256、py7zr 純 Python;要裝 7-Zip/Keka 才開得了,Windows 檔案總管與 macOS 內建解壓都不支援; ② AES-256 zip(pyzipper):同樣要裝 7-Zip,且檔名清單是明文(「XX公司_滲透報告.pdf」直接外露); ③ 單張圖片另外轉成一頁加密 PDF,讓 Chrome 雙擊就開。

建議:①,對話框明寫「請用 7-Zip 或 Keka 開啟」。③ 不做:為了少裝一個 7-Zip 多開一條路徑不值得。現有 zip 出口(稽核計畫 zip、前置資料全部下載、Agent 檔案包、診斷包)全改 7z。

D4 浮水印要不要、長什麼樣

密碼擋被動情境(別人雙擊);浮水印擋的是「使用者自己把檔傳出去」的追責。選項: ① PDF 與 Word 每頁頁尾小字「下載者 王大明(wang) · 2026-10-29 14:32 · Guidant AI」; ② 斜角大字滿版(銀行對保那種); ③ 不做,本案只做加密。

建議:①。結案報告已有「草稿」浮水印機制可延伸;滿版斜字會影響可讀性,稽核員會抱怨;Excel 與 7z 不蓋(Excel 沒有頁的概念,蓋了會進資料格)。

D6 開關值怎麼到 Agent

Agent 主控台也有下載,而且可能離線。選項: ① 開關值掛進心跳回應(照 FR-166 D23 權限下發的模型),Agent 存最後一份,離線沿用; ② Agent 自己一份設定,與主系統無關; ③ Agent 一律加密,不吃開關。

建議:①。一份真相;掛點 heartbeat_extras 現成;離線沿用最後一份是 FR-166 已接受的行為。密碼在 Agent 本機瀏覽器端產,稽核事件走 FR-166.1 D6 剛接好的本機 logging 管線,離線先存、連線補送。

D7 「預設線上看、不下載」要不要在這案做

前面討論提過「多數人只是要看一眼,不需要讓檔案落地」。但要做就是每個匯出頁面加預覽器,範圍是這案的好幾倍。

建議:這案不做。只做加密。Agent 主控台已有 HTML 預覽(FR-166),主系統結案報告也已有 PDF 預覽,先維持現狀;以後要做另開 FR。

D8 密碼在哪一端產、怎麼送到後端

選項:① 瀏覽器端用 crypto.getRandomValues 產、放 HTTP header 送到後端加密;② 後端產、回給前端顯示。

建議:①。密碼只在使用者瀏覽器與那一次請求裡出現,後端連「產生」這一步的 log 風險都沒有;放 header 不放 URL(URL 會進 access log、瀏覽器歷史)。陷阱:crypto.getRandomValues 在 http+IP 的頁面仍可用(它不像 randomUUID 要 secure context),但要實測一次。後端收不到 header 時回 400,不靜默吐明文。

§6

現況盤點:沿用什麼、補什麼

元件 現況 本案動作
匯出端點 16 支各自 send_file:稽核計畫(docx/pdf/xlsx/zip)、SSP、結案報告、控制項對照、RACI、風險登錄、前置資料 zip、診斷包、AI 呼叫紀錄、Agent 報告與檔案包等 各加一行呼叫共用 helper;不改各自的產檔邏輯
加密能力 主系統有 cryptography(Fernet 用於密鑰欄位)、pypdf、LibreOffice;沒有 Office 加密、7z 新套件帶 pypdf、msoffcrypto-tool、py7zr
浮水印 結案報告有「草稿」浮水印(docx 範本變數) 套件提供 PDF 與 docx 蓋頁尾小字;結案報告沿用範本變數
安全政策 system_configs 群 RUNTIME_CONFIG,型別與範圍在 jedi-iam security_policy.py;FE 頁四段(兩階段驗證、登入、密碼、權杖) 加一布林鍵 FILE_DOWNLOAD_PROTECTION(預設 true)進 BOOL_KEYS;FE 多一個開關+關閉警示
心跳下發 heartbeat_extras 已掛弱點庫、工具 schema、LDAP 設定 多掛一支帶開關值
稽核事件 audit(logger, name, EventCode, **fields);Agent 側 FR-166.1 D6 接同一套 新事件碼 FILE_DOWNLOADED,欄位:檔名、格式、是否加密(開關關閉時為否)、來源端點
FE 下載 useApExportDownload 等 composable 各自 axios blob 下載;檔名讀 X-Filename 抽一支共用 useProtectedDownload:先開對話框產密碼,確認後帶 header 下載;各頁改呼叫它
Agent 主控台 FR-166.1 D3:下載收 file.download 能力點,出貨全鎖 只有持有能力點的人會看到對話框;主控台前端接同一支 composable 的 Agent 版
§7

資料模型草案

不新增資料表。 只有:

  • system_configs:RUNTIME_CONFIG 群多一布林鍵 FILE_DOWNLOAD_PROTECTION,預設 true。
  • common/enum/event_code.py:多一個 FILE_DOWNLOADED 事件碼(Agent 側對應一個)。

密碼不落任何表。

§8

業界怎麼做

類型 代表 做法 對我們
一般 SaaS Google Drive、M365 不加密檔案;靜態加密+短效連結+審計 底線,我們已有登入守門
安全傳檔 Proton Drive、Tresorit 瀏覽器端對端加密 伺服器必須看得到內容才能產報表,不適用
GRC 同業 Vanta、Drata、AuditBoard 幾乎不加密匯出檔;靠權限、審計、浮水印、審計員入口線上看 我們多做一步
金融/政府傳檔 台灣銀行、健保署 Office/PDF 原生密碼+AES 壓縮檔,密碼走第二通道 本案採用的就是這條,但密碼改成系統產、畫面顯示(銀行用身分證字號是弱做法)
企業 IRM Purview、Seclore、工研院 開檔時向政策伺服器驗證、可撤銷 決策者裁不做
§9

排除的方案

方案 為什麼不
IRM/DRM(含工研院類、OpenTDF、Purview) 要客戶裝 client;且擋不住「同一台已登入電腦換人坐」;撤銷不在本案
自建 HTML 殼(開檔連回伺服器要鑰匙) 只有做撤銷才有存在理由;不做撤銷就只是比原生密碼多一層自建格式
使用者自訂密碼 決策者不要;會用生日、統編等可預測密碼
寄信或簡訊送密碼 Agent 離線寄不出;多一條留紀錄的通路;畫面顯示已足夠
加密 zip 當唯一手段 解開後一份明文留在電腦,下次有人坐過來一樣開;檔名明文
自製加密格式(.enc) 沒人開得了,業界無人這樣做
放 jedi-file-upload 或 jedi-common 見「已定案」第五條
「使用者可選」模式、對話框「不加密下載」 決策者裁不要;會變成習慣性點掉
寫死強制、沒有管理員開關 e2e/教育訓練、客戶既有 DLP、匯出餵別的系統三種情境沒有正規出口,使用者會自己繞;開關預設開+關閉有警示已壓掉「被關掉」的風險
§10

不做什麼

  • 撤銷、到期、追蹤轉傳、禁截圖。
  • 使用者自訂密碼、重寄密碼、個人固定匯出密鑰。
  • 線上預覽器改造(D7 建議不做)。
  • 上傳進系統的檔靜態加密(物件儲存那層,另案)。
  • 匯入功能不動:加密檔上傳進系統要先解密,那是另一個需求。
§11

先看哪裡

  1. 點 prototype/index.html:①匯出對話框(含 7z 提醒)②安全政策開關與關閉後的警示 ③Agent 主控台離線時下載。
  2. 裁 D1~D4、D6~D8。
  3. 拍板後落 design.md、拆卡。預估跨 jedi-packages(新套件)、BE(16 支端點、政策鍵、心跳、事件碼、helper)、FE(composable、對話框、安全政策段、i18n)、evidence-agent(主控台接套件與 composable)四個 repo。