豆泥關心的難題.
EN ← 回到豆泥部落格
← All essays
中文 English

數位身分 有備而來:理想的數位皮夾開發報告 第 5 篇

整合 MyData:用數位皮夾實踐資料保險箱

“MyData 平臺只傳遞資料,不簽章、不背書、八小時後清除。本文記錄有備而來把 MyData 文件收進手機保險箱的格式比較、隱私與安全設計、真實帳號的使用結果,以及讓驗證者承認這些文件、避免它們成為孤兒的政策建議。”

Anthropic Claude Fable 5.1 22 分鐘 #2026-09-05-mydata-vault-in-the-digital-wallet
AI 生成資訊

模型:Anthropic Claude Fable 5.1

生成日期:2026年9月5日

提問:依有備而來 iOS 原始碼(MyDataScratch、MyDataVaultArchive、MyDataDocumentType、MyDataPendingRequestStore、MyDataAutofillProfile)、開發交接與檢查點文件、MyData 平臺公開頁面與常見問題、數位發展部公開資料,以及真實 MyData 帳號在 iPhone 上的匯入結果,撰寫 MyData 資料保險箱的開發報告與政策建議。

這是「有備而來:理想的數位皮夾開發報告」第五篇。本文依有備而來的原始碼、開發紀錄,以及真實 MyData 帳號在 iPhone 上的實機操作撰寫。文中截圖來自開發版 App,檔案內容、姓名、統一編號與地址一律未出現。MyData 平臺的制度描述引自平臺的公開頁面與數位發展部的公開資料。

前四篇處理的是證件。自然人憑證、電信卡、政府卡片都有一個明確的簽發者,皮夾的工作是收下、保存、出示。本篇處理的對象沒有簽發者。MyData 平臺把戶籍、所得、投保、地籍這些資料從機關送到民眾手上,交付的是一份 PDF 或 CSV,平臺在交付後隨即刪除,八小時未領取也刪除。民眾拿到的是一份沒有簽章、沒有背書、沒有保存位置的文件。

有備而來把這些文件收進手機上的資料保險箱。本文記錄為什麼需要這個保險箱、儲存格式怎麼選、隱私與安全怎麼做、真實帳號用起來的結果,以及要讓這些文件在查驗端被承認還缺什麼。

MyData 的架構與它留下的缺口

MyData 平臺由數位發展部營運。依數位發展部公布的統計,平臺已介接七十餘個機關,含二十餘個地方政府,提供八百多項資料下載與服務申辦。平臺自述的核心是「民眾自主同意、資料安全取得」,運作採三方架構。資料提供機關保有原始紀錄,平臺負責身分驗證與傳輸,服務提供者(政府機關或平臺信賴的企業)在民眾單次同意下收到資料。

這個架構有四個特徵,決定了後面所有的設計。

平臺只傳遞,不留存。 平臺隱私政策寫明「資料一旦取用後,系統將立即刪除該取得之個人資料」,未取用者「本平臺將於八小時後自動刪除」。這是正確的隱私設計,平臺不該成為第二個資料庫。代價是民眾沒有任何一個由自己控制的儲存位置。今天下載的納稅證明,下個月申請貸款時要重新驗證身分、重新申請、重新等待。

文件沒有簽章。 以真實帳號下載的戶政國民身分證資料,經逐位元組檢查,十四個 PDF 簽章標記全部為零,沒有簽章字典、沒有 ByteRange、沒有簽章表單欄位、沒有夾帶的獨立簽章。檢測工具以十一份由 pyhanko 與 pypdf 產出的真實 PDF 做過對照,含加密、物件流與「已建欄位但未簽」的邊界案例,確認這個零是文件的事實,並非工具的盲點。機關的簽章存在於 API 層,簽的是機關回覆平臺的訊息,這份簽章沒有跟著文件一起交到民眾手上。

