跳至主要內容
Skip to content

身份驗證與數位簽章

在政府服務、金融服務、醫療系統、合約簽署、線上申辦流程裡,常會出現一個很容易混淆的問題:

text
使用者已經登入了,這樣可以代表他簽署文件嗎?

答案通常是:

text
不可以直接等同。

身份驗證和數位簽章都可能用到密碼學、憑證、公私鑰、challenge-response,但它們解決的是不同問題。

身份驗證回答:

text
這次操作的人是誰?

數位簽章回答:

text
這個人是否對某份特定內容做出可驗證的簽署?

差別非常大。

如果系統把「登入成功」直接當成「同意並簽署所有後續文件」,很容易在法規、稽核、爭議處理和安全設計上出問題。

這篇要把幾件事講清楚:

  • 身份驗證、授權、Session、數位簽章差在哪?
  • 為什麼登入成功不等於簽署文件?
  • Challenge-response 登入為什麼也不自動等於文件簽章?
  • 交易簽章應該綁定哪些內容?
  • 系統應該保存哪些證據?
  • 面試時怎麼回答才像真的做過高信任系統?

一、 一句話回答

如果面試官問:

身份驗證和數位簽章有什麼不同?

可以先回答:

身份驗證是確認這次操作的人是誰,通常用來建立 session 或提升當前操作的信任等級;數位簽章是使用私鑰對特定文件、交易內容或其摘要產生可驗證的簽章,用來證明內容未被竄改、簽署者身份可驗證,並提供後續爭議處理所需的證據。登入成功不能自動代表使用者簽署所有後續內容;如果要有簽章語意,必須讓使用者看到要簽署的內容,對穩定且明確的內容或 digest 產生簽章,並保存簽章值、簽署內容摘要、憑證資訊、時間、驗證結果與稽核紀錄。

短一點可以說:

text
Authentication 證明「誰正在操作」,
Digital Signature 證明「誰簽了哪一份內容」。

二、 先拆四個概念

概念回答的問題典型結果常見例子
身份驗證 Authentication這次操作是不是本人?建立 session、提高 assurance level帳號密碼、Passkey、TW FidO 登入
授權 Authorization這個人能不能做這件事?allow / denyRBAC、scope、資料權限
Session驗證後如何維持登入狀態?session id、cookie、token登入後保持狀態
數位簽章 Digital Signature誰對哪份內容簽署?內容是否被改過?signature、document hash、驗證證據自然人憑證簽署、合約簽章、交易簽章

這四件事可以串在同一個業務流程裡,但不能混成同一個布林值。

例如:

text
使用者通過 TW FidO 登入
-> 系統建立 session
-> 使用者申請某項服務
-> 系統檢查授權與資格
-> 使用者確認申請內容
-> 對申請書做數位簽章
-> 保存簽章與稽核證據

這不是一個動作,而是一串不同語意的動作。

三、 電子簽章與數位簽章

台灣的《電子簽章法》把電子簽章、數位簽章、憑證等概念分開定義。

用工程角度簡化理解:

名稱重點
電子簽章以電子形式表示簽署或同意的方式,是較大的概念
數位簽章電子簽章的一種,使用私鑰、公開金鑰與憑證等密碼學機制驗證
憑證用來確認簽署人身份、資格與簽章驗證資料的電子形式證明

所以:

text
數位簽章是電子簽章的一種,
但不是所有電子簽章都一定是數位簽章。

例如:

場景可能屬於
網頁上勾選「我同意」電子化同意,是否具法律效果要看流程與證據
在 PDF 上貼入手寫簽名圖片電子簽章的一種表現,但未必有密碼學驗證
使用自然人憑證對文件 digest 簽章數位簽章
使用合格簽章服務對合約簽署依服務與法規設計,可能具有較高證據力

面試時不要把所有「線上同意」都說成數位簽章。

四、 登入流程和簽章流程不同

登入流程

登入通常長這樣:

登入的產物通常是:

  • session。
  • access token。
  • authenticated user。
  • auth event。
  • assurance level。

也就是:

