跳轉到

PII 遮蔽與個資合規

PHP Compatibility

This example uses PHP 8.5 syntax. If your environment runs PHP 8.1 or 7.4, use NextPDF Backport for a backward-compatible build.

個人識別資訊(PII,Personally Identifiable Information)遮蔽是 GDPR(EU 2016/679)、台灣個人資料保護法(個資法)及各行業合規框架的核心要求。NextPDF Pro 的遮蔽機制在排版時期攔截敏感文字,確保敏感資料永遠不會進入:

  • PDF 內容串流(content stream)
  • 字型子集(font subset)
  • ToUnicode CMap(字型反查表)
  • 文件詮釋資料(XMP metadata)
  • 書籤文字或注釋

架構:TextPreprocessor 管線

PII 遮蔽整合於 Core 的 TextPreprocessorInterface 介面。RedactionTextPreprocessor 在文字進入排版引擎之前攔截並轉換:

graph LR
    Input["原始文字\n(含 PII)"] --> Preprocessor["RedactionTextPreprocessor\n(排版時期攔截)"]
    Preprocessor --> Detector["PiiDetector\n(規則/RegEx/ML)"]
    Detector --> Redactor["PiiRedactor\n(替換/遮蔽/雜湊)"]
    Redactor --> Layout["排版引擎\n(乾淨文字)"]
    Layout --> Stream["PDF 內容串流\n(永不含原始 PII)"]
    Preprocessor --> AuditLog["合規審計日誌\n(遮蔽操作記錄)"]
    style Stream fill:#16a34a,color:#fff
    style AuditLog fill:#D97706,color:#fff

快速開始

use NextPDF\Pro\Redaction\RedactionTextPreprocessor;
use NextPDF\Pro\Redaction\Detector\RegexPiiDetector;
use NextPDF\Pro\Redaction\Redactor\MaskRedactor;
use NextPDF\Pro\Redaction\Redactor\HashRedactor;
use NextPDF\Pro\Redaction\PiiCategory;
use NextPDF\Pro\Redaction\Audit\RedactionAuditLogger;
use NextPDF\Pro\Document\ProDocument;

// 1. 設定偵測規則
$detector = RegexPiiDetector::withBuiltinRules(
    categories: [
        PiiCategory::TaiwanNationalId,      // 台灣身分證字號 A123456789
        PiiCategory::TaiwanUniformNumber,    // 統一編號
        PiiCategory::EmailAddress,           // 電子郵件
        PiiCategory::PhoneNumber,            // 電話號碼(支援多國格式)
        PiiCategory::CreditCard,             // 信用卡號(Luhn 驗證)
        PiiCategory::BankAccount,            // 銀行帳號
        PiiCategory::IpAddress,              // IP 位址
    ],
);

// 可加入自訂正規表達式規則
$detector->addCustomRule(
    name: 'employee-id',
    pattern: '/EMP-\d{6}/',
    category: PiiCategory::Custom,
);

// 2. 設定遮蔽策略
$redactor = MaskRedactor::create(
    maskChar: '█',          // 遮蔽字元
    preserveLength: true,   // 保留原始長度(維持排版)
    preservePrefix: 3,      // 保留前 N 個字元(如身分證前段 A12█████)
);

// 3. 設定審計日誌
$auditLogger = new RedactionAuditLogger(
    logPath: '/var/log/nextpdf/redaction.jsonl',
    includePosition: true,   // 記錄頁碼與位置
    includeCategory: true,   // 記錄 PII 類型(不記錄原始值)
);

// 4. 建立 TextPreprocessor
$preprocessor = new RedactionTextPreprocessor(
    detector: $detector,
    redactor: $redactor,
    auditLogger: $auditLogger,
);

// 5. 注入至 ProDocument
$doc = ProDocument::createStandalone(
    textPreprocessors: [$preprocessor],
);

// 6. 正常生成文件——PII 自動遮蔽
$doc->addPage();
$doc->text('客戶姓名:王大明', x: 20, y: 30);
$doc->text('身分證號:A123456789', x: 20, y: 45);   // 自動遮蔽為 A12█████
$doc->text('Email:wang@example.com', x: 20, y: 60); // 自動遮蔽
$doc->text('信用卡:4111-1111-1111-1111', x: 20, y: 75); // 自動遮蔽

$pdf = $doc->render();
// 輸出的 PDF 中,上述 PII 已在串流層級完全遮蔽

遮蔽策略選項

MaskRedactor — 字元替換

use NextPDF\Pro\Redaction\Redactor\MaskRedactor;

// 完全遮蔽
$redactor = MaskRedactor::create(maskChar: '█');