背書只在線上流程裡成立。 MyData 的臨櫃核驗要民眾出示一組二十分鐘有效的條碼,加上簡訊或電子郵件收到的動態密碼,櫃檯人員掃碼後由平臺把文件交給櫃檯。整個流程沒有驗證民眾手上那份檔案,驗證的是平臺當下重新交付的那一份。線上服務同理,服務提供者收到的是平臺直送的資料。換句話說,MyData 的信任建立在「平臺當下傳送」這個動作上,離開這個動作,文件就只是一份 PDF。

下載是同步等待,資料是非同步產出。 個人所得資料的頁面寫明「預計下載時間約 120 分鐘」,完成後以通知告知,民眾要回到個人專區的「個人文件」下載。八小時期限從這裡開始計算。

這四個特徵合起來,就是保險箱的需求。民眾需要一個地方保存這些文件,保存時要能證明它沒有被改過,未來要能只揭露其中一個欄位,而且這個地方要比雲端硬碟或相簿更嚴格。數位皮夾已經具備每卡獨立金鑰、Secure Enclave、選擇性揭露與出示流程,是承接這個需求最自然的位置。

儲存格式的比較與決定

規劃初期評估過五種做法。比較的標準有四項。第一,能不能離線驗證。第二,能不能只揭露一個欄位。第三,能不能證明文件與下載當時一致。第四,與 App 既有的 SD-JWT-VC、OpenID4VP 堆疊是否相容。

做法離線驗證逐欄揭露原檔一致性與既有堆疊評估
保存原始 PDF 或 CSV,附 SHA-256 指紋可不可可中立採用,作為唯一事實來源
解析欄位後包成持有人簽署的 SD-JWT-VC可可以指紋綁定完全相容採用,作為衍生層,依需要產生
JSON-LD VC 加 BBS+ 簽章可可,且不可關聯需另做第二套堆疊保留,待不可關聯性成為硬需求
ISO 18013-5 mdoc可可需另做第二套堆疊延後,實體 NFC 場景才需要
Solid Pod(個人資料儲存協定)不可,驗證方要連線讀 Pod協定本身不提供需另做完全不同的層不採用

拍板的設計有兩層。原始檔是唯一事實來源。 保險箱保存機關產出的檔案本身,連同 SHA-256 指紋與匯入時間。使用者可以隨時重新開啟、重新驗證指紋、重新下載取代、單項刪除。憑證是衍生物。 需要出示的時候,才從原始檔解析欄位,由持有人以自然人憑證或每卡金鑰簽署成 SD-JWT-VC,並在憑證裡記錄來源文件的指紋、文件類型與解析器版本。這張憑證的信任標籤固定為「持有人從 MyData 文件衍生」,畫面與查驗端都不會把它顯示成政府簽發。

早期版本走過相反的路。App 曾為了在首頁顯示保險箱文件,把每一份都自簽成一張憑證。這個做法後來被撤回,理由是自簽並沒有增加信任根。下載的檔案本來就沒有簽章,用手機金鑰重簽欄位,得到的信任不會比原檔更強,反而讓「證件」與「文件」在使用者眼中混成一種東西。撤回後的首頁把「自發國民身分證」、「政府皮夾卡片」與「MyData 資料保險箱」分成三個區塊,保險箱直接從原始檔清單,不再為顯示製造憑證。

為什麼沒有用 Solid

Solid Protocol 在規劃階段被認真評估過,因為它與「個人資料由個人控制」的目標在語言上非常接近。最後不採用,原因有三。

第一,層次不同。Solid 是儲存與存取控制的協定,規範資料放在哪個 Pod、誰可以讀。它不簽章、不做選擇性揭露、不定義憑證格式。就算採用 Solid,上面仍然要疊一層 SD-JWT-VC 或同等的憑證格式,才能回答「這個欄位是誰說的」。Solid 解決的問題與這裡要解決的問題不重疊。

第二,驗證方向相反。Solid 的模型是驗證方連線到持有人的 Pod 讀取資料,這需要一個永遠在線的伺服器與一套存取授權。數位皮夾的模型是持有人把一份自帶簽章的位元組交出去,查驗方離線也能驗。第二篇的超商取貨與第三篇的離線藍牙出示都依賴後者。引入 Solid 等於為每一次出示加上一個網路依賴與一個可用性風險。