text
在某個時間點,系統相信這個 session 屬於某個 user。

簽章流程

簽章通常長這樣:

簽章的產物通常是:

  • signed content。
  • document hash。
  • signature value。
  • signer certificate 或 certificate reference。
  • signing time。
  • verification result。
  • audit log。

也就是:

text
某個簽署者對某份特定內容留下可驗證證據。

五、 為什麼登入不等於簽章

登入成功只代表:

text
系統剛才驗證過這個操作者。

它不代表:

text
使用者看過某份文件。
使用者同意某個金額。
使用者確認某個收款帳號。
使用者簽署某份申請書。
使用者願意承擔該內容的法律效果。

舉例:

text
使用者 10:00 用高信任方式登入。
10:05 系統背景產生一份申請書。
10:06 後端直接把登入狀態當成簽署。

這裡最大的問題是:

text
簽署內容沒有被明確綁定。

後續如果發生爭議,系統很難回答:

  • 使用者當時看到的是哪個版本?
  • 文件內容是否和現在保存的一樣?
  • 簽署時的金額、對象、條款是什麼?
  • 簽署行為是使用者明確觸發,還是系統自動產生?
  • 能不能用公鑰驗證當時的簽章?

所以登入可以是簽章前置條件,但不能自動取代簽章。

六、 數位簽章到底解決什麼

數位簽章主要解決幾個問題。

1. 完整性

簽章通常針對文件內容或 digest。

如果文件被改過,hash 會變,簽章驗證會失敗。

text
同一份內容 -> 同一個 digest
內容被改動 -> digest 改變 -> 驗章失敗

2. 簽署者身份

透過憑證與公開金鑰,可以驗證簽章是否對應到某個簽署者。

這和「現在 session 裡的 userId 是誰」不同。

session 是應用系統狀態。

簽章是密碼學證據。

3. 不可否認性

在符合憑證、流程、時間、保存與法規要求的前提下,簽章可以提供較強的爭議處理能力。

工程上不要只說:

text
有 signature,所以一定不可否認。

更準確是:

text
數位簽章提供不可否認性的技術基礎,
但仍需要正確的身份確認、憑證狀態、簽署流程、時間證據與稽核紀錄支撐。

4. 時間證據

很多爭議不是只問:

text
誰簽的?

還會問:

text
什麼時候簽的?
當時憑證是否有效?
當時文件版本是什麼?

所以高信任場景常需要保存:

  • server received time。
  • signing time。
  • timestamp token。
  • 憑證有效期。
  • 憑證撤銷檢查結果。
  • 驗章當下結果。

是否需要可信時間戳,要看業務、法規與證據需求。

七、 Challenge-response 登入不等於文件簽章

Passkey、WebAuthn、TW FidO 類型的登入常用 challenge-response。

流程大致是:

text
server 產生 random challenge
-> authenticator 用私鑰簽署 challenge 與相關資料
-> server 用公鑰驗證

W3C WebAuthn 規範也明確把 challenge 放在 request options 裡,並要求它由 Relying Party 在可信環境產生,用來避免重放攻擊。

這是一種密碼學簽名沒錯。

但它的簽署對象通常是:

text
登入 challenge + origin + authenticator data

不是:

text
申請書全文
轉帳金額
收款帳號
合約條款
醫療授權內容

所以不能因為底層有 signature,就直接說:

text
這等同文件簽章。

比較精準的說法是:

text
WebAuthn / FIDO2 authentication assertion 可以證明持有私鑰的 authenticator 回應了這次登入 challenge;
但若要變成交易簽章或文件簽章,必須把要簽署的業務內容明確納入簽章對象或可驗證的簽章流程。

八、 交易簽章要綁定內容

交易簽章的核心是:

text
簽章必須綁定使用者真正要承諾的內容。

例如轉帳:

json
{
  "type": "transfer",
  "fromAccount": "123-456",
  "toAccount": "987-654",
  "amount": 50000,
  "currency": "TWD",
  "purpose": "rent",
  "nonce": "random-request-id",
  "expiresAt": "2026-05-24T12:00:00+08:00"
}

