Build with Proof

把簽署,
接回你的服務。

免註冊、免 API 金鑰,直接整合。把文件交給 Proof 簽署,再安全地接回你的流程。每次以新的非對稱金鑰證明 Session 控制權,不需向 Proof 登記身分或交換共用密鑰。

免註冊免 API 金鑰直接整合可下載整合範例
開發預覽:API 與 E2EE 核心已有本機測試;完整 App Clip 路由、瀏覽器安全復原、requester PDF 驗證與正式部署尚在整合。本頁不提供虛構的 npm 套件或假成功結果。

三種入口,一套協定

三種入口共用同一套 Session、金鑰、文件與 receipt 模型。

  1. 準備文件與金鑰

    固定 PDF bytes、SHA-256;產生全新的 ownership、transport key 與 bootstrap capability。

  2. 建立 Session

    簽署 request → Proof 驗簽;上傳加密 PDF。Proof 不取得解密 capability。

  3. 選擇入口

    網站跳轉 / 原生 App handoff / 桌機 QR;同一個 App Clip ceremony。

  4. 確認與簽署

    解密並核對文件 hash → 閱讀確認 → NFC + PIN → 卡片簽署。

  5. 交付已簽文件

    加密並上傳固定的 signed artifact。網路重試不重新簽署。

  6. 回到 requester 驗證

    同機返回 / 桌機 polling;ownership proof 取結果,驗 artifact、PAdES 與 Proof receipt。

  7. 繼續原工作流程

    持久化已驗證結果 → ACK → 清理短期金鑰。

返回只負責導覽,不代表簽署成功。只有驗證 artifact 與 Proof-signed receipt 後,requester 才能推進 workflow。Bootstrap 用於文件解密與 transport binding,不具 Session ownership 權限。

Requester SDK · 0.2.1

先接上流程,再深入協定。

SDK 封裝 Session 建立、端對端加密、結果解密、簽章及收據驗證。瀏覽器使用 IndexedDB 保存接續資料;Worker 使用 SealedRecoveryStore 加密保存金鑰。

套件名稱:@sentry-security/proof-sdk@0.2.1,發布於 GitHub Packages。私有套件下載需要套件存取權;這與 Proof API 不需帳號或 API Key 的整合模型不同。可下載本頁原始碼範例自行建置。

import { SigningSessionClient } from '@sentry-security/proof-sdk';
import { BrowserRecoveryStore } from '@sentry-security/proof-sdk/recovery-store';

const client = new SigningSessionClient({
  storage: new BrowserRecoveryStore(),
});
const session = await client.create(file, {
  context: 'web',
  returnURL: location.origin + '/sign/return',
});
// 交給點擊連結或 QR 的 UI;不要記錄或公開此網址。
showSigningLink(session.invocationURL);

// 返回頁面或輪詢時,以保存的 session_id 接續。
const saved = await client.recover(session.session.session_id);
const result = await client.complete(saved);
// complete() 可能仍回傳等待狀態;僅完成並驗證後推進業務。
if (result.status === 'COMPLETED') {
  // 另依業務規則核對預期簽署者,並保存文件與收據。
  acceptVerifiedResult(result);
}

協定參考:建立簽署要求

協定採 Ed25519、RFC 8785 JCS、compact JWS、RFC 7638 thumbprint。請使用成熟套件,不要用一般 JSON.stringify 當 canonicalization。Web 與 Cloudflare Workers 共用 requester SDK。下方保留協定位元組範例;日常整合可由 SDK 處理加密、驗證與復原。

import { createOwnership, signCreate, random256 } from './sdk/src/ownership.mjs';
import { invitationKeyPair, bootstrapCommitment } from './sdk/src/bootstrap.mjs';
// 每次 Session 產生新 key;私鑰只留在 requester。
const owner = await createOwnership();
const invitation = await invitationKeyPair();
const request = {
  protocol: 'sentry-proof-signing/1',
  request_id: crypto.randomUUID(), nonce: random256(),
  iat: now, exp: now + 600,
  bootstrap_commitment: await bootstrapCommitment(invitation),
  document: { display_name: '測試合約.pdf', sha256: originalHash },
  credential: { type: 'MOICA' },
  document_transport: transportDeclaration,
  return: { type: 'web', url: 'https://example.com/sign/return' }
};
const response = await fetch('https://proof.sentry.red/v1/signing-sessions', {
  method: 'POST', headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(await signCreate(request, owner))
});
// 此段展示請求格式;now、originalHash、transportDeclaration 由發起方準備。完整流程請使用上方 SDK 或下載範例。

API 與權限

路徑用途/授權
POST /v1/signing-sessions整份 create request 的 ownership JWS
GET /v1/signing-sessions/{id}/challenge短效單次 challenge,指定 action
PUT /v1/signing-sessions/{id}/sourceX-Proof-Ownership 綁 ciphertext hash;body 是密文
POST /v1/signing-sessions/{id}/resultget-result ownership proof,取得狀態/metadata/receipt
POST /v1/signing-sessions/{id}/artifactget-artifact ownership proof,取得已簽密文
POST /v1/signing-sessions/{id}/confirmconfirm-artifact proof 綁 confirmation body hash
POST /v1/signing-sessions/{id}/acknowledgeacknowledge proof 綁 receipt hash acknowledgement
GET /.well-known/jwks.jsonProof receipt 公鑰;依 kid 驗證

驗證結果,才能繼續 workflow

拿到 session_id 或跳回 return URL,都不是成功證明。先驗 bootstrap-authenticated pairing record、解密與核對已簽 PDF hash,再以 requester 的 PAdES 政策驗章。取得 receipt 後,核對固定的 Proof JWKS、alg、typ、kid 以及 session_id、request_id、nonce、request_key_thumbprint、bootstrap_commitment、原始與已簽文件 hash。

Receipt 將證據分為 proof/requester/ceremony 來源。Requester 回報的 PAdES 結果,不等於 Proof 獨立檢查過 PDF。符合憑證簽署不代表符合你的預期簽署人授權,這仍由業務端判斷。

原生 iOS 與返回

原生 App 與 Web、桌機 QR 使用同一套 Session。Swift requester 實作涵蓋請求組裝、加密上傳、結果回收與收據核對;可參考專案內的 RequesterSessionClient 與 RequesterRecovery。返回採 HTTPS universal link,僅負責導覽。#sp2 以精簡 envelope 交付 bootstrap capability;整合時應測試你的瀏覽器、通訊軟體及 App 是否完整保留連結。缺少 capability 時中止,不改放 query 或傳至 Proof。

重試與金鑰生命週期

安全邊界與測試建議

QR 洩漏可能讓取得者解密文件及進入 ceremony,但不能取得 requester ownership。請測試錯誤 key、文件被修改、challenge replay、重複上傳、網路中斷、返回頁面與 full App 路由。請勿記錄完整 request、文件 URL token、PIN 或 private key。

前往可操作的整合體驗 ↗