第三,生態對齊。數位發展部的數位憑證皮夾、歐盟 EUDI 的架構參考框架,都往 SD-JWT-VC 與 mdoc 收斂。有備而來的政府卡片、驗證器與 OpenID4VP 出示已經全線走 SD-JWT-VC。保險箱沿用同一條路,不用維護第二套簽章、驗證與出示程式。

Solid 適合的場景是多方協作的動態資料,例如社群貼文、行事曆、共同編輯的紀錄。政府核發的靜態文件,需要的是不可否認的簽章與可離線的出示,這兩件事 Solid 都交給別人做。

為什麼 zkPDF 與 zkTLS 也難以介接

除了儲存格式,規劃階段還評估過兩條以零知識證明直接為 MyData 文件建立信任根的路。兩條都在評估與實測之後排除。密碼學本身沒有問題,卡住的地方是 MyData 交付資料的方式。

zkPDF 的前提是文件帶簽章。 隱私與規模探索小組(PSE)的 zkpdf 能在電路裡驗證 PDF 內嵌的 PKCS#7 RSA-SHA256 簽章,再證明某一頁出現某段文字,持有人不必交出整份文件。這條路一度是首選,開發時的分岔表寫著「有簽章就走 zkpdf」。真實帳號下載的戶政 PDF 量出十四個簽章標記全為零之後,這條路關閉。沒有簽章的 PDF 放進 zkpdf,能證明的只有「這份檔案含有這段文字」,任何人用文書軟體都能做出同樣的檔案,證明不了機關說過這些話。

即使未來文件帶了簽章,還有三個介接障礙要先解決。第一,MyData 的 PDF 以標準安全處理器加密,密碼是統一編號,內容串流是密文,電路要先解密再解壓縮才看得到文字,或者在電路外解密後把明文交給證明器,後者等於把整份文件交出去。第二,中文 PDF 的文字以 CID 與 CMap 對照表編碼,要在電路內抽出「臺北市」三個字,字型對照表也要進電路,這部分的支援程度隨每份文件的產生工具而異,八個機關的產出工具並不相同。第三,zkpdf 以 SP1 zkVM 產生證明,設計上由證明網路或桌機執行,手機端在數分鐘與數 GB 記憶體之外沒有可行的路徑;在遠端產證又必須上傳明文 PDF,隱私前提隨之消失。第四篇量到 OpenAC 電路在手機上需要數秒、驗證端需要半 GB,zkVM 路線的成本高出一到兩個數量級。

zkTLS 證明的是網站說過什麼,不是機關簽過什麼。 TLSNotary 一類的協定讓持有人與一個公證方共同執行 TLS 連線,公證方看不到明文,事後為傳輸內容簽一份承諾,持有人再選擇性揭露其中一段。用在 MyData 上,理論上可以證明「mydata.nat.gov.tw 在這次連線裡回傳了這份檔案」。實際評估後有五個問題。

  1. 連線的另一端是行動自然人憑證,不是單純的 HTTPS。 MyData 的身分驗證會把使用者交棒到行動自然人憑證 App,簽完再回來,所得資料還要等兩小時後從個人專區另起一次連線下載。MPC-TLS 要求公證方從握手開始全程參與同一條連線,App 之間的交棒與非同步的下載把「一條連線」拆成好幾條,證明無法涵蓋整個因果鏈。
  2. 回傳的是加密的 ZIP,不是可讀的欄位。 zkTLS 承諾的是傳輸位元組。要對「所得是否高於門檻」做選擇性揭露,得在證明裡解壓縮、解密、解析 PDF,這又回到 zkPDF 的問題。承諾一段密文,能揭露的只有密文本身。
  3. TLS 版本。 實測 mydata.nat.gov.tw 預設協商 TLS 1.3,仍接受 TLS 1.2。TLSNotary 文件寫明目前支援 TLS 1.2,1.3 在路線圖上。今天能接,平臺一次安全升級就會斷。
  4. 信任錨是網站憑證,不是機關印信。 zkTLS 證明的效力綁在 mydata.nat.gov.tw 的 TLS 憑證,由臺灣網路認證公司簽發,屬於網頁公開金鑰基礎建設。查驗方因此要相信兩件事,網頁憑證體系與公證方不串通。這兩者都不在數位發展部的信任清單裡,一個政府查驗方沒有理由接受它。TLSNotary 自己的文件也寫明,查驗方只在信任公證方時才接受簽署的資料。
  5. 證明綁定網頁結構。 證明所指的內容是網頁回應的位元組位置,平臺任何改版都會讓既有證明失去意義。文件簽章不隨網頁改版失效,這正是簽章與 zkTLS 的根本差異。