如果只簽:

text
I agree.

那幾乎沒有意義。

因為爭議時無法證明使用者同意的是哪筆交易。

好的簽章 payload 至少要綁定:

  • 操作類型。
  • 金額或關鍵業務欄位。
  • 對象,例如收款帳號、申請機關、文件 id。
  • 文件版本。
  • document hash。
  • request id / nonce。
  • 過期時間。
  • 簽署者身份或 subject。
  • 顯示給使用者看的摘要。

面試時可以用一句話收束:

text
交易簽章不是簽「我同意」三個字,
而是簽「我同意這一筆具體內容」。

九、 What You See Is What You Sign

簽章設計最難的地方之一是:

text
使用者看到的內容,必須和真正被簽的內容一致。

這常被稱為:

text
What You See Is What You Sign

常見風險:

風險問題
UI 顯示 A,後端簽 B使用者以為同意 A,但證據是 B
前端自行組 payload可能被 XSS 或惡意客戶端竄改
文件渲染版本不固定同一份資料在不同環境顯示不同
沒有保存文件版本事後無法重現簽署畫面
只保存 PDF,不保存 hash難以證明 PDF 未被替換

比較穩的做法是:

text
後端產生 canonical content
-> 後端產生 digest
-> 前端顯示由同一份 canonical content 渲染出的摘要或文件
-> 使用者明確確認
-> 簽署 digest 或內容
-> 保存 canonical content version + digest + signature

十、 Canonicalization 與 Digest

簽章前通常要先處理內容穩定性。

例如 JSON 有這些問題:

json
{"amount":50000,"currency":"TWD"}

和:

json
{
  "currency": "TWD",
  "amount": 50000
}

語意可能一樣,但字串不同。

如果直接簽原始字串,欄位順序、空白、換行都可能影響 hash。

所以高信任簽章流程常會做:

  • canonical JSON。
  • 固定欄位排序。
  • 固定數字格式。
  • 固定時間格式。
  • 固定編碼。
  • 固定文件模板版本。
  • 對 canonical content 產生 digest。

概念:

ts
type SigningPayload = {
  type: 'application'
  documentId: string
  documentVersion: string
  subjectId: string
  contentHash: string
  nonce: string
  expiresAt: string
}

真正簽的不是模糊的畫面,而是穩定、可重現、可驗證的內容。

十一、 系統應該保存什麼

簽章完成後,不是存一個 signed = true 就好。

至少應該保存:

欄位用途
document_id對應文件
document_version對應文件版本
canonical_content_hash證明內容未變
signature_value簽章本體
signing_algorithm驗證演算法
certificate_subject簽署者憑證資訊
certificate_serial_number憑證識別
certificate_chain 或 reference後續驗章
signed_at簽署時間
verified_at系統驗章時間
verification_result驗章結果
revocation_check_result憑證是否撤銷
request_id / nonce防重放與追蹤
ip / user_agent稽核輔助
displayed_summary使用者當時看到的摘要

資料表概念:

sql
create table document_signatures (
  id uuid primary key,
  document_id uuid not null,
  document_version text not null,
  signer_user_id uuid not null,
  provider text not null,
  canonical_content_hash text not null,
  signature_value text not null,
  signing_algorithm text not null,
  certificate_subject text,
  certificate_serial_number text,
  signed_at timestamp not null,
  verified_at timestamp,
  verification_result text not null,
  revocation_check_result text,
  request_id text not null unique,
  created_at timestamp not null
);

如果業務要求很高,還會把文件原文、簽章封包、時間戳、憑證鏈、驗證報告放到不可任意修改的 evidence store。

十二、 自然人憑證、TW FidO 與簽章

在台灣場景裡,自然人憑證與行動自然人憑證常同時出現在「登入」與「簽章」兩種語境。

要分清楚:

場景語意
使用自然人憑證登入服務高信任身份驗證
使用自然人憑證簽署文件對特定文件產生數位簽章
使用 TW FidO 登入行動自然人憑證體系下的身份驗證
使用官方能力進行數位簽章依介接能力對特定內容簽署