// 保留部分資訊(常見於客服場景)
$redactor = MaskRedactor::create(
    maskChar: '*',
    preservePrefix: 3,  // 前 3 字元可見
    preserveSuffix: 4,  // 後 4 字元可見(適合信用卡末 4 碼)
    preserveLength: true,
);

HashRedactor — 不可逆雜湊

use NextPDF\Pro\Redaction\Redactor\HashRedactor;

// 以 SHA-256 雜湊取代原始值(可用於追蹤但不可還原)
$redactor = HashRedactor::create(
    algorithm: 'sha256',
    salt: (string) getenv('REDACTION_HASH_SALT'), // 必填:防止彩虹表攻擊
    outputLength: 8,    // 截取前 8 個字元
    prefix: '[HASH:',
    suffix: ']',
);
// 輸出範例:[HASH:a3f8c91b]

TokenRedactor — 可逆代換

use NextPDF\Pro\Redaction\Redactor\TokenRedactor;
use NextPDF\Pro\Redaction\Token\DatabaseTokenStore;

// 將 PII 替換為隨機 Token,Token 對應關係安全儲存於外部
$tokenStore = new DatabaseTokenStore(pdo: $pdo, tableName: 'pii_tokens');

$redactor = TokenRedactor::create(
    tokenStore: $tokenStore,
    tokenPrefix: 'PII-',
    tokenLength: 16,
);
// 輸出範例:PII-4f8a9b2c1e3d7f6a
// 授權使用者可透過 tokenStore 還原原始值

複合遮蔽管線

單一文件可串接多個 Preprocessor,依優先序執行:

use NextPDF\Pro\Redaction\RedactionTextPreprocessor;
use NextPDF\Pro\Redaction\Detector\CompositeDetector;

// 組合多個偵測器
$compositeDetector = new CompositeDetector([
    RegexPiiDetector::withBuiltinRules([PiiCategory::TaiwanNationalId, PiiCategory::CreditCard]),
    NlpPiiDetector::forLanguage('zh-Hant'), // NLP 偵測(需安裝額外模型)
    CustomRuleDetector::fromYaml('/config/pii-rules.yaml'),
]);

$preprocessor = new RedactionTextPreprocessor(
    detector: $compositeDetector,
    redactor: MaskRedactor::create(maskChar: '█'),
    auditLogger: $auditLogger,
);

批次遮蔽既有 PDF

除在生成時遮蔽外,Pro 也支援對既有 PDF 執行後處理遮蔽:

use NextPDF\Pro\Redaction\PdfRedactionProcessor;
use NextPDF\Pro\Redaction\RedactionReport;

$processor = new PdfRedactionProcessor(
    detector: $detector,
    redactor: $redactor,
    auditLogger: $auditLogger,
);

$inputPdf = file_get_contents('/uploads/contract.pdf');

/** @var RedactionReport $report */
$report = $processor->process(
    pdfBytes: $inputPdf,
    options: RedactionProcessorOptions::create(
        redactContent: true,         // 遮蔽頁面內容
        redactMetadata: true,        // 清除 XMP 詮釋資料中的 PII
        redactAnnotations: true,     // 遮蔽注釋文字
        redactBookmarks: true,       // 遮蔽書籤標題
        flattenForms: false,         // 保留表單欄位結構
    ),
);

$redactedPdf = $report->getRedactedPdf();
$summary = $report->getSummary(); // RedactionSummary: 遮蔽數量、類型分布

file_put_contents('/output/redacted-contract.pdf', $redactedPdf);

echo sprintf(
    'Redacted %d PII instances across %d pages. Categories: %s',
    $summary->getTotalRedacted(),
    $summary->getAffectedPageCount(),
    implode(', ', $summary->getCategoryBreakdown()),
);

合規審計日誌格式

每次遮蔽操作均產生 JSONL 格式的審計記錄(僅記錄操作事實,不記錄原始 PII 值):

{
  "timestamp": "2026-03-04T10:23:45+08:00",
  "document_id": "doc-7f3a9b2c",
  "page": 1,
  "position": {"x": 20.0, "y": 45.0},
  "pii_category": "TaiwanNationalId",
  "redaction_strategy": "mask",
  "original_length": 10,
  "redacted_value": "A12█████",
  "rule_matched": "tw-national-id-builtin",
  "operator": "system"
}

PDPA(台灣個資法)合規要點

個資法條文 要求 NextPDF Pro 對應功能
第 11 條 個資正確性,有錯誤應更正 TokenRedactor 支援可逆遮蔽
第 19 條 特定目的外不得蒐集利用 PiiCategory 精確分類控制
第 27 條 安全維護措施義務 審計日誌 + 串流層級遮蔽
第 28 條 損害賠償責任 完整操作記錄作為舉證依據

相關資源