兩條路都指向同一個結論。零知識證明可以隱藏欄位,不能無中生有製造信任根。信任根要由資料提供機關在交付時放進文件,方式是簽章或直接發出憑證。文件一旦帶了簽章,zkPDF 會重新成為比持有人代簽更強的選項;在那之前,保險箱保存原始檔與指紋,是唯一誠實的做法。

隱私與安全的設計

保險箱處理的是 App 接觸過最敏感的資料,設計上分成兩套不同的紀律。

國民身分證資料維持銷毀原則。 戶政 PDF 含姓名、統一編號、地址、全戶成員,下載後放在暫存目錄的隔離區,解壓縮時檢查每一個項目的路徑防止 zip-slip,讀出位元組後立即清除,再進入需要使用者互動的步驟。到 App 要求輸入統一編號解密的時候,磁碟上已經沒有東西需要保護。這條路徑的產物只有一張經自然人憑證簽署的選擇性揭露憑證。

保險箱文件保存原始檔,但用同一級保護。 使用者選擇匯入的財力、投保、稅務、地籍、戶籍文件,原始檔寫入 Application Support,永遠不進 Documents,因為 Documents 會發佈到「檔案」App,任何拿到解鎖手機的人都能瀏覽、AirDrop、複製,也會進每一次 iCloud 備份。檔案保護等級設為 completeUnlessOpen,鎖定時不可讀,但允許自動鎖定後仍能完成一筆寫入。整個目錄標記為排除備份,原始紀錄不會離開這支手機。每份原始檔旁有一個中繼檔記錄寫入當下的 SHA-256,詳情頁每次開啟都重算比對,不符時明確顯示「檔案與匯入時保存的指紋不符」。

有備而來保險箱裡地籍及實價資料的詳情頁,列出文件類型、來源、匯入時間、檔案格式、SHA-256 檔案指紋與完整性查核通過,下方有查看原始文件與匯出或分享副本
圖一。保險箱文件的詳情頁。指紋在每次開啟時重算,「查看原始文件」在記憶體內渲染 PDF,不寫出任何預覽檔;「匯出或分享副本」前會再確認一次,並說明副本離開保險箱後不再受保護。

預覽不落地。 「查看原始文件」把 PDF 位元組直接交給渲染器,MyData 常見的 ZIP 包 PDF 在匯入時就解開只留 PDF,預覽過程不產生任何可被其他 App 讀到的檔案。分享是唯一讓資料離開保險箱的路徑,按下前會出現確認,寫明副本將不再受保護,請確認收件人與目的地。

常用資料只填給官方網站。 MyData 每次調閱都要輸入統一編號與出生日期。App 提供選填的「常用資料」,存在 iOS 鑰匙圈、限定本裝置、不進備份,只會自動填入 mydata.nat.gov.tw 的官方頁面,不會傳給有備而來的任何伺服器,也不會寫進任何憑證。

有備而來的 MyData 常用資料頁,兩個欄位為臺灣身分證統一編號與出生日期,下方說明只保存在這支 iPhone 的鑰匙圈,只會填入官方 mydata.nat.gov.tw,不會傳給有備而來,也不會納入備份
圖二。常用資料的保存範圍在畫面上寫清楚。這兩個值是 MyData 登入與檔案解密的必要輸入,App 只代填,不代管。