同一個身份基礎設施可以支援多種能力。

但工程設計要問清楚:

text
這次 API 是 authentication?
還是 signing?

如果是 authentication,產物是:

text
auth result + session

如果是 signing,產物是:

text
signature + signed content evidence

十三、 高風險操作重新驗證

有些流程不一定需要正式文件簽章,但仍需要重新驗證。

例如:

  • 修改密碼。
  • 修改手機。
  • 綁定第三方登入。
  • 新增收款帳號。
  • 查看敏感醫療資料。
  • 匯出大量個資。
  • 提交高風險申請。

這時候常見設計是:

text
使用者已登入
-> 進入高風險操作
-> 要求重新驗證
-> 驗證通過後給短效 step-up token
-> 在短時間內完成該操作

重新驗證也不等於數位簽章。

它通常只是提高當前操作信任等級。

下一篇可以再獨立談:

text
高風險操作重新驗證

十四、 常見錯誤

1. 用 session 代表使用者已簽署

錯誤:

text
userId 存在 session,所以 signedBy = userId。

正確:

text
session 只能代表登入狀態;簽章要有簽署內容、signature、時間與驗證證據。

2. 只簽 vague text

錯誤:

text
使用者簽署「我同意」。

正確:

text
使用者簽署包含文件 id、版本、金額、對象、nonce、過期時間等具體內容。

3. 不保存內容 hash

錯誤:

text
只保存 PDF 檔案和 signed=true。

正確:

text
保存 canonical content、hash、signature、文件版本與驗章結果。

4. 忽略憑證狀態

錯誤:

text
只要 signature 驗得過就好。

正確:

text
還要考慮憑證有效期、撤銷狀態、信任鏈與簽署時間。

5. UI 內容和簽署 payload 不一致

錯誤:

text
前端顯示摘要 A,但後端簽署 payload B。

正確:

text
顯示內容、canonical content、digest 和簽署 payload 必須有可追溯關係。

6. 把 WebAuthn assertion 當成業務文件簽章

錯誤:

text
Passkey 登入時有 signature,所以可視為同意合約。

正確:

text
Passkey 登入 signature 通常是對 challenge,而不是對合約內容。

十五、 面試追問題庫

Q1:身份驗證和數位簽章差在哪?

身份驗證確認這次操作的人是誰,通常產生 session 或提升信任等級;數位簽章是對特定文件或交易內容產生可驗證簽章,證明內容完整性、簽署者身份與簽署證據。

Q2:登入成功可以代表簽章嗎?

不應直接等同。登入只能證明當下身份驗證成功,不能證明使用者看過並同意某份具體內容。要有簽章語意,必須對特定內容或 digest 簽章並保存證據。

Q3:Passkey / WebAuthn 有 signature,為什麼不是文件簽章?

WebAuthn authentication assertion 簽的通常是 server challenge、origin 與 authenticator data,用來防止重放並證明 credential 持有者完成驗證。它不一定包含業務文件內容,因此不能自動視為文件簽章。

Q4:交易簽章要簽什麼?

要簽具體且可重現的交易內容,例如操作類型、金額、對象、文件 id、文件版本、content hash、nonce、過期時間與簽署者身份,不能只簽「我同意」。

Q5:為什麼要保存 document hash?

因為 hash 可以證明後續拿出來驗證的文件與當時簽署的內容一致。如果文件被改過,hash 會不同,簽章驗證或內容比對會失敗。

Q6:不可否認性只靠 signature 就夠嗎?

不夠。還需要可信身份、憑證鏈、憑證有效與撤銷狀態、簽署時間、使用者確認流程、簽署內容保存、驗章結果與稽核紀錄。

Q7:重新驗證和簽章有什麼不同?

重新驗證是提高當前操作信任等級,例如修改密碼前再驗一次 MFA;簽章是對特定內容留下可驗證承諾。重新驗證不一定具有文件簽章語意。

十六、 實作題

題目一:設計線上申請書簽章流程

情境:

text
使用者登入政府服務後,要線上送出一份申請書,系統要求自然人憑證或行動憑證簽章。

