Skip to content

數位簽章 (HasSecurity)

HasSecurity trait 提供 setSignature() 方法用於 PAdES 合規的數位簽章。TCPDF-Next 透過 PadesOrchestratorTsaClient 與 LTV 模組支援四種簽章等級 — 從基本(B-B)到典藏(B-LTA)。所有簽章方法皆回傳 static 以支援鏈式串接。

快速參考

類別 / 列舉用途
CertificateInfo載入簽署憑證(PEM 或 PKCS#12)
SignatureLevel列舉:PAdES_B_BPAdES_B_TPAdES_B_LTPAdES_B_LTA
TsaClientRFC 3161 時間戳記授權用戶端
SignatureAppearance可見或不可見的簽章小工具
OcspClientRFC 6960 線上撤銷檢查
CrlFetcherRFC 5280 CRL 發佈點擷取

簽章等級

等級包含內容有效性
B-B(基本)簽章 + 簽署憑證在憑證未被撤銷期間有效
B-T(時間戳記)B-B + RFC 3161 時間戳記證明簽章在某個時間點之前已存在
B-LT(長期)B-T + 包含 OCSP/CRL 回應的 DSS憑證過期後仍可驗證
B-LTA(典藏)B-LT + 文件時間戳記 + 典藏迴圈可無限期驗證

載入憑證

從 PEM 檔案

php
use Yeeefang\TcpdfNext\Security\Signature\CertificateInfo;

$cert = CertificateInfo::fromFiles(
    certPath: '/path/to/certificate.pem',
    keyPath: '/path/to/private-key.pem',
    password: 'key-password',
    extraCerts: '/path/to/ca-chain.pem',  // 選用的中繼憑證
);

從 PKCS#12(.p12 / .pfx)

php
use Yeeefang\TcpdfNext\Security\Signature\CertificateInfo;

$cert = CertificateInfo::fromPkcs12(
    p12Path: '/path/to/certificate.p12',
    password: 'pkcs12-password',
);

簽署範例

php
use Yeeefang\TcpdfNext\Core\Document;
use Yeeefang\TcpdfNext\Security\Signature\CertificateInfo;
use Yeeefang\TcpdfNext\Contracts\SignatureLevel;
use Yeeefang\TcpdfNext\Security\Timestamp\TsaClient;

$cert = CertificateInfo::fromFiles(
    certPath: '/path/to/certificate.pem',
    keyPath: '/path/to/private-key.pem',
    password: 'key-password',
);

// PAdES B-B(基本)— 僅簽章
$pdf = Document::create()
    ->setSignature($cert, SignatureLevel::PAdES_B_B)
    ->addPage()
    ->setFont('Helvetica', '', 12)
    ->cell(0, 10, 'Signed document (B-B)')
    ->save('signed-bb.pdf');

// PAdES B-T(時間戳記)— 簽章 + 時間戳記
$tsa = new TsaClient('https://freetsa.org/tsr');
$pdf = Document::create()
    ->setSignature($cert, SignatureLevel::PAdES_B_T, $tsa)
    ->addPage()
    ->cell(0, 10, 'Signed with timestamp (B-T)')
    ->save('signed-bt.pdf');

// PAdES B-LTA(典藏)— 完整長期驗證
$pdf = Document::create()
    ->setSignature($cert, SignatureLevel::PAdES_B_LTA, $tsa)
    ->addPage()
    ->cell(0, 10, 'Archival signature (B-LTA)')
    ->save('signed-blta.pdf');

TsaClient — 時間戳記授權

TsaClient 支援選用的驗證機制。Nonce 驗證與 DNS 固定預設啟用,以防止重放攻擊與 SSRF。

php
$tsa = new TsaClient(
    url: 'https://tsa.example.com/timestamp',
    user: 'tsa-user',
    pass: 'tsa-password',
);

B-T 及以上等級皆需要提供 TsaClient。時間戳記依據 RFC 3161 標準,向時間戳記授權機構(TSA)請求可信的時間證明,確保簽章的時間不可否認性。

長期驗證(B-LT / B-LTA)

B-LT 與 B-LTA 等級會自動擷取並嵌入撤銷資料:

  • OcspClient — 根據憑證的 AIA 擴充,查詢 OCSP 回應者(RFC 6960)
  • CrlFetcher — 從發佈點下載 CRL(RFC 5280)
  • DSS(文件安全儲存區) — 將 OCSP 回應與 CRL 儲存在文件安全儲存區中
  • VRI(驗證相關資訊) — 每個簽章的驗證資料(選用,依 ETSI 建議)

B-LTA 還會額外新增文件時間戳記,啟動典藏迴圈 — 文件可透過重新加蓋時間戳記來無限期延長有效性。

簽章外觀

預設情況下,簽章為不可見。若要建立可見的簽章小工具:

php
use Yeeefang\TcpdfNext\Security\Signature\SignatureAppearance;

$pdf = Document::create()
    ->setSignature($cert, SignatureLevel::PAdES_B_T, $tsa)
    ->setSignatureAppearance(
        SignatureAppearance::visible(x: 20, y: 250, w: 80, h: 30)
    )
    ->addPage()
    ->cell(0, 10, 'Document with visible signature')
    ->save('visible-signature.pdf');

若要明確設定不可見簽章:

php
$pdf->setSignatureAppearance(SignatureAppearance::invisible());

簽章等級比較

特性B-BB-TB-LTB-LTA
數位簽章VVVV
簽署憑證VVVV
RFC 3161 時間戳記VVV
DSS(OCSP + CRL)VV
文件時間戳記V
典藏迴圈V
憑證過期後可驗證VV
無限期可驗證V

方法參考

php
$pdf->setSignature(
    CertificateInfo   $cert,           // 憑證與私密金鑰
    SignatureLevel    $level,           // B-B、B-T、B-LT 或 B-LTA
    ?TsaClient        $tsa   = null,   // B-T、B-LT、B-LTA 必須提供
);

回傳 static 以支援鏈式串接。簽章在呼叫 save()output() 時套用。

簽章演算法透過 phpseclib3 實作:RSA PKCS#1 v1.5(預設,最廣泛的相容性)與 RSASSA-PSS(更強的填充方案,建議新部署使用)。

完整 PKCS#12 範例

php
use Yeeefang\TcpdfNext\Core\Document;
use Yeeefang\TcpdfNext\Security\Signature\CertificateInfo;
use Yeeefang\TcpdfNext\Security\Signature\SignatureAppearance;
use Yeeefang\TcpdfNext\Contracts\SignatureLevel;
use Yeeefang\TcpdfNext\Security\Timestamp\TsaClient;

// 從 PKCS#12 載入憑證
$cert = CertificateInfo::fromPkcs12(
    p12Path: '/path/to/certificate.p12',
    password: 'pkcs12-password',
);

// 設定時間戳記授權
$tsa = new TsaClient('https://freetsa.org/tsr');

// 建立具有 B-LTA 等級簽章的文件
$pdf = Document::create()
    ->setTitle('Signed Contract')
    ->setAuthor('Legal Department')
    ->setSignature($cert, SignatureLevel::PAdES_B_LTA, $tsa)
    ->setSignatureAppearance(
        SignatureAppearance::visible(x: 20, y: 250, w: 80, h: 30)
    )
    ->addPage()
    ->setFont('Helvetica', 'B', 18)
    ->cell(0, 15, 'Service Agreement', newLine: true)
    ->setFont('Helvetica', '', 12)
    ->multiCell(0, 6, 'This document has been digitally signed with a PAdES B-LTA '
        . 'archival signature. The signature includes a trusted timestamp and '
        . 'embedded revocation data for long-term validation.')
    ->save('signed-contract.pdf');

以 LGPL-3.0-or-later 授權釋出。