未完成的調閱只記錄中繼資料。 所得資料要等兩小時,這段時間不該綁著一個網頁視圖。App 記錄的待處理項目只有文件識別碼與發起時間,沒有統一編號、生日、檔名或任何欄位。八小時後自動忘記,因為平臺那邊的檔案也已經不存在,不該再對使用者說有東西在等。

取用需要解鎖。 進入保險箱要通過 Face ID 或裝置密碼,解鎖後有十分鐘寬限。刪除一份文件會同時移除原始檔與指紋中繼檔,不留孤兒。

這些設計都有對應的單元測試,其中解壓縮路徑防護、指紋比對與刪除的完整性用突變測試反向確認過,把檢查改壞時測試必須轉紅。

真實帳號的使用結果

保險箱已在 iPhone 上以真實 MyData 帳號完成匯入。登錄表裡的八個項目中,納稅證明、個人所得資料、健保投保資料、健保保費繳納紀錄、地籍及實價資料、戶籍謄本六份已經進入保險箱,全部標示「已保存原始檔」,格式有 PDF 也有 ZIP。

有備而來首頁的 MyData 資料保險箱區塊,六份文件依序為納稅證明、個人所得資料、健保投保資料、地籍及實價資料、健保保費繳納紀錄、戶籍謄本,各標示已保存原始檔,最下方顯示格式與匯入時間,上方是一張政府皮夾卡片
圖三。保險箱的文件清單。每一列只有文件類型與保存狀態,格式與匯入時間放在卡片底部,任何內容欄位都不出現在這一層。上方的政府皮夾卡片來自另一條線,信任來源標示為數位發展部信任清單,與保險箱的「已保存原始檔」形成對照。

過程中確認了幾件只有真實帳號才量得到的事。

八個資料項目的路徑都是真的。 平臺每個項目的網址形狀一致,都是 personal/detail/API. 加一段代碼。所得、勞保投保、健保投保、健保保費、納稅證明、勞退提繳、地籍實價、現戶戶籍八個項目的代碼都從平臺本身查得,並寫進 App 的文件登錄表。學歷證明刻意排除,平臺 141 個文件項目裡沒有任何一個對應畢業或學位,教育部的學位驗證走另一套系統,屬於不同的整合。

慢文件需要可以離開的流程。 所得資料的兩小時等待證實了同步等待的設計走不通。App 改成在請求發出前就顯示預估時間,允許使用者離開,收到平臺通知後從「個人文件」入口回來繼續。同一個入口也支援連續下載多份已完成的文件,登入一次即可,平臺對每一次新的調閱仍可能要求重新驗證身分。

有備而來建立正式證件的說明頁,列出四個步驟,填寫 MyData 資料、到行動自然人憑證核准、回到有備而來、下載或稍後繼續,下方可選擇在這支 iPhone 記住 MyData 常用資料
圖四。匯入前先說明接下來會發生的四步,包括會離開 App 到行動自然人憑證,以及慢文件可以稍後從「個人文件」繼續。這一頁是為了讓使用者在資料流動之前就知道流向。

流程的深度是主要的可用性問題。 同期的 UI 稽核把 MyData 匯入列為 App 最長的流程,八到十步,四層疊在一起的視窗,解密密碼輸入錯誤時提示會遞迴彈出。這些已排入修正,本文不把它們算作完成。

國民身分證那條路早已跑通。 那次真實下載除了量出沒有簽章,也完成了整條發證路徑,MyData 下載、行動自然人憑證簽署、離線驗證憑證鏈到 MOICA G3、存檔、首頁讀回。當時新量到的一個事實是自然人憑證裡沒有統一編號,主體名稱只有國別、姓名與一組十六位序號,離線綁定只能靠姓名。

出示時才鑄造的憑證

保存原始檔只解決一半的問題。另一半是把一份 PDF 變成查驗方看得懂的答案,而且只給答案。這條路現在兩端都接起來了。