好的答案應包含:

  1. 使用者先完成身份驗證並建立 session。
  2. 使用者填寫申請資料。
  3. 後端產生文件版本與 canonical content。
  4. 後端產生 document hash。
  5. 前端顯示要簽署的內容或摘要。
  6. 使用者明確按下簽署。
  7. 透過憑證或簽章服務對內容或 digest 簽章。
  8. 後端驗章。
  9. 保存簽章值、hash、憑證資訊、時間、驗章結果與 audit log。
  10. 文件狀態變成 signed / submitted。

題目二:找出以下設計問題

text
使用者登入後,後端直接把所有送出的表單標記 signed=true,
資料庫只保存 user_id、form_id、created_at。

問題:

  • 沒有簽章值。
  • 沒有文件 hash。
  • 沒有文件版本。
  • 沒有明確簽署行為。
  • 沒有憑證資訊。
  • 沒有驗章結果。
  • 無法證明內容未被竄改。
  • 無法證明使用者看到的內容。

題目三:設計交易簽章 payload

好的 payload 應包含:

json
{
  "type": "transfer",
  "transactionId": "tx_123",
  "fromAccount": "123-456",
  "toAccount": "987-654",
  "amount": "50000",
  "currency": "TWD",
  "contentHash": "sha256:...",
  "nonce": "random-request-id",
  "expiresAt": "2026-05-24T12:00:00+08:00"
}

並說明:

text
使用者畫面顯示的金額、帳號與交易摘要,必須來自同一份 payload 或可驗證內容。

十七、 資深視角

1. 先問語意,不要先問 API

資深工程師看到「登入、簽章、驗證」這些需求時,第一個問題不是 API 怎麼接,而是:

text
這次業務到底需要的是 authentication、authorization、step-up authentication,還是 digital signature?

語意錯了,API 接對也沒用。

2. 證據鏈比 signed=true 重要

高信任系統要能在事後回答:

  • 誰簽的?
  • 簽了什麼?
  • 什麼時候簽?
  • 當時憑證是否有效?
  • 內容是否被改過?
  • 使用者當時看到了什麼?
  • 驗章結果是什麼?
  • 操作是從哪個 request 來的?

這些答案才是系統真正的抗爭議能力。

3. 安全和法規語意要一起設計

工程上可能覺得:

text
我有驗登入、有 HTTPS、有 audit log,應該夠了。

但在簽章場景,還要考慮:

  • 電子簽章法。
  • 憑證信任鏈。
  • 憑證撤銷。
  • 簽章格式。
  • 文件保存。
  • 時間證據。
  • 使用者明確同意。
  • 個資最小化。

這也是為什麼政府、金融、醫療場景不能只用一般登入思維處理。

4. 不要過度承諾

在面試或設計文件裡,不要輕易說:

text
這樣就有法律效力。

更好的說法是:

text
這個設計提供數位簽章所需的技術證據鏈,
實際法律效力還要依適用法規、簽章服務、憑證類型與業務流程判斷。

這樣比較精準,也比較專業。


總結

問題回答重點
身份驗證確認這次操作的人是誰
Session保存登入狀態
授權判斷能不能做某件事
數位簽章對特定內容留下可驗證簽署證據
登入是否等於簽章不等於
WebAuthn signature 是否等於文件簽章不一定,通常只是登入 challenge
交易簽章核心綁定具體交易內容
簽章保存重點signature、content hash、憑證、時間、驗章結果、audit log

一句完整的面試回答可以是:

身份驗證和數位簽章都可能用到密碼學,但語意不同。身份驗證是確認這次操作的人是誰,通常用來建立 session 或提升操作信任等級;數位簽章則是使用私鑰對特定文件或交易內容產生可驗證簽章,用來證明內容完整性、簽署者身份與後續爭議處理證據。因此登入成功不能直接代表使用者簽署文件;如果要有簽章語意,必須讓使用者看到要簽署的內容,對 canonical content 或 digest 簽章,並保存簽章值、文件 hash、憑證資訊、簽署時間、驗章結果與 audit log。

延伸閱讀