PDF Redaction in C#: Remove Sensitive Data and Sanitize Documents with IronPDF
PDF內容刪除在C# .NET中使用IronPDF可以永久移除文件內部結構中的敏感內容,不僅僅是視覺上的覆蓋,從而確保無法通過複製、搜尋或法醫分析來恢復原始資料。 這遠不止是文字上的黑色塊:IronPDF提供正則表達式模式匹配的文字刪除、針對簽名和圖片的區域型刪除、元資料剝離、文件清理以消除嵌入的腳本、以及漏洞掃描,為.NET開發人員提供完整的工具集,以進行符合HIPAA、GDPR和PCI DSS的文件保護工作流程。
重點摘要:快速入門指南本教程涵蓋了在C# .NET中從PDF文件中永久移除敏感內容,包括文字模式、圖片區域、元資料和嵌入腳本。
- **物件:**在醫療、法律、財務或政府背景中處理敏感文件的.NET開發人員。
- **建構內容:**使用正則表達式模式匹配進行文字刪除(如SSN、信用卡、電子郵件),基於座標的區域刪除簽名和照片,清理元資料,PDF清理以去除嵌入的腳本,以及基於YARA的漏洞掃描。
- 運行環境: .NET 10, .NET 8 LTS, .NET Framework 4.6.2+,以及.NET Standard 2.0。不需要外部依賴,所有操作均在本地運行。
- 使用時機: 當您需要在法律取證、FOIA請求或外部分發時分享文件,並確保被移除的內容確實消失時。
- 技術意義: 視覺覆蓋會使原始文字在PDF的內容流中仍然可恢復。 IronPDF的刪除將文字的資料直接從文件結構中刪除,使得恢復變得不可能。
使用寥寥幾行程式碼即可從PDF中刪除敏感文字:
-
1Install IronPDF with NuGet Package Manager
PM > Install-Package IronPdf
-
2Copy and run this code snippet.
using IronPdf; PdfDocument pdf = PdfDocument.FromFile("confidential-report.pdf"); pdf.RedactTextOnAllPages("CONFIDENTIAL"); pdf.SaveAs("redacted-report.pdf");C# -
3Deploy to test on your live environment
Start using IronPDF in your project today with a free trial
在您購買或註冊IronPDF的30天試用後,請在應用程式的開頭新增您的授權金鑰。
IronPdf.License.LicenseKey = "KEY";Imports IronPdf
IronPdf.License.LicenseKey = "KEY"Start using IronPDF in your project today with a free trial.
PM > Install-Package IronPdf
- 總結:快速入門指南
- 從PDF文件中刪除文字
- 模式配對和自動刪除
- 區域型刪除
- 從PDF的元資料中移除敏感資料
- 在.NET中的PDF清理
- 完整的工作流程
- 下一步
什麼是真正的刪除和視覺覆蓋之間的區別?
理解真正的刪除和視覺覆蓋之間的區別對於處理敏感文件的人來說至關重要。 許多工具和手工方法創造出刪除的外觀,但實際上並未真正移除底層資料。 這種錯誤的安全感已造成多次高調的資料洩漏和合規失敗。
視覺覆蓋的方法通常在敏感內容上繪製不透明的形狀。 文字在PDF結構內仍然完整無損。 查看文件的人看到的是黑色矩形,但原始字元仍在文件的內容流中存在。 選取頁面上所有文字,使用可存取性工具或檢查原始PDF資料會暴露所有原本被認為已隱藏的內容。 在法庭案件中,紅色的文件被對方律師輕易取消了遮掩。 政府機構曾不小心洩露看似被刪除但仍完整可恢復的機密資訊。
真正的刪除運作方式不同。 當您使用IronPDF的刪除方法時,程式庫會在PDF的內部結構中定位指定的文字並將其徹底移除。 字元資料從內容流中被刪除。 視覺表現被替換為一個刪除標記,通常是黑色矩形,但文件中不再存在原始內容。選取、複製或者法醫分析無法恢復已經永久被刪除的內容。
IronPDF透過在結構層面上修改PDF來實現真正的刪除。 RedactTextOnAllPages方法及其變體在頁面內容中搜索,識別符合的文字,將其從文件物件模型中移除,並可選地畫出指示器以標示內容原本的所在位置。 此方式符合像NIST等組織對於安全文件刪除的指南。
實際影響是重大的。 如果您需要外部共享文件、提交文件進行法律取證、根據資訊自由請求發佈記錄或在分發報告時保護個人身份資訊,只有真正的刪除才提供足夠的保護。 視覺覆蓋可能適用於僅在內部草稿中想要減少對某些部分的注意力,但它們不應被信任用於真正的資料保護。 欲了解更多文件安全措施,請參閱我們有關加密PDF和數位簽名的指導。
How do I Redact PDF Text in C# Across an Entire Document?
最常見的刪除場景涉及刪除整個文件中的某些特定文字實例。 也許您需要從報告中刪除某人的姓名,從財務報表中移除帳戶號碼,或從外部分發前剝離內部參考程式碼。 IronPDF透過使用RedactTextOnAllPages方法使這一過程簡單直觀。
輸入
一份包含個人資訊的員工記錄文件,包括姓名、社會安全號和員工ID。
using IronPdf;
// Load the source document
PdfDocument pdf = PdfDocument.FromFile("employee-records.pdf");
// Redact an employee name from the entire document
pdf.RedactTextOnAllPages("John Smith");
// Redact a Social Security Number
pdf.RedactTextOnAllPages("123-45-6789");
// Redact an internal employee ID
pdf.RedactTextOnAllPages("EMP-2024-0042");
// Save the cleaned document
pdf.SaveAs("employee-records-redacted.pdf");Imports IronPdf
' Load the source document
Dim pdf As PdfDocument = PdfDocument.FromFile("employee-records.pdf")
' Redact an employee name from the entire document
pdf.RedactTextOnAllPages("John Smith")
' Redact a Social Security Number
pdf.RedactTextOnAllPages("123-45-6789")
' Redact an internal employee ID
pdf.RedactTextOnAllPages("EMP-2024-0042")
' Save the cleaned document
pdf.SaveAs("employee-records-redacted.pdf")此程式碼將一個包含員工資訊的PDF載入,並逐一呼叫RedactTextOnAllPages連結來刪除三個機密資料。 每次呼叫會搜尋文件中的每一頁,並永久刪除所有匹配的員工姓名、社會安全號和內部ID。
範例輸出
預設行為是在刪除文字的位置處畫黑矩形,並在文件結構中用星號取代實際字元。 這提供了刪除已發生的視覺確認,並確保原始內容完全消失。
處理較長的文件或多個刪除目標時,您可以有效地連接這些呼叫:
using IronPdf;
using System.Collections.Generic;
// Load the document once
PdfDocument pdf = PdfDocument.FromFile("quarterly-report.pdf");
// Define all terms that need redaction
List<string> sensitiveTerms = new List<string>
{
"Project Titan",
"Sarah Johnson",
"Budget: $4.2M",
"Q3-INTERNAL-2024",
"sarah.johnson@company.com"
};
// Redact each term
foreach (string term in sensitiveTerms)
{
pdf.RedactTextOnAllPages(term);
}
// Save the result
pdf.SaveAs("quarterly-report-public.pdf");Imports IronPdf
Imports System.Collections.Generic
' Load the document once
Dim pdf As PdfDocument = PdfDocument.FromFile("quarterly-report.pdf")
' Define all terms that need redaction
Dim sensitiveTerms As New List(Of String) From {
"Project Titan",
"Sarah Johnson",
"Budget: $4.2M",
"Q3-INTERNAL-2024",
"sarah.johnson@company.com"
}
' Redact each term
For Each term As String In sensitiveTerms
pdf.RedactTextOnAllPages(term)
Next
' Save the result
pdf.SaveAs("quarterly-report-public.pdf")這種模式在您有已知的要刪除的敏感值列表時效果很好。 文件一次載入,所有刪除在記憶體中應用,最終結果即被儲存。 每個詞彙單獨處理,因此部分匹配或詞彙之間的格式差異不會影響其他刪除。
如何僅在特定頁面中刪除文字?
有時您需要更精確地控制刪除的發生地點。 文件可能有一個需要保持完整的資訊封面頁,或您知道機密資料僅在某些特定部分中出現。 IronPDF提供RedactTextOnPages針對多個特定頁面的目標化呼叫。
輸入
一份包含客戶姓名在簽名頁和財務條款在特定頁中散布的多頁合同組合。
using IronPdf;
// Load the document
PdfDocument pdf = PdfDocument.FromFile("contract-bundle.pdf");
// Redact text only on page 1 (index 0)
pdf.RedactTextOnPage(0, "Client Name: Acme Corporation");
// Redact text on pages 3, 5, and 7 (indices 2, 4, 6)
int[] financialPages = { 2, 4, 6 };
pdf.RedactTextOnPages(financialPages, "Payment Terms: Net 30");
// Other pages remain untouched except for the specific redactions applied
pdf.SaveAs("contract-bundle-redacted.pdf");Imports IronPdf
' Load the document
Dim pdf As PdfDocument = PdfDocument.FromFile("contract-bundle.pdf")
' Redact text only on page 1 (index 0)
pdf.RedactTextOnPage(0, "Client Name: Acme Corporation")
' Redact text on pages 3, 5, and 7 (indices 2, 4, 6)
Dim financialPages As Integer() = {2, 4, 6}
pdf.RedactTextOnPages(financialPages, "Payment Terms: Net 30")
' Other pages remain untouched except for the specific redactions applied
pdf.SaveAs("contract-bundle-redacted.pdf")此程式碼透過使用RedactTextOnPages移除多個特定頁面上的內容。 客戶姓名僅從頁1(索引為0)中移除,而付款條款在頁3、5和7(索引為2、4、6)中被移除,其他頁面不受影響。
範例輸出
IronPDF中的頁面索引是從0開始的,這意味著第一頁的索引是0,第二頁是1,依此類推。 這符合標準程式編寫慣例,並與大多數開發人員對於陣列存取的思維方式一致。
在處理大量文件時,針對特定頁面的目標化提高了性能。 而不是掃描數百頁以搜尋僅在少數位置出現的文字,您可以指導刪除引擎精確定位要查找的地方。 這很重要,特別是在批量處理場景中,您可能要處理數以千計的文件。 為了達到最高吞吐量,考慮使用非同步和多執行緒技術。
using IronPdf;
// Process a large document efficiently
PdfDocument pdf = PdfDocument.FromFile("annual-report-500-pages.pdf");
// We know from document structure that:
// - Executive summary with names is on pages 1-3
// - Financial data is on pages 45-60
// - Appendix with employee info is on pages 480-495
// Redact executive names from summary section
for (int i = 0; i <= 2; i++)
{
pdf.RedactTextOnPage(i, "CEO: Robert Williams");
pdf.RedactTextOnPage(i, "CFO: Maria Garcia");
}
// Redact specific financial figures from the financial section
int[] financialSection = { 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59 };
pdf.RedactTextOnPages(financialSection, "Net Revenue: $847M");
// Redact employee identifiers from appendix
for (int i = 479; i <= 494; i++)
{
pdf.RedactTextOnPage(i, "Employee ID:");
}
pdf.SaveAs("annual-report-public-release.pdf");Imports IronPdf
' Process a large document efficiently
Dim pdf As PdfDocument = PdfDocument.FromFile("annual-report-500-pages.pdf")
' We know from document structure that:
' - Executive summary with names is on pages 1-3
' - Financial data is on pages 45-60
' - Appendix with employee info is on pages 480-495
' Redact executive names from summary section
For i As Integer = 0 To 2
pdf.RedactTextOnPage(i, "CEO: Robert Williams")
pdf.RedactTextOnPage(i, "CFO: Maria Garcia")
Next
' Redact specific financial figures from the financial section
Dim financialSection As Integer() = {44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59}
pdf.RedactTextOnPages(financialSection, "Net Revenue: $847M")
' Redact employee identifiers from appendix
For i As Integer = 479 To 494
pdf.RedactTextOnPage(i, "Employee ID:")
Next
pdf.SaveAs("annual-report-public-release.pdf")這種目標化的方法僅處理500頁文件中的相關部分,與全頁掃描每個刪除術語相比,顯著縮短執行時間。
如何自訂被刪除內容的外觀?
IronPDF提供多種參數來控制刪除在最終文件中如何顯示。 您可以調整大小寫靈敏性、全詞匹配、是否繪製視覺矩形以及在刪除內容替換的文字。
輸入
一份法律簡報,包含多種需要不同刪除處理的敏感術語,包括分類標籤、密碼和內部參考程式碼。
using IronPdf;
// Load the document
PdfDocument pdf = PdfDocument.FromFile("legal-brief.pdf");
// Case-sensitive redaction: only matches exact case
// "CLASSIFIED" will be redacted but "classified" or "Classified" will not
pdf.RedactTextOnAllPages(
"CLASSIFIED",
CaseSensitive: true,
OnlyMatchWholeWords: true,
DrawRectangles: true,
ReplacementText: "[REDACTED]"
);
// Case-insensitive redaction: matches regardless of case
// Will redact "Secret", "SECRET", "secret", etc.
pdf.RedactTextOnAllPages(
"secret",
CaseSensitive: false,
OnlyMatchWholeWords: true,
DrawRectangles: true,
ReplacementText: "*****"
);
// Whole word disabled: matches partial strings too
// Will redact "password", "passwords", "mypassword123", etc.
pdf.RedactTextOnAllPages(
"password",
CaseSensitive: false,
OnlyMatchWholeWords: false,
DrawRectangles: true,
ReplacementText: "XXXXX"
);
// No visual rectangle: text is removed but no black box appears
// Useful when you want seamless removal without obvious redaction marks
pdf.RedactTextOnAllPages(
"internal-reference-code",
CaseSensitive: true,
OnlyMatchWholeWords: true,
DrawRectangles: false,
ReplacementText: ""
);
pdf.SaveAs("legal-brief-redacted.pdf");Imports IronPdf
' Load the document
Dim pdf As PdfDocument = PdfDocument.FromFile("legal-brief.pdf")
' Case-sensitive redaction: only matches exact case
' "CLASSIFIED" will be redacted but "classified" or "Classified" will not
pdf.RedactTextOnAllPages(
"CLASSIFIED",
CaseSensitive:=True,
OnlyMatchWholeWords:=True,
DrawRectangles:=True,
ReplacementText:="[REDACTED]"
)
' Case-insensitive redaction: matches regardless of case
' Will redact "Secret", "SECRET", "secret", etc.
pdf.RedactTextOnAllPages(
"secret",
CaseSensitive:=False,
OnlyMatchWholeWords:=True,
DrawRectangles:=True,
ReplacementText:="*****"
)
' Whole word disabled: matches partial strings too
' Will redact "password", "passwords", "mypassword123", etc.
pdf.RedactTextOnAllPages(
"password",
CaseSensitive:=False,
OnlyMatchWholeWords:=False,
DrawRectangles:=True,
ReplacementText:="XXXXX"
)
' No visual rectangle: text is removed but no black box appears
' Useful when you want seamless removal without obvious redaction marks
pdf.RedactTextOnAllPages(
"internal-reference-code",
CaseSensitive:=True,
OnlyMatchWholeWords:=True,
DrawRectangles:=False,
ReplacementText:=""
)
pdf.SaveAs("legal-brief-redacted.pdf")此程式碼通過使用RedactTextOnAllPages的可選參數顯示四種不同的刪除配置。 它展示了大小寫敏感的精確匹配,使用"[REDACTED]"替換,大小寫不敏感的匹配,使用星號進行替換,部分詞匹配以抓住像"passwords"這樣的變化,和無視覺矩形進行的無痕移除以實現無縫的內容刪除。
範例輸出
參數根據您的需求有不同的用途:
CaseSensitive決定匹配是否考慮字母大小寫。 法律文件通常使用特定的大小寫形式來攜帶意義,因此大小寫敏感的匹配確保您只刪除精確匹配。 處理大小寫可能變化的普通文字時,可能需要不區分大小寫的匹配來抓住所有實例。
OnlyMatchWholeWords控制搜尋是否匹配整個單詞或部分字串。 在刪除名稱時,您通常希望進行整個词匹配,這樣"Smith"不會意外地刪除"Blacksmith"或"Smithfield"的一部分。 在刪除模式如帳戶號前輟時,可能需要部分匹配來抓住變化。
DrawRectangles指定黑色框是否顯示在刪除內容的位置。 大多數監管和法律上下文需要可見的刪除標記作為刻意刪除而非意外遺漏的證據。 內部工作流程可能偏好無痕移除以獲得更清晰的輸出。
ReplacementText定義在哪些字元會出現在刪除內容的替代位置。 常見的選擇包括星號、"REDACTED"標籤或空字串。 替換文字會在文件結構中出現,萬一有人試圖從刪除的區域選取或複製。
如何使用正則表達式尋找並刪除敏感模式?
刪除已知的文字字串適用于有具體數值要移除的情況,但許多機密資料型別遵循可預測的格式而非固定的數值。 社會安全號、信用卡號碼、電子郵件地址、電話號碼和日期都有可識別的格式,可以通過正則表達式來匹配。 建立一個基於模式的刪除系統可以讓您在不預先知道每個具體數值的情況下從PDF內容中移除私有資訊。
IronPDF的文字提取功能結合刪除方法,使得強大的模式匹配工作流程成為可能。 您提取文字,使用.NET的正則表達式標識匹配項,然後刪除每個發現的數值。
using IronPdf;
using System.Text.RegularExpressions;
using System.Collections.Generic;
public class PatternRedactor
{
// Common patterns for sensitive data
private static readonly Dictionary<string, string> SensitivePatterns = new Dictionary<string, string>
{
// US Social Security Number: 123-45-6789
{ "SSN", @"\b\d{3}-\d{2}-\d{4}\b" },
// Credit Card Numbers: various formats with 13-19 digits
{ "CreditCard", @"\b(?:\d{4}[-\s]?){3}\d{1,4}\b" },
// Email Addresses
{ "Email", @"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b" },
// US Phone Numbers: (123) 456-7890 or 123-456-7890
{ "Phone", @"\b(?:\(\d{3}\)\s?|\d{3}[-.])\d{3}[-.]?\d{4}\b" },
// Dates: MM/DD/YYYY or MM-DD-YYYY
{ "Date", @"\b\d{1,2}[/-]\d{1,2}[/-]\d{2,4}\b" },
// IP Addresses
{ "IPAddress", @"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b" }
};
public void RedactPatterns(string inputPath, string outputPath, params string[] patternNames)
{
// Load the PDF
PdfDocument pdf = PdfDocument.FromFile(inputPath);
// Extract all text from the document
string fullText = pdf.ExtractAllText();
// Track unique matches to avoid duplicate redaction attempts
HashSet<string> matchesToRedact = new HashSet<string>();
// Find all matches for requested patterns
foreach (string patternName in patternNames)
{
if (SensitivePatterns.TryGetValue(patternName, out string pattern))
{
Regex regex = new Regex(pattern, RegexOptions.IgnoreCase);
MatchCollection matches = regex.Matches(fullText);
foreach (Match match in matches)
{
matchesToRedact.Add(match.Value);
}
}
}
// Redact each unique match
foreach (string sensitiveValue in matchesToRedact)
{
pdf.RedactTextOnAllPages(sensitiveValue);
}
// Save the redacted document
pdf.SaveAs(outputPath);
}
}
// Usage example
class Program
{
static void Main()
{
PatternRedactor redactor = new PatternRedactor();
// Redact SSNs and credit cards from a financial document
redactor.RedactPatterns(
"customer-data.pdf",
"customer-data-safe.pdf",
"SSN", "CreditCard", "Email"
);
}
}Imports IronPdf
Imports System.Text.RegularExpressions
Imports System.Collections.Generic
Public Class PatternRedactor
' Common patterns for sensitive data
Private Shared ReadOnly SensitivePatterns As New Dictionary(Of String, String) From {
' US Social Security Number: 123-45-6789
{"SSN", "\b\d{3}-\d{2}-\d{4}\b"},
' Credit Card Numbers: various formats with 13-19 digits
{"CreditCard", "\b(?:\d{4}[-\s]?){3}\d{1,4}\b"},
' Email Addresses
{"Email", "\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b"},
' US Phone Numbers: (123) 456-7890 or 123-456-7890
{"Phone", "\b(?:\(\d{3}\)\s?|\d{3}[-.])\d{3}[-.]?\d{4}\b"},
' Dates: MM/DD/YYYY or MM-DD-YYYY
{"Date", "\b\d{1,2}[/-]\d{1,2}[/-]\d{2,4}\b"},
' IP Addresses
{"IPAddress", "\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b"}
}
Public Sub RedactPatterns(inputPath As String, outputPath As String, ParamArray patternNames As String())
' Load the PDF
Dim pdf As PdfDocument = PdfDocument.FromFile(inputPath)
' Extract all text from the document
Dim fullText As String = pdf.ExtractAllText()
' Track unique matches to avoid duplicate redaction attempts
Dim matchesToRedact As New HashSet(Of String)()
' Find all matches for requested patterns
For Each patternName As String In patternNames
Dim pattern As String = Nothing
If SensitivePatterns.TryGetValue(patternName, pattern) Then
Dim regex As New Regex(pattern, RegexOptions.IgnoreCase)
Dim matches As MatchCollection = regex.Matches(fullText)
For Each match As Match In matches
matchesToRedact.Add(match.Value)
Next
End If
Next
' Redact each unique match
For Each sensitiveValue As String In matchesToRedact
pdf.RedactTextOnAllPages(sensitiveValue)
Next
' Save the redacted document
pdf.SaveAs(outputPath)
End Sub
End Class
' Usage example
Class Program
Shared Sub Main()
Dim redactor As New PatternRedactor()
' Redact SSNs and credit cards from a financial document
redactor.RedactPatterns(
"customer-data.pdf",
"customer-data-safe.pdf",
"SSN", "CreditCard", "Email"
)
End Sub
End Class這種基於模式的方法能良好擴展,因為您只需一次性定義模式,然後可以應用於任何文件。 新增新的資料型別只需將新的正則表達式模式新增到字典中。
如何構建可重複使用的敏感資料掃描器?
在生產環境中,您通常需要掃描文件並報告所有存在的機密資訊,然後再決定是否刪除。 這有助於合規審計,並允許對刪除決策進行人工檢閱。 以下類別提供掃描功能以及刪除功能。
using IronPdf;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Linq;
public class SensitiveDataMatch
{
public string PatternType { get; set; }
public string Value { get; set; }
public int PageNumber { get; set; }
}
public class ScanResult
{
public string FilePath { get; set; }
public List<SensitiveDataMatch> Matches { get; set; } = new List<SensitiveDataMatch>();
public bool ContainsSensitiveData => Matches.Count > 0;
public Dictionary<string, int> GetSummary()
{
return Matches.GroupBy(m => m.PatternType)
.ToDictionary(g => g.Key, g => g.Count());
}
}
public class DocumentScanner
{
private readonly Dictionary<string, string> _patterns;
public DocumentScanner()
{
_patterns = new Dictionary<string, string>
{
{ "Social Security Number", @"\b\d{3}-\d{2}-\d{4}\b" },
{ "Credit Card", @"\b(?:\d{4}[-\s]?){3}\d{1,4}\b" },
{ "Email Address", @"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b" },
{ "Phone Number", @"\b(?:\(\d{3}\)\s?|\d{3}[-.])\d{3}[-.]?\d{4}\b" },
{ "Date of Birth Pattern", @"\b(?:DOB|Date of Birth|Birth Date)[:\s]+\d{1,2}[/-]\d{1,2}[/-]\d{2,4}\b" }
};
}
public ScanResult ScanDocument(string filePath)
{
ScanResult result = new ScanResult { FilePath = filePath };
PdfDocument pdf = PdfDocument.FromFile(filePath);
// Scan each page individually to track location
for (int pageIndex = 0; pageIndex < pdf.PageCount; pageIndex++)
{
string pageText = pdf.ExtractTextFromPage(pageIndex);
foreach (var pattern in _patterns)
{
Regex regex = new Regex(pattern.Value, RegexOptions.IgnoreCase);
MatchCollection matches = regex.Matches(pageText);
foreach (Match match in matches)
{
result.Matches.Add(new SensitiveDataMatch
{
PatternType = pattern.Key,
Value = MaskValue(match.Value, pattern.Key),
PageNumber = pageIndex + 1
});
}
}
}
return result;
}
// Partially mask values for safe storage
private string MaskValue(string value, string patternType)
{
if (patternType == "Social Security Number" && value.Length >= 4)
{
return "XXX-XX-" + value.Substring(value.Length - 4);
}
if (patternType == "Credit Card" && value.Length >= 4)
{
return "****-****-****-" + value.Substring(value.Length - 4);
}
if (patternType == "Email Address")
{
int atIndex = value.IndexOf('@');
if (atIndex > 2)
{
return value.Substring(0, 2) + "***" + value.Substring(atIndex);
}
}
return value.Length > 4 ? value.Substring(0, 2) + "***" : "****";
}
public void ScanAndRedact(string inputPath, string outputPath)
{
// First scan to identify sensitive data
ScanResult scanResult = ScanDocument(inputPath);
if (!scanResult.ContainsSensitiveData)
{
return;
}
// Load document for redaction
PdfDocument pdf = PdfDocument.FromFile(inputPath);
// Extract unique actual values (not masked) for redaction
string fullText = pdf.ExtractAllText();
HashSet<string> valuesToRedact = new HashSet<string>();
foreach (var pattern in _patterns)
{
Regex regex = new Regex(pattern.Value, RegexOptions.IgnoreCase);
foreach (Match match in regex.Matches(fullText))
{
valuesToRedact.Add(match.Value);
}
}
// Apply redactions
foreach (string value in valuesToRedact)
{
pdf.RedactTextOnAllPages(value);
}
pdf.SaveAs(outputPath);
}
}
// Usage
class Program
{
static void Main()
{
DocumentScanner scanner = new DocumentScanner();
// Scan only (for audit purposes)
ScanResult result = scanner.ScanDocument("application-form.pdf");
var summary = result.GetSummary();
// Scan and redact in one operation
scanner.ScanAndRedact("application-form.pdf", "application-form-redacted.pdf");
}
}Imports IronPdf
Imports System.Collections.Generic
Imports System.Text.RegularExpressions
Imports System.Linq
Public Class SensitiveDataMatch
Public Property PatternType As String
Public Property Value As String
Public Property PageNumber As Integer
End Class
Public Class ScanResult
Public Property FilePath As String
Public Property Matches As List(Of SensitiveDataMatch) = New List(Of SensitiveDataMatch)()
Public ReadOnly Property ContainsSensitiveData As Boolean
Get
Return Matches.Count > 0
End Get
End Property
Public Function GetSummary() As Dictionary(Of String, Integer)
Return Matches.GroupBy(Function(m) m.PatternType) _
.ToDictionary(Function(g) g.Key, Function(g) g.Count())
End Function
End Class
Public Class DocumentScanner
Private ReadOnly _patterns As Dictionary(Of String, String)
Public Sub New()
_patterns = New Dictionary(Of String, String) From {
{"Social Security Number", "\b\d{3}-\d{2}-\d{4}\b"},
{"Credit Card", "\b(?:\d{4}[-\s]?){3}\d{1,4}\b"},
{"Email Address", "\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b"},
{"Phone Number", "\b(?:\(\d{3}\)\s?|\d{3}[-.])\d{3}[-.]?\d{4}\b"},
{"Date of Birth Pattern", "\b(?:DOB|Date of Birth|Birth Date)[:\s]+\d{1,2}[/-]\d{1,2}[/-]\d{2,4}\b"}
}
End Sub
Public Function ScanDocument(filePath As String) As ScanResult
Dim result As New ScanResult With {.FilePath = filePath}
Dim pdf As PdfDocument = PdfDocument.FromFile(filePath)
' Scan each page individually to track location
For pageIndex As Integer = 0 To pdf.PageCount - 1
Dim pageText As String = pdf.ExtractTextFromPage(pageIndex)
For Each pattern In _patterns
Dim regex As New Regex(pattern.Value, RegexOptions.IgnoreCase)
Dim matches As MatchCollection = regex.Matches(pageText)
For Each match As Match In matches
result.Matches.Add(New SensitiveDataMatch With {
.PatternType = pattern.Key,
.Value = MaskValue(match.Value, pattern.Key),
.PageNumber = pageIndex + 1
})
Next
Next
Next
Return result
End Function
' Partially mask values for safe storage
Private Function MaskValue(value As String, patternType As String) As String
If patternType = "Social Security Number" AndAlso value.Length >= 4 Then
Return "XXX-XX-" & value.Substring(value.Length - 4)
End If
If patternType = "Credit Card" AndAlso value.Length >= 4 Then
Return "****-****-****-" & value.Substring(value.Length - 4)
End If
If patternType = "Email Address" Then
Dim atIndex As Integer = value.IndexOf("@"c)
If atIndex > 2 Then
Return value.Substring(0, 2) & "***" & value.Substring(atIndex)
End If
End If
Return If(value.Length > 4, value.Substring(0, 2) & "***", "****")
End Function
Public Sub ScanAndRedact(inputPath As String, outputPath As String)
' First scan to identify sensitive data
Dim scanResult As ScanResult = ScanDocument(inputPath)
If Not scanResult.ContainsSensitiveData Then
Return
End If
' Load document for redaction
Dim pdf As PdfDocument = PdfDocument.FromFile(inputPath)
' Extract unique actual values (not masked) for redaction
Dim fullText As String = pdf.ExtractAllText()
Dim valuesToRedact As New HashSet(Of String)()
For Each pattern In _patterns
Dim regex As New Regex(pattern.Value, RegexOptions.IgnoreCase)
For Each match As Match In regex.Matches(fullText)
valuesToRedact.Add(match.Value)
Next
Next
' Apply redactions
For Each value As String In valuesToRedact
pdf.RedactTextOnAllPages(value)
Next
pdf.SaveAs(outputPath)
End Sub
End Class
' Usage
Module Program
Sub Main()
Dim scanner As New DocumentScanner()
' Scan only (for audit purposes)
Dim result As ScanResult = scanner.ScanDocument("application-form.pdf")
Dim summary = result.GetSummary()
' Scan and redact in one operation
scanner.ScanAndRedact("application-form.pdf", "application-form-redacted.pdf")
End Sub
End Module掃描器在任何修改發生之前提供對什麼機密資訊存在的可見性。 這支持合規工作流程,您需要對找到並移除的內容進行文件記錄。 屏蔽功能確保日誌文件和報告本身不成為資料暴露的來源。
如何在PDF中刪除特定區域或區域?
文字刪除有效地處理基於字元的內容,但PDF通常包含敏感資訊,文字匹配無法解決。 簽名、照片、手寫註釋、印章和圖形元素需要不同的方法。 區域型刪除讓您可以通過其座標指定矩形區域並永久遮蔽該範圍內的所有內容。
IronPDF使用RectangleF結構來定義刪除區域。 您指定左上角的X和Y座標,然後是區域的寬度和高度。 座標以頁面左下角為基點來量測,與PDF規範的座標系統一致。
輸入
一份包含手寫簽名和需要使用基於坐標的區域目標進行刪除的身分證照片的簽署協議文件。
using IronPdf;
using IronSoftware.Drawing;
// Load a document with signature blocks and photos
PdfDocument pdf = PdfDocument.FromFile("signed-agreement.pdf");
// Define a region for a signature block
// Located 100 points from left, 650 points from bottom
// Width of 200 points, height of 50 points
RectangleF signatureRegion = new RectangleF(100, 650, 200, 50);
// Redact the signature region on all pages
pdf.RedactRegionsOnAllPages(signatureRegion);
// Define a region for a photo ID in the upper right
RectangleF photoRegion = new RectangleF(450, 700, 100, 120);
pdf.RedactRegionsOnAllPages(photoRegion);
// Save the document with regions redacted
pdf.SaveAs("signed-agreement-redacted.pdf");Imports IronPdf
Imports IronSoftware.Drawing
' Load a document with signature blocks and photos
Dim pdf As PdfDocument = PdfDocument.FromFile("signed-agreement.pdf")
' Define a region for a signature block
' Located 100 points from left, 650 points from bottom
' Width of 200 points, height of 50 points
Dim signatureRegion As New RectangleF(100, 650, 200, 50)
' Redact the signature region on all pages
pdf.RedactRegionsOnAllPages(signatureRegion)
' Define a region for a photo ID in the upper right
Dim photoRegion As New RectangleF(450, 700, 100, 120)
pdf.RedactRegionsOnAllPages(photoRegion)
' Save the document with regions redacted
pdf.SaveAs("signed-agreement-redacted.pdf")此程式碼使用RectangleF結構來定義矩形區域進行刪除。 簽名區域位於座標(100, 650)處,尺寸為200x50像素,而照片區域位於(450, 700)處,尺寸為100x120像素。 RedactRegionsOnAllPages方法在所有頁面上應用黑色矩形。
範例輸出
確定正確的座標往往需要一些實驗或測量。 PDF頁面通常使用一個點等於1/72英寸的座標系統。 標準美國信紙寬612點,高792點。 A4頁大約為595乘842點。 可以使用顯示同時移動游標的座標的PDF查看工具,或者您可以程式地提取頁面尺寸:
using IronPdf;
using IronSoftware.Drawing;
PdfDocument pdf = PdfDocument.FromFile("form-document.pdf");
// Get dimensions of the first page
var pageInfo = pdf.Pages[0];
// Calculate regions relative to page dimensions
// Redact the bottom quarter of the page where signatures appear
float signatureAreaHeight = (float)(pageInfo.Height / 4);
RectangleF bottomQuarter = new RectangleF(
0, // Start at left edge
0, // Start at bottom
(float)pageInfo.Width, // Full page width
signatureAreaHeight // Quarter of page height
);
pdf.RedactRegionsOnAllPages(bottomQuarter);
// Redact a header area at the top containing letterhead with address
float headerHeight = 100;
RectangleF headerArea = new RectangleF(
0,
(float)(pageInfo.Height - headerHeight), // Position from bottom
(float)pageInfo.Width,
headerHeight
);
pdf.RedactRegionsOnAllPages(headerArea);
pdf.SaveAs("form-document-redacted.pdf");Imports IronPdf
Imports IronSoftware.Drawing
Dim pdf As PdfDocument = PdfDocument.FromFile("form-document.pdf")
' Get dimensions of the first page
Dim pageInfo = pdf.Pages(0)
' Calculate regions relative to page dimensions
' Redact the bottom quarter of the page where signatures appear
Dim signatureAreaHeight As Single = CSng(pageInfo.Height / 4)
Dim bottomQuarter As New RectangleF(0, 0, CSng(pageInfo.Width), signatureAreaHeight)
pdf.RedactRegionsOnAllPages(bottomQuarter)
' Redact a header area at the top containing letterhead with address
Dim headerHeight As Single = 100
Dim headerArea As New RectangleF(0, CSng(pageInfo.Height - headerHeight), CSng(pageInfo.Width), headerHeight)
pdf.RedactRegionsOnAllPages(headerArea)
pdf.SaveAs("form-document-redacted.pdf")如何跨不同頁面刪除多個區域?
複雜的文件通常需要在不同頁面中刪除不同的區域。 一份多頁表格可能在不同位置有簽名行,或不同頁面可能在獨特位置包含照片、印章或其他圖形元素。 IronPDF包含針對目標區域刪除的頁面特定方法。
using IronPdf;
using IronSoftware.Drawing;
PdfDocument pdf = PdfDocument.FromFile("multi-page-application.pdf");
// Define page-specific redaction regions
// Page 1: Cover page with applicant photo
RectangleF page1Photo = new RectangleF(450, 600, 120, 150);
pdf.RedactRegionOnPage(0, page1Photo);
// Page 2: Personal information section
RectangleF page2InfoBlock = new RectangleF(50, 400, 250, 200);
pdf.RedactRegionOnPage(1, page2InfoBlock);
// Pages 3-5: Signature lines at the same position
RectangleF signatureLine = new RectangleF(100, 100, 200, 40);
int[] signaturePages = { 2, 3, 4 };
pdf.RedactRegionOnPages(signaturePages, signatureLine);
// Page 6: Multiple regions - notary stamp and witness signature
RectangleF notaryStamp = new RectangleF(400, 150, 150, 150);
RectangleF witnessSignature = new RectangleF(100, 150, 200, 40);
pdf.RedactRegionOnPage(5, notaryStamp);
pdf.RedactRegionOnPage(5, witnessSignature);
pdf.SaveAs("multi-page-application-redacted.pdf");Imports IronPdf
Imports IronSoftware.Drawing
Dim pdf As PdfDocument = PdfDocument.FromFile("multi-page-application.pdf")
' Define page-specific redaction regions
' Page 1: Cover page with applicant photo
Dim page1Photo As New RectangleF(450, 600, 120, 150)
pdf.RedactRegionOnPage(0, page1Photo)
' Page 2: Personal information section
Dim page2InfoBlock As New RectangleF(50, 400, 250, 200)
pdf.RedactRegionOnPage(1, page2InfoBlock)
' Pages 3-5: Signature lines at the same position
Dim signatureLine As New RectangleF(100, 100, 200, 40)
Dim signaturePages As Integer() = {2, 3, 4}
pdf.RedactRegionOnPages(signaturePages, signatureLine)
' Page 6: Multiple regions - notary stamp and witness signature
Dim notaryStamp As New RectangleF(400, 150, 150, 150)
Dim witnessSignature As New RectangleF(100, 150, 200, 40)
pdf.RedactRegionOnPage(5, notaryStamp)
pdf.RedactRegionOnPage(5, witnessSignature)
pdf.SaveAs("multi-page-application-redacted.pdf")具有一致佈局的文件受益於可重用的區域定義:
using IronPdf;
using IronSoftware.Drawing;
public class FormRegions
{
// Standard form regions based on common templates
public static RectangleF HeaderLogo => new RectangleF(20, 720, 150, 60);
public static RectangleF SignatureBlock => new RectangleF(72, 72, 200, 50);
public static RectangleF DateField => new RectangleF(400, 72, 120, 20);
public static RectangleF PhotoId => new RectangleF(480, 650, 100, 130);
public static RectangleF AddressBlock => new RectangleF(72, 600, 250, 80);
}
class Program
{
static void Main()
{
PdfDocument pdf = PdfDocument.FromFile("standard-form.pdf");
// Apply standard redactions using predefined regions
pdf.RedactRegionsOnAllPages(FormRegions.SignatureBlock);
pdf.RedactRegionsOnAllPages(FormRegions.DateField);
pdf.RedactRegionOnPage(0, FormRegions.PhotoId);
pdf.SaveAs("standard-form-redacted.pdf");
}
}
如何移除可能洩露敏感資訊的元資料?
PDF元資料代表一個常被忽略的資訊洩漏來源。 每個PDF都帶有可以揭示敏感細節的屬性:作者的姓名和使用者名,建立文件的軟體,建立和修改時間戳,原始文件名,修訂歷史和由各種應用新增的自定義屬性。 在外部共享文件之前,剝離或清理此元資料至關重要。 如需元資料操作的全面概覽,請參閱我們的元資料使用指南。
IronPDF通過MetaData屬性曝光文件元資料,允許您讀取現有值,修改它們或完全移除它們。
using IronPdf;
using System;
// Load a document containing sensitive metadata
PdfDocument pdf = PdfDocument.FromFile("internal-report.pdf");
// Access current metadata properties
string author = pdf.MetaData.Author;
string title = pdf.MetaData.Title;
string subject = pdf.MetaData.Subject;
string keywords = pdf.MetaData.Keywords;
string creator = pdf.MetaData.Creator;
string producer = pdf.MetaData.Producer;
DateTime? creationDate = pdf.MetaData.CreationDate;
DateTime? modifiedDate = pdf.MetaData.ModifiedDate;
// Get all metadata keys including custom properties
var allKeys = pdf.MetaData.Keys();Imports IronPdf
Imports System
' Load a document containing sensitive metadata
Dim pdf As PdfDocument = PdfDocument.FromFile("internal-report.pdf")
' Access current metadata properties
Dim author As String = pdf.MetaData.Author
Dim title As String = pdf.MetaData.Title
Dim subject As String = pdf.MetaData.Subject
Dim keywords As String = pdf.MetaData.Keywords
Dim creator As String = pdf.MetaData.Creator
Dim producer As String = pdf.MetaData.Producer
Dim creationDate As DateTime? = pdf.MetaData.CreationDate
Dim modifiedDate As DateTime? = pdf.MetaData.ModifiedDate
' Get all metadata keys including custom properties
Dim allKeys = pdf.MetaData.Keys()在分發之前移除敏感的元資料:
輸入
一份包含嵌入元資料的內部備忘錄,如作者姓名、建立時間戳和可能揭露敏感組織資訊的自定義屬性。
using IronPdf;
using System;
PdfDocument pdf = PdfDocument.FromFile("confidential-memo.pdf");
// Replace identifying metadata with generic values
pdf.MetaData.Author = "Organization Name";
pdf.MetaData.Creator = "Document System";
pdf.MetaData.Producer = "";
pdf.MetaData.Title = "Public Document";
pdf.MetaData.Subject = "";
pdf.MetaData.Keywords = "";
// Normalize dates to remove timing information
pdf.MetaData.CreationDate = DateTime.Now;
pdf.MetaData.ModifiedDate = DateTime.Now;
// Remove specific custom metadata keys
pdf.MetaData.RemoveMetaDataKey("OriginalFilename");
pdf.MetaData.RemoveMetaDataKey("LastSavedBy");
pdf.MetaData.RemoveMetaDataKey("Company");
pdf.MetaData.RemoveMetaDataKey("Manager");
// Remove custom properties added by applications
try
{
pdf.MetaData.CustomProperties.Remove("SourcePath");
}
catch { }
pdf.SaveAs("confidential-memo-cleaned.pdf");Imports IronPdf
Imports System
Dim pdf As PdfDocument = PdfDocument.FromFile("confidential-memo.pdf")
' Replace identifying metadata with generic values
pdf.MetaData.Author = "Organization Name"
pdf.MetaData.Creator = "Document System"
pdf.MetaData.Producer = ""
pdf.MetaData.Title = "Public Document"
pdf.MetaData.Subject = ""
pdf.MetaData.Keywords = ""
' Normalize dates to remove timing information
pdf.MetaData.CreationDate = DateTime.Now
pdf.MetaData.ModifiedDate = DateTime.Now
' Remove specific custom metadata keys
pdf.MetaData.RemoveMetaDataKey("OriginalFilename")
pdf.MetaData.RemoveMetaDataKey("LastSavedBy")
pdf.MetaData.RemoveMetaDataKey("Company")
pdf.MetaData.RemoveMetaDataKey("Manager")
' Remove custom properties added by applications
Try
pdf.MetaData.CustomProperties.Remove("SourcePath")
Catch
End Try
pdf.SaveAs("confidential-memo-cleaned.pdf")此程式碼用通用值替換識別性元資料字段,將時間戳統一到當前日期,並移除應用程式可能新增的自定義元資料鍵。 RemoveMetaDataKey方法目標特定屬性,如"OriginalFilename"和"LastSavedBy",可能洩露內部資訊。
範例輸出
跨批量操作的徹底元資料清理需要系統化的方法:
using IronPdf;
using System;
using System.Collections.Generic;
public class MetadataCleaner
{
private readonly string _defaultAuthor;
private readonly string _defaultCreator;
public MetadataCleaner(string organizationName)
{
_defaultAuthor = organizationName;
_defaultCreator = $"{organizationName} Document System";
}
public void CleanMetadata(PdfDocument pdf)
{
// Replace standard metadata fields
pdf.MetaData.Author = _defaultAuthor;
pdf.MetaData.Creator = _defaultCreator;
pdf.MetaData.Producer = "";
pdf.MetaData.Subject = "";
pdf.MetaData.Keywords = "";
// Normalize timestamps
DateTime now = DateTime.Now;
pdf.MetaData.CreationDate = now;
pdf.MetaData.ModifiedDate = now;
// Get all keys and remove potentially sensitive ones
List<string> keysToRemove = new List<string>();
foreach (string key in pdf.MetaData.Keys())
{
// Keep only essential keys
if (!IsEssentialKey(key))
{
keysToRemove.Add(key);
}
}
foreach (string key in keysToRemove)
{
pdf.MetaData.RemoveMetaDataKey(key);
}
}
private bool IsEssentialKey(string key)
{
// Keep only the basic display properties
string[] essentialKeys = { "Title", "Author", "CreationDate", "ModifiedDate" };
foreach (string essential in essentialKeys)
{
if (key.Equals(essential, StringComparison.OrdinalIgnoreCase))
{
return true;
}
}
return false;
}
}
// Usage
class Program
{
static void Main()
{
MetadataCleaner cleaner = new MetadataCleaner("Acme Corporation");
PdfDocument pdf = PdfDocument.FromFile("report.pdf");
cleaner.CleanMetadata(pdf);
pdf.SaveAs("report-clean.pdf");
}
}
如何清理PDF以移除嵌入的腳本和隱藏的威脅?
PDF清理解決的安全問題超越了可見的內容和元資料。 PDF文件可以包含JavaScript程式碼、嵌入的可執行文件、觸發外部連接的表單動作和其他潛在的惡意元素。 這些功能確實有合法用途,比如交互式表單和多媒體內容,但它們也創造了攻擊載體。 清理PDF會移除這些有活動部件的元素,保留視覺內容。 欲瞭解更多有關清理方法的詳細資訊,請參閱我們的清理PDF使用指南。
IronPDF的Cleaner類通過一個優雅的方法進行清理:將PDF轉換為圖像格式,然後再轉換回來。 此過程會剝離JavaScript、嵌入物件、表單動作和註釋,同時保留視覺外觀。 程式庫提供兩種具有不同特性的清理方法。
輸入
從外部來源接收的PDF文件,可能包含JavaScript、嵌入物件或其他潛在的惡意活動內容。
using IronPdf;
// Load a PDF that may contain active content
PdfDocument pdf = PdfDocument.FromFile("received-document.pdf");
// Sanitize using SVG conversion
// Faster processing, results in searchable text, slight layout variations possible
PdfDocument sanitizedSvg = Cleaner.SanitizeWithSvg(pdf);
sanitizedSvg.SaveAs("sanitized-svg.pdf");
// Sanitize using Bitmap conversion
// Slower processing, text becomes image (not searchable), exact visual reproduction
PdfDocument sanitizedBitmap = Cleaner.SanitizeWithBitmap(pdf);
sanitizedBitmap.SaveAs("sanitized-bitmap.pdf");Imports IronPdf
' Load a PDF that may contain active content
Dim pdf As PdfDocument = PdfDocument.FromFile("received-document.pdf")
' Sanitize using SVG conversion
' Faster processing, results in searchable text, slight layout variations possible
Dim sanitizedSvg As PdfDocument = Cleaner.SanitizeWithSvg(pdf)
sanitizedSvg.SaveAs("sanitized-svg.pdf")
' Sanitize using Bitmap conversion
' Slower processing, text becomes image (not searchable), exact visual reproduction
Dim sanitizedBitmap As PdfDocument = Cleaner.SanitizeWithBitmap(pdf)
sanitizedBitmap.SaveAs("sanitized-bitmap.pdf")此程式碼演示IronPDF的Cleaner類提供的兩種清理方法。 SanitizeWithSvg通過SVG中間格式轉換PDF,保持文字搜尋功能,同時移除活動內容。 SanitizeWithBitmap將頁面先轉換為圖像,產生精確的視覺副本,但文字作為不可搜尋的圖形呈現。
範例輸出
SVG方法速度較快,保留文字為可搜尋內容,適用於需要保持索引或可存取性的文件。 位圖方法產生精確的視覺副本,但將文字轉換為圖像,這會阻止文字選擇和搜尋。 根據輸出文件的需求進行選擇。
您還可以在清理過程中應用渲染選項來調整輸出:
using IronPdf;
// Load the potentially unsafe document
PdfDocument pdf = PdfDocument.FromFile("untrusted-source.pdf");
// Configure rendering options for sanitization
var renderOptions = new ChromePdfRenderOptions
{
MarginTop = 10,
MarginBottom = 10,
MarginLeft = 10,
MarginRight = 10
};
// Sanitize with custom options
PdfDocument sanitized = Cleaner.SanitizeWithSvg(pdf, renderOptions);
sanitized.SaveAs("untrusted-source-safe.pdf");Imports IronPdf
' Load the potentially unsafe document
Dim pdf As PdfDocument = PdfDocument.FromFile("untrusted-source.pdf")
' Configure rendering options for sanitization
Dim renderOptions As New ChromePdfRenderOptions With {
.MarginTop = 10,
.MarginBottom = 10,
.MarginLeft = 10,
.MarginRight = 10
}
' Sanitize with custom options
Dim sanitized As PdfDocument = Cleaner.SanitizeWithSvg(pdf, renderOptions)
sanitized.SaveAs("untrusted-source-safe.pdf")高安全性環境通常需要將清理與其他保護措施結合使用:
using IronPdf;
using System;
public class SecureDocumentProcessor
{
public PdfDocument ProcessUntrustedDocument(string inputPath)
{
// Load the document
PdfDocument original = PdfDocument.FromFile(inputPath);
// Step 1: Sanitize to remove active content
PdfDocument sanitized = Cleaner.SanitizeWithSvg(original);
// Step 2: Clean metadata
sanitized.MetaData.Author = "Processed Document";
sanitized.MetaData.Creator = "Secure Processor";
sanitized.MetaData.Producer = "";
sanitized.MetaData.CreationDate = DateTime.Now;
sanitized.MetaData.ModifiedDate = DateTime.Now;
// Remove all custom metadata
foreach (string key in sanitized.MetaData.Keys())
{
if (key != "Title" && key != "Author" && key != "CreationDate" && key != "ModifiedDate")
{
sanitized.MetaData.RemoveMetaDataKey(key);
}
}
return sanitized;
}
}
// Usage
class Program
{
static void Main()
{
SecureDocumentProcessor processor = new SecureDocumentProcessor();
PdfDocument safe = processor.ProcessUntrustedDocument("email-attachment.pdf");
safe.SaveAs("email-attachment-safe.pdf");
}
}Imports IronPdf
Imports System
Public Class SecureDocumentProcessor
Public Function ProcessUntrustedDocument(inputPath As String) As PdfDocument
' Load the document
Dim original As PdfDocument = PdfDocument.FromFile(inputPath)
' Step 1: Sanitize to remove active content
Dim sanitized As PdfDocument = Cleaner.SanitizeWithSvg(original)
' Step 2: Clean metadata
sanitized.MetaData.Author = "Processed Document"
sanitized.MetaData.Creator = "Secure Processor"
sanitized.MetaData.Producer = ""
sanitized.MetaData.CreationDate = DateTime.Now
sanitized.MetaData.ModifiedDate = DateTime.Now
' Remove all custom metadata
For Each key As String In sanitized.MetaData.Keys()
If key <> "Title" AndAlso key <> "Author" AndAlso key <> "CreationDate" AndAlso key <> "ModifiedDate" Then
sanitized.MetaData.RemoveMetaDataKey(key)
End If
Next
Return sanitized
End Function
End Class
' Usage
Module Program
Sub Main()
Dim processor As New SecureDocumentProcessor()
Dim safe As PdfDocument = processor.ProcessUntrustedDocument("email-attachment.pdf")
safe.SaveAs("email-attachment-safe.pdf")
End Sub
End Module如何掃描PDF中的安全漏洞?
在處理或清理文件之前,您可能想要評估它們所包含的潛在威脅。 IronPDF的Cleaner.ScanPdf方法使用YARA規則檢查文件,YARA規則是通常用於惡意軟體分析和威脅檢測的模式定義。 掃描識別與惡意PDF文件相關的特徵。
using IronPdf;
// Load the document to scan
PdfDocument pdf = PdfDocument.FromFile("suspicious-document.pdf");
// Scan using default YARA rules
CleanerScanResult scanResult = Cleaner.ScanPdf(pdf);
// Check the scan results
bool threatsDetected = scanResult.IsDetected;
int riskCount = scanResult.Risks.Count;
// Process identified risks
if (scanResult.IsDetected)
{
foreach (var risk in scanResult.Risks)
{
// Handle each identified risk
}
// Sanitize the document before use
PdfDocument sanitized = Cleaner.SanitizeWithSvg(pdf);
sanitized.SaveAs("suspicious-document-safe.pdf");
}Imports IronPdf
' Load the document to scan
Dim pdf As PdfDocument = PdfDocument.FromFile("suspicious-document.pdf")
' Scan using default YARA rules
Dim scanResult As CleanerScanResult = Cleaner.ScanPdf(pdf)
' Check the scan results
Dim threatsDetected As Boolean = scanResult.IsDetected
Dim riskCount As Integer = scanResult.Risks.Count
' Process identified risks
If scanResult.IsDetected Then
For Each risk In scanResult.Risks
' Handle each identified risk
Next
' Sanitize the document before use
Dim sanitized As PdfDocument = Cleaner.SanitizeWithSvg(pdf)
sanitized.SaveAs("suspicious-document-safe.pdf")
End If您可以提供自定義的YARA規則文件以滿足專門的檢測需求。 具有特定威脅模型或合規需求的組織通常維護自己的規則集,以應對特定漏洞模式的目標。
using IronPdf;
PdfDocument pdf = PdfDocument.FromFile("incoming-document.pdf");
// Scan with custom YARA rules
string[] customYaraFiles = { "corporate-rules.yar", "industry-specific.yar" };
CleanerScanResult result = Cleaner.ScanPdf(pdf, customYaraFiles);
if (result.IsDetected)
{
// Document triggered custom rules and requires review or sanitization
PdfDocument sanitized = Cleaner.SanitizeWithSvg(pdf);
sanitized.SaveAs("incoming-document-safe.pdf");
}Imports IronPdf
Dim pdf As PdfDocument = PdfDocument.FromFile("incoming-document.pdf")
' Scan with custom YARA rules
Dim customYaraFiles As String() = {"corporate-rules.yar", "industry-specific.yar"}
Dim result As CleanerScanResult = Cleaner.ScanPdf(pdf, customYaraFiles)
If result.IsDetected Then
' Document triggered custom rules and requires review or sanitization
Dim sanitized As PdfDocument = Cleaner.SanitizeWithSvg(pdf)
sanitized.SaveAs("incoming-document-safe.pdf")
End If將掃描整合到文件接收工作流程中有助於自動化安全決策:
using IronPdf;
using System;
using System.IO;
public enum DocumentSafetyLevel
{
Safe,
Suspicious,
Dangerous
}
public class DocumentSecurityGateway
{
public DocumentSafetyLevel EvaluateDocument(string filePath)
{
PdfDocument pdf = PdfDocument.FromFile(filePath);
CleanerScanResult scan = Cleaner.ScanPdf(pdf);
if (!scan.IsDetected)
{
return DocumentSafetyLevel.Safe;
}
// Evaluate severity based on number of risks
if (scan.Risks.Count > 5)
{
return DocumentSafetyLevel.Dangerous;
}
return DocumentSafetyLevel.Suspicious;
}
public PdfDocument ProcessIncomingDocument(string filePath, string outputDirectory)
{
DocumentSafetyLevel safety = EvaluateDocument(filePath);
string fileName = Path.GetFileName(filePath);
switch (safety)
{
case DocumentSafetyLevel.Safe:
return PdfDocument.FromFile(filePath);
case DocumentSafetyLevel.Suspicious:
PdfDocument suspicious = PdfDocument.FromFile(filePath);
return Cleaner.SanitizeWithSvg(suspicious);
case DocumentSafetyLevel.Dangerous:
throw new SecurityException($"Document {fileName} contains dangerous content");
default:
throw new InvalidOperationException("Unknown safety level");
}
}
}Imports IronPdf
Imports System
Imports System.IO
Public Enum DocumentSafetyLevel
Safe
Suspicious
Dangerous
End Enum
Public Class DocumentSecurityGateway
Public Function EvaluateDocument(filePath As String) As DocumentSafetyLevel
Dim pdf As PdfDocument = PdfDocument.FromFile(filePath)
Dim scan As CleanerScanResult = Cleaner.ScanPdf(pdf)
If Not scan.IsDetected Then
Return DocumentSafetyLevel.Safe
End If
' Evaluate severity based on number of risks
If scan.Risks.Count > 5 Then
Return DocumentSafetyLevel.Dangerous
End If
Return DocumentSafetyLevel.Suspicious
End Function
Public Function ProcessIncomingDocument(filePath As String, outputDirectory As String) As PdfDocument
Dim safety As DocumentSafetyLevel = EvaluateDocument(filePath)
Dim fileName As String = Path.GetFileName(filePath)
Select Case safety
Case DocumentSafetyLevel.Safe
Return PdfDocument.FromFile(filePath)
Case DocumentSafetyLevel.Suspicious
Dim suspicious As PdfDocument = PdfDocument.FromFile(filePath)
Return Cleaner.SanitizeWithSvg(suspicious)
Case DocumentSafetyLevel.Dangerous
Throw New SecurityException($"Document {fileName} contains dangerous content")
Case Else
Throw New InvalidOperationException("Unknown safety level")
End Select
End Function
End Class如何建立一個完整的刪除和清理流水線?
生產文件處理通常需要將多種保護技術組成一個連貫的工作流。 一個完整的流水線可能會掃描進來的文件以發現威脅,清理通過初步篩選的文件,應用文字和區域刪除,剝離元資料,並產生記錄所有執行操作的稽核日誌。 這個例子展示了這種整合的方法。
using IronPdf;
using IronSoftware.Drawing;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
public class DocumentProcessingResult
{
public string OriginalFile { get; set; }
public string OutputFile { get; set; }
public bool WasSanitized { get; set; }
public int TextRedactionsApplied { get; set; }
public int RegionRedactionsApplied { get; set; }
public bool MetadataCleaned { get; set; }
public List<string> SensitiveDataTypesFound { get; set; } = new List<string>();
public DateTime ProcessedAt { get; set; }
public bool Success { get; set; }
public string ErrorMessage { get; set; }
}
public class ComprehensiveDocumentProcessor
{
// Sensitive data patterns
private readonly Dictionary<string, string> _sensitivePatterns = new Dictionary<string, string>
{
{ "SSN", @"\b\d{3}-\d{2}-\d{4}\b" },
{ "Credit Card", @"\b(?:\d{4}[-\s]?){3}\d{1,4}\b" },
{ "Email", @"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b" },
{ "Phone", @"\b(?:\(\d{3}\)\s?|\d{3}[-.])\d{3}[-.]?\d{4}\b" }
};
// Standard regions to redact (signature areas, photo locations)
private readonly List<RectangleF> _standardRedactionRegions = new List<RectangleF>
{
new RectangleF(72, 72, 200, 50), // Bottom left signature
new RectangleF(350, 72, 200, 50) // Bottom right signature
};
private readonly string _organizationName;
public ComprehensiveDocumentProcessor(string organizationName)
{
_organizationName = organizationName;
}
public DocumentProcessingResult ProcessDocument(
string inputPath,
string outputPath,
bool sanitize = true,
bool redactPatterns = true,
bool redactRegions = true,
bool cleanMetadata = true,
List<string> additionalTermsToRedact = null)
{
var result = new DocumentProcessingResult
{
OriginalFile = inputPath,
OutputFile = outputPath,
ProcessedAt = DateTime.Now
};
try
{
// Load the document
PdfDocument pdf = PdfDocument.FromFile(inputPath);
// Step 1: Security scan
CleanerScanResult scanResult = Cleaner.ScanPdf(pdf);
if (scanResult.IsDetected && scanResult.Risks.Count > 10)
{
throw new SecurityException("Document contains too many security risks to process");
}
// Step 2: Sanitization (if needed or requested)
if (sanitize || scanResult.IsDetected)
{
pdf = Cleaner.SanitizeWithSvg(pdf);
result.WasSanitized = true;
}
// Step 3: Pattern-based text redaction
if (redactPatterns)
{
string fullText = pdf.ExtractAllText();
HashSet<string> valuesToRedact = new HashSet<string>();
foreach (var pattern in _sensitivePatterns)
{
Regex regex = new Regex(pattern.Value, RegexOptions.IgnoreCase);
MatchCollection matches = regex.Matches(fullText);
if (matches.Count > 0)
{
result.SensitiveDataTypesFound.Add($"{pattern.Key} ({matches.Count})");
foreach (Match match in matches)
{
valuesToRedact.Add(match.Value);
}
}
}
// Apply redactions
foreach (string value in valuesToRedact)
{
pdf.RedactTextOnAllPages(value);
result.TextRedactionsApplied++;
}
}
// Step 4: Additional specific terms
if (additionalTermsToRedact != null)
{
foreach (string term in additionalTermsToRedact)
{
pdf.RedactTextOnAllPages(term);
result.TextRedactionsApplied++;
}
}
// Step 5: Region-based redaction
if (redactRegions)
{
foreach (RectangleF region in _standardRedactionRegions)
{
pdf.RedactRegionsOnAllPages(region);
result.RegionRedactionsApplied++;
}
}
// Step 6: Metadata cleaning
if (cleanMetadata)
{
pdf.MetaData.Author = _organizationName;
pdf.MetaData.Creator = $"{_organizationName} Document Processor";
pdf.MetaData.Producer = "";
pdf.MetaData.Subject = "";
pdf.MetaData.Keywords = "";
pdf.MetaData.CreationDate = DateTime.Now;
pdf.MetaData.ModifiedDate = DateTime.Now;
result.MetadataCleaned = true;
}
// Step 7: Save the processed document
pdf.SaveAs(outputPath);
result.Success = true;
}
catch (Exception ex)
{
result.Success = false;
result.ErrorMessage = ex.Message;
}
return result;
}
}
// Usage example
class Program
{
static void Main()
{
var processor = new ComprehensiveDocumentProcessor("Acme Corporation");
// Process a single document with all protections
var result = processor.ProcessDocument(
inputPath: "customer-application.pdf",
outputPath: "customer-application-redacted.pdf",
sanitize: true,
redactPatterns: true,
redactRegions: true,
cleanMetadata: true,
additionalTermsToRedact: new List<string> { "Project Alpha", "Internal Use Only" }
);
// Batch process multiple documents
string[] inputFiles = Directory.GetFiles("incoming", "*.pdf");
foreach (string file in inputFiles)
{
string outputFile = Path.Combine("processed", Path.GetFileName(file));
processor.ProcessDocument(file, outputFile);
}
}
}Imports IronPdf
Imports IronSoftware.Drawing
Imports System
Imports System.Collections.Generic
Imports System.IO
Imports System.Text.RegularExpressions
Public Class DocumentProcessingResult
Public Property OriginalFile As String
Public Property OutputFile As String
Public Property WasSanitized As Boolean
Public Property TextRedactionsApplied As Integer
Public Property RegionRedactionsApplied As Integer
Public Property MetadataCleaned As Boolean
Public Property SensitiveDataTypesFound As List(Of String) = New List(Of String)()
Public Property ProcessedAt As DateTime
Public Property Success As Boolean
Public Property ErrorMessage As String
End Class
Public Class ComprehensiveDocumentProcessor
' Sensitive data patterns
Private ReadOnly _sensitivePatterns As Dictionary(Of String, String) = New Dictionary(Of String, String) From {
{"SSN", "\b\d{3}-\d{2}-\d{4}\b"},
{"Credit Card", "\b(?:\d{4}[-\s]?){3}\d{1,4}\b"},
{"Email", "\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b"},
{"Phone", "\b(?:\(\d{3}\)\s?|\d{3}[-.])\d{3}[-.]?\d{4}\b"}
}
' Standard regions to redact (signature areas, photo locations)
Private ReadOnly _standardRedactionRegions As List(Of RectangleF) = New List(Of RectangleF) From {
New RectangleF(72, 72, 200, 50), ' Bottom left signature
New RectangleF(350, 72, 200, 50) ' Bottom right signature
}
Private ReadOnly _organizationName As String
Public Sub New(organizationName As String)
_organizationName = organizationName
End Sub
Public Function ProcessDocument(
inputPath As String,
outputPath As String,
Optional sanitize As Boolean = True,
Optional redactPatterns As Boolean = True,
Optional redactRegions As Boolean = True,
Optional cleanMetadata As Boolean = True,
Optional additionalTermsToRedact As List(Of String) = Nothing) As DocumentProcessingResult
Dim result As New DocumentProcessingResult With {
.OriginalFile = inputPath,
.OutputFile = outputPath,
.ProcessedAt = DateTime.Now
}
Try
' Load the document
Dim pdf As PdfDocument = PdfDocument.FromFile(inputPath)
' Step 1: Security scan
Dim scanResult As CleanerScanResult = Cleaner.ScanPdf(pdf)
If scanResult.IsDetected AndAlso scanResult.Risks.Count > 10 Then
Throw New SecurityException("Document contains too many security risks to process")
End If
' Step 2: Sanitization (if needed or requested)
If sanitize OrElse scanResult.IsDetected Then
pdf = Cleaner.SanitizeWithSvg(pdf)
result.WasSanitized = True
End If
' Step 3: Pattern-based text redaction
If redactPatterns Then
Dim fullText As String = pdf.ExtractAllText()
Dim valuesToRedact As New HashSet(Of String)()
For Each pattern In _sensitivePatterns
Dim regex As New Regex(pattern.Value, RegexOptions.IgnoreCase)
Dim matches As MatchCollection = regex.Matches(fullText)
If matches.Count > 0 Then
result.SensitiveDataTypesFound.Add($"{pattern.Key} ({matches.Count})")
For Each match As Match In matches
valuesToRedact.Add(match.Value)
Next
End If
Next
' Apply redactions
For Each value As String In valuesToRedact
pdf.RedactTextOnAllPages(value)
result.TextRedactionsApplied += 1
Next
End If
' Step 4: Additional specific terms
If additionalTermsToRedact IsNot Nothing Then
For Each term As String In additionalTermsToRedact
pdf.RedactTextOnAllPages(term)
result.TextRedactionsApplied += 1
Next
End If
' Step 5: Region-based redaction
If redactRegions Then
For Each region As RectangleF In _standardRedactionRegions
pdf.RedactRegionsOnAllPages(region)
result.RegionRedactionsApplied += 1
Next
End If
' Step 6: Metadata cleaning
If cleanMetadata Then
pdf.MetaData.Author = _organizationName
pdf.MetaData.Creator = $"{_organizationName} Document Processor"
pdf.MetaData.Producer = ""
pdf.MetaData.Subject = ""
pdf.MetaData.Keywords = ""
pdf.MetaData.CreationDate = DateTime.Now
pdf.MetaData.ModifiedDate = DateTime.Now
result.MetadataCleaned = True
End If
' Step 7: Save the processed document
pdf.SaveAs(outputPath)
result.Success = True
Catch ex As Exception
result.Success = False
result.ErrorMessage = ex.Message
End Try
Return result
End Function
End Class
' Usage example
Class Program
Shared Sub Main()
Dim processor As New ComprehensiveDocumentProcessor("Acme Corporation")
' Process a single document with all protections
Dim result = processor.ProcessDocument(
inputPath:="customer-application.pdf",
outputPath:="customer-application-redacted.pdf",
sanitize:=True,
redactPatterns:=True,
redactRegions:=True,
cleanMetadata:=True,
additionalTermsToRedact:=New List(Of String) From {"Project Alpha", "Internal Use Only"}
)
' Batch process multiple documents
Dim inputFiles As String() = Directory.GetFiles("incoming", "*.pdf")
For Each file As String In inputFiles
Dim outputFile As String = Path.Combine("processed", Path.GetFileName(file))
processor.ProcessDocument(file, outputFile)
Next
End Sub
End Class輸入
一份包含多種型別敏感資料的客戶申請表,包括SSN、信用卡號碼、電子郵件地址和簽名塊,要求全面保護。
範例輸出
這個綜合處理器整合了本指南中介紹的所有技術到一個單一的、可配置的類中。 它檢查威脅,必要時清理,尋找並刪除敏感模式,應用區域刪除,清潔元資料,並產生詳細的報告。 您可以調整靈敏度模式、刪除區域和處理選項以匹配您的具體要求。
下一步
在PDF文件中保護敏感資訊需要的不只是表面的措施。 真正的刪除從文件結構中永久移除內容。 模式匹配自動尋找和移除像社會安全號碼、信用卡詳細資訊和電子郵件地址等資料。 區域型刪除處理簽名、照片,以及文字匹配無法處理的其他圖形元素。 元資料清潔消除可能透露作者、時間戳或內部文件路徑的隱藏資訊。 清理去除嵌入的腳本和可能造成安全風險的活動內容。
IronPDF通過一個一致的,精良設計的API提供所有這些功能,與C#和.NET開發慣例自然結合。 本指南展示的方法可以處理單一文件,也可擴展至批量處理數以千計的文件。 不論您是為醫療資料建立合規工作流程,準備法律文件進行取證,或僅僅是確保內部報告能安全地外部分享,這些技術構成負責文件處理的基礎。 為了全面的安全保障,將刪除與密碼保護和權限以及數位簽名結合起來。
準備好開始構建了嗎? 下載 IronPDF並試用免費試用版。 程式庫包含免費的開發授權,您可以在投入生產授權之前,全面評估刪除、文字提取以及清理的能力。 如果您對實施或合規工作流程有任何疑問,請聯繫我們的工程支援團隊。
Frequently Asked Questions
什麼是PDF遮蔽?
PDF遮蔽是永久移除PDF文件中敏感資訊的過程。這包括需要隱藏以保護隱私或合規性原因的文字、圖片及元資料。
如何使用C#在PDF中遮蔽資訊?
您可以使用IronPDF在PDF中使用C#遮蔽資訊。這允許您永久移除或隱藏PDF文件中的文字、圖片及元資料,確保其符合隱私及合規性標準。
為什麼PDF遮蔽對合規性很重要?
PDF遮蔽對於如HIPAA、GDPR和PCI DSS等標準的合規性至關重要,因為它有助於保護敏感資料並防止未經授權的機密資訊存取。
IronPDF可以遮蔽PDF的整個區域嗎?
是的,IronPDF可以遮蔽PDF的整個區域。這允許您在文件中定義特定需要隱藏或移除的區域以安全目的。
IronPDF能遮蔽哪些型別的資料?
IronPDF可以遮蔽多種型別的資料,包括文字、圖片及PDF文件中的元資料,確保全面的資料隱私和安全。
IronPDF是否支持文件淨化?
是的,IronPDF支持文件淨化,這包括清理PDF以移除隱藏資料或元資料,可能不可見但仍可能構成隱私風險。
是否可以使用IronPDF自動進行PDF遮蔽?
是的,IronPDF允許自動化C#中的PDF遮蔽過程,使處理需要移除敏感資料的大量文件更易於管理。
IronPDF如何確保遮蔽的永久性?
IronPDF確保遮蔽的永久性是通過永久從文件中移除所選文字和圖片,而不是僅僅遮蓋它們,這意味著它們不能被恢復或查看。
IronPDF可以在PDF中遮蔽元資料嗎?
是的,IronPDF可以在PDF文件中遮蔽元資料,確保所有形式的敏感資料,包括隱藏或背景資料,都被徹底移除。
使用IronPDF進行PDF遮蔽有哪些好處?
使用IronPDF進行PDF遮蔽的好處包括確保資料保護規範的合規性,增強文件安全性,並提供高效的自動化流程來管理敏感資訊。

Curtis Chau holds a Bachelor’s degree in Computer Science (Carleton University) and specializes in front-end development with expertise in Node.js, TypeScript, JavaScript, and React. Passionate about crafting intuitive and aesthetically pleasing user interfaces, Curtis enjoys working with modern frameworks and creating well-structured, visually appealing manuals.