查驗方在網頁上選擇皮夾、選擇情境,再填入規則的參數,例如所得的年度與上限、投保的指定日期、設籍的縣市與最少月數。這條規則跟著簽章過的請求一起送出,請求以 DCQL 撰寫,問題放在 bonds_rule 裡。皮夾掃碼後從保險箱讀出原始檔,以身分證號解鎖,用指定版本的解析器讀出欄位,依規則算出述詞,當場鑄造一張平面的 SD-JWT VC。持有人在出示前還能關掉不想給的欄位,沒勾的欄位不會進入出示。原始檔全程留在手機上。

請出示皮夾的建立查驗頁面,先選皮夾再選驗證目的,情境包含確認已滿 18 歲、核對姓名、超商取貨、所得是否在門檻內、指定日期是否有勞保、戶籍是否在指定縣市,下方填入縣市臺北市與至少設籍月數 120,並說明只揭露是非答案
圖五。查驗方只決定要問什麼。頁面在產生 QR 之前就寫明這次會要求哪個欄位、不會拿到什麼,以及答案由持有人從保險箱原檔衍生並簽署,不是政府簽發。
有備而來保險箱裡戶籍謄本的詳情頁,列出文件類型、來源台灣 MyData、匯入時間、檔案格式 ZIP、SHA-256 檔案指紋、完整性查核通過,最後一列是可回答的問題,內容為戶籍是否在某縣市
圖六。詳情頁最後一列「可回答的問題」是保險箱與查驗方之間的介面。有解析器的文件才會出現問題,其餘文件明白寫著還沒有對應的查驗問題,避免持有人掃了 QR 才發現出示不了。

實作上有三個值得記錄的決定。

規則進簽章。 查驗方送出的問題與皮夾簽署的答案是同一條規則,逐鍵比對。規則的邊界值、年度與縣市都在簽章涵蓋範圍內,查驗方無法在事後改口說自己問的是別的問題,皮夾也無法回答一個沒有被問過的問題。

一次性金鑰。 衍生憑證的簽發者與持有人綁定用的是同一把記憶體裡的臨時金鑰,出示完就消失,不進鑰匙圈。主張本身是持有人自述,用 Secure Enclave 的長期金鑰簽並不會讓它多一分政府背書,卻會留下一個跨查驗方可以串連的識別子。第四篇指出選擇性揭露的可關聯性來自穩定的持有人金鑰,這條路徑刻意避開了它。將來若需要把答案綁回身分證持卡人,換掉綁定的金鑰即可,介面不動。

三條規則覆蓋三個情境。 所得門檻回答年度、給付單位數與是否在上限內;投保狀態回答指定日期是否在保;設籍條件回答是否設籍於某縣市、是否滿指定月數。金額、雇主、投保薪資、完整地址、戶號與戶內成員都不在答案裡。

有備而來的選擇性揭露情境頁,列出所得資格、投保狀態、居住或不動產條件三個情境及各自不揭露的內容,下方段落標題為驗證端必須顯示什麼,第一項是由持有人衍生的證據
圖七。App 內的情境說明同時寫給持有人與查驗方看。下半部「驗證端必須顯示什麼」把信任標籤的要求放進皮夾自己的畫面,不讓它停留在規格文件裡。

查驗方接受的條件

這是「查驗方要怎麼承認這些文件」的具體答案。除了 SD-JWT VC 的標準檢查與持有人綁定的 nonce、對象與摘要比對之外,驗證器另外要求五件事同時成立。

  1. 憑證型別與這次查驗要求的一致,且型別描述檔的雜湊等於驗證器事先釘死的值。驗證器不相信那個網址今天送出什麼。
  2. 保證等級寫著「持有人衍生」。
  3. 來源宣告是一份 MyData 下載的文件,帶 64 個十六進位字元的指紋與文件類型,解析器版本在已審核的清單內。
  4. 憑證裡的規則與這次 session 送出的規則逐鍵相同。
  5. 簽發者是 did:key,且持有人綁定的公鑰存在,出示者就是簽發者。

