計算憑證 1.0
憑證是一份你可以重跑的主張。
憑證不要求你信任那次稽核。它記下的東西,足以讓你把那次稽核重做一遍,然後一個雜湊一個雜湊地比對。
信封
兩個部分:被簽署的內容,以及說明「怎麼簽的」完整性區塊。
json
{
"payload": { "...": "signed content" },
"integrity": {
"certificate_id": "mmr1-...",
"canonicalization": "MMR-CJ-1",
"payload_sha256": "...",
"signature_algorithm": "Ed25519",
"public_key_base64": "...",
"signature_base64": "..."
}
}簽署負載
負載帶的是整次稽核,不是稽核的摘要。
- 結構描述版本與建立時間戳。
- XLSX 檔名、位元組大小、SHA-256、日期系統,以及工作表/公式/已定義名稱/表格/樣式的數量。
- MMR 與外部引擎的環境清單。
- 結構化參照正規化的完整紀錄。
- 稽核摘要與排序後的公式證據。
- 快取失效、覆核與公式寫入三類決策。
- 正規化、證據、決策三者各自獨立的 SHA-256 雜湊。
- 重播所需的條件。
三個雜湊分開存,是為了讓「部分失敗」看得懂。一次重播可能證據完全重現、正規化卻不同,憑證會如實說出這件事。
正規化 — MMR-CJ-1
JSON 本身穩定度不足以直接拿去雜湊,所以雜湊跑在一棵正規化樹上,而你讀到的負載仍然是普通的 JSON。
- 鍵序
- 字典依 UTF-8 字串鍵排序。
- 編碼
- UTF-8,不含任何無意義空白。
- 浮點數
- 有限浮點數在正規化雜湊樹中轉成帶標記的 17 位數字串。
- 禁止值
- NaN 與無限大直接拒絕。
- 可讀性
- 給人看的負載維持普通 JSON;只有雜湊會看到正規化樹。
簽章
正規化後的負載位元組先以 SHA-256 雜湊,再用 Ed25519 簽署。憑證裡只帶公鑰。釋出用的範例憑證刻意不附私鑰。
寫入授權
當兩條獨立的計算路徑都認為某個存下來的快取已經過期時,憑證可以記錄一次快取失效。整個寫入面就這麼大。
永不
引擎意見不一致,永遠不構成公式寫入的授權。
重播協定
重播依嚴格順序執行。每一項檢查各自獨立回報,所以重播告訴你的是「哪一階段失敗」,而不是一個總結性的判決。
- 重新計算正規化負載的 SHA-256。
- 驗證 Ed25519 簽章。
- 對提供的 XLSX 取雜湊,與簽署時記下的主體雜湊比對。
- 重新抽取 OOXML 快照。
- 重跑 MMR 與外部引擎的求值。
- 重建結構化參照的正規化紀錄。
- 重新計算正規化、證據與決策三個雜湊。
- 各項檢查獨立回報。
只有在所有必要檢查皆為真時,該次重播才算有效。
失敗階段
signature- 憑證負載或簽章遭到修改。
source- 提供的 XLSX 並不是被簽署的那一份來源。
replay- 來源相符,但目前的引擎環境重現不出被簽署的證據。
把這三種分開,比乍看之下重要得多。若不分開,「升級了一個相依套件」和「有人動了文件」會得到同一個紅色結果,讀的人根本無從分辨環境漂移與攻擊。
一份有效的憑證證明了什麼
負載確實由內含的公鑰簽署;負載雜湊完好;重播時提供的 XLSX 具有記錄下來的 SHA-256;且在記錄的軟體環境下,正規化、證據與決策三個雜湊都能重現。
並未證明
任何引擎實作了全部 Excel 語意、某條商業公式在概念上正確,或引擎之間的不一致足以授權改寫公式。