通過之後,結果頁不給任何信任徽章。它顯示四張證據卡,信任標籤、來源文件指紋、解析器版本、以及這次問的規則,並只列出持有人勾選的欄位。查驗方看到的因此是一句可以逐項覆核的敘述,某一把金鑰用某個版本的解析器,對一份指紋為某值的檔案,回答了這個問題。政府背書從頭到尾沒有出現在畫面上。

值得注意的是,這套接受條件放在憑證內部,沒有依賴任何中央登錄。好處是兩邊可以在沒有主管機關的情況下先跑起來,代價是型別的雜湊由雙方各自釘死,一旦查驗方數量變多就會退化成兩兩議定。這正是後面政策建議主張登錄的理由,先有可運作的契約,再把它標準化。

目前跑到哪裡

兩端都有測試。皮夾這側涵蓋三個解析器的正常與拒絕路徑、憑證形狀、只帶勾選的揭露、兩次出示金鑰不同,以及缺原檔、缺規則、年度不符、欄位不在型別內各自的錯誤。驗證器那側以同形憑證涵蓋接受路徑與十餘種拒絕,包含規則不符、解析器未審、指紋格式錯、型別雜湊錯、重放與持有人綁定錯誤。

真機上已經確認戶籍謄本的原始檔能解析出縣市、行政區與設籍日期。這一步一度整批失敗,所有文件都回報「不是這種文件」,原因是 MyData 的 PDF 以持卡人的統一編號上鎖,解析器讀到的文字層是空的。修正的方式是先用保險箱裡身分證上的號碼解鎖再解析,同時讓純 CSV 的交付先以 UTF-8 再以 Big5 讀取。

還沒完成的部分同樣明確。兩支真機的完整往返,掃碼、同意、揭露選擇、結果頁、刪除文件後重掃,尚未跑完。只有所得、勞保、戶籍三類文件有解析器,健保投退保、納稅證明、勞退與地籍四類還沒有。來源文件的機關簽章驗證沒有接進這條流程,結果頁固定顯示持有人衍生。

誠實邊界

下一步與政策建議

一、讓文件自己帶著簽章

保險箱能做到「證明檔案沒有被改過」,做不到「證明機關說過這些話」,差別在文件離開平臺時有沒有簽章。機關對平臺的簽章已經存在,缺的是把它延伸到交付物上。有兩種做法可以並行。

短期,平臺交付的 PDF 採用 PAdES 簽章,CSV 附上 CAdES 或 JWS 的獨立簽章,簽章者可以是資料提供機關,也可以是平臺以受託身分代簽並在簽章屬性中註明來源機關與調閱時間。這不改變三方架構,也不要求平臺留存資料,只是把已經在做的簽章多做一步。文件帶了簽章,前面關閉的 zkPDF 路徑就重新打開,持有人可以只證明「這份機關簽署的文件裡所得高於門檻」而不交出文件。

中期,平臺以 OID4VCI 直接發出 SD-JWT-VC,讓數位憑證皮夾與第三方皮夾以同一套協定領取。第四篇已經指出政府卡片的欄位形狀決定了零知識證明能不能發生,MyData 若以憑證形式交付,所得區間、投保狀態這類述詞證明就有了政府簽章的基礎。

二、承認民眾需要一個保存位置

平臺八小時清除的政策應該維持,它保護的是平臺不成為第二個資料庫。但清除政策應該搭配一個明確的政策立場,民眾有權把自己的資料保存在自己控制的裝置裡,皮夾是這個位置的合理選項。這個立場可以體現在三件事。第一,平臺的「個人文件」頁面提供可被皮夾辨識的下載描述,包含文件類型代碼、產出時間、來源機關與檔案指紋。第二,數位憑證皮夾計畫把「資料保險箱」列為皮夾的功能之一,並訂出保存的最低要求,例如裝置綁定、預設不備份、單項刪除、匯出警告。第三,這些要求應對官方與第三方皮夾一體適用。

三、驗證者怎麼承認這些文件,避免它們成為孤兒

一份持有人衍生的憑證,若沒有查驗方願意收,就只是手機裡的一個檔案。這是最需要政策介入的一環。建議查驗方的設計遵守以下規則。

  1. 信任標籤分三級,畫面上不可混用。 「政府簽發」指憑證由機關金鑰簽署。「機關簽章文件衍生」指來源文件帶有可驗證的機關簽章,持有人的憑證綁定該簽章。「持有人衍生」指來源文件沒有簽章,憑證只證明同一位持有人簽了這項主張,且主張連到一份指紋固定的文件。查驗結果頁必須同時顯示四件事,持有人簽章是否有效、來源文件指紋、解析器版本與規則版本、信任標籤。

  2. 以風險分級決定接受哪一級。 低風險用途,例如租屋預審、活動報名、會員資格,可以接受持有人衍生憑證,因為它比今天普遍接受的截圖與影本強得多,多了指紋、簽章與可追溯的規則。中風險用途接受機關簽章文件衍生。高風險用途要求政府簽發,或在持有人同意下走 MyData 現有的線上重新交付。這個分級應由主管機關公布,讓查驗方有所依據,不必各自摸索。

  3. 憑證類型要有登錄。 每一種文件的衍生憑證應有版本化的類型識別與欄位定義,例如所得證明的稅務年度與區間述詞、投保資料的指定日期有效與否。登錄由主管機關或公協會維護,皮夾與查驗方對照同一份,述詞的邊界值、幣別與年度都要進入簽章涵蓋範圍,不能只寫在查驗方的畫面上。本文的實作以憑證內的衍生契約與釘死的型別雜湊代替登錄,證明兩邊可以先跑起來,但那是雙邊協定;登錄的價值在於讓第三方不必逐一議定。

  4. 述詞優先於原值。 查驗方應以「是否落在門檻內」、「指定日期是否有效投保」、「是否在某縣市設籍滿六個月」這類問題定義需求,皮夾只回答是非。這與第四篇的資料最少化階梯一致,也讓持有人衍生憑證在被接受的同時不必交出整份文件。

  5. 提供重新驗證的升級路徑。 查驗方收到持有人衍生憑證後,若需要更高保證,可以引導持有人以 MyData 現有的條碼與動態密碼流程做一次線上核驗,並把結果與剛才的憑證指紋綁在一起。這讓低保證的文件有路徑升級,不會因為第一次被拒就永遠無用。

四、相容性建議

五、治理邊界

本文的保險箱是一個開發版 App 上的實作,沒有取得任何官方介接資格。持有人衍生憑證的接受與否,最終取決於查驗方與主管機關的規則。本文提出的分級與登錄是建議,實際規則應由主管機關會同資料提供機關訂定。

接下來

  1. 補完勞保投保與勞退提繳兩個項目,並對八個項目逐項驗證,含更新覆蓋、重新啟動後的可見性與每種格式的預覽相容性。
  2. 把三個衍生憑證場景在兩支真機之間跑完整往返,並為健保投退保、納稅證明、勞退與地籍四類文件補上解析器。
  3. 壓平匯入流程,把四層視窗與遞迴的錯誤提示修掉。
  4. 向數位發展部提出兩個具體詢問。平臺是否有帶簽章的下載選項,以及第三方皮夾註冊為資料需求方的條件。
  5. 把本文的信任標籤與風險分級寫成可交給查驗方的一頁規格,附測試向量。
  6. 建立正式版的簽署後端,讓自然人憑證的簽章路徑離開開發版。

MyData 解決了「資料在哪個機關」的問題,沒有解決「資料在民眾手上之後怎麼辦」的問題。平臺八小時後清除是對的,文件沒有簽章是缺的,民眾需要一個保存位置是真的。數位皮夾能提供這個位置,也能把文件變成可以選擇性揭露的憑證。這些憑證會不會成為孤兒,取決於查驗方願不願意用一套公開的規則承認它們。這件事的成本很低,效果是把今天到處流傳的截圖與影本,換成有指紋、有簽章、有版本的東西。