PDF Redaction in C#; : Supprimer les données sensibles et assainir les documents avec IronPDF

This article was translated from English: Does it need improvement?
Translated
View the article in English

PDF redaction in C# .NET with IronPDF supprime de façon permanente le contenu sensible de la structure interne d'un document, sans se contenter de le recouvrir visuellement, de sorte qu'aucun effort de copie, de recherche ou d'analyse médico-légale ne puisse permettre de récupérer les données d'origine. Cela va bien au-delà des rectangles noirs sur le texte : IronPDF propose une rédaction de texte avec correspondance de motifs regex, une rédaction basée sur les régions pour les signatures et les images, un dépouillement des métadonnées, une assainissement du document pour éliminer les scripts intégrés et une analyse des vulnérabilités, offrant ainsi aux développeurs .NET une boîte à outils complète pour les flux de travail de protection des documents conformes aux normes HIPAA, GDPR et PCI DSS.

TL;DR : Quickstart Guide

Ce tutoriel traite de la suppression permanente du contenu sensible des documents PDF en C# .NET, notamment les motifs de texte, les régions d'image, les métadonnées et les scripts intégrés.

  • À qui s'adresse ce document: Les développeurs .NET qui traitent des documents sensibles dans les domaines de la santé, du droit, de la finance ou de l'administration.
  • Ce que vous construirez: Rédaction de texte avec correspondance de motifs (SSN, cartes de crédit, courriels), rédaction de régions basée sur les coordonnées pour les signatures et les photos, nettoyage des métadonnées, assainissement des PDF pour supprimer les scripts intégrés et analyse des vulnérabilités basée sur YARA.
  • Où ça marche: .NET 10, .NET 8 LTS, .NET Framework 4.6.2+, et .NET Standard 2.0. Toutes les opérations s'exécutent localement, sans dépendance externe.
  • Quand utiliser cette approche: Lorsque vous devez partager des documents à des fins de divulgation légale, de demandes d'accès à l'information ou de distribution externe, tout en vous assurant que le contenu supprimé a réellement disparu.
  • Pourquoi c'est important techniquement: Les superpositions visuelles laissent le texte original récupérable dans les flux de contenu du PDF. La rédaction d'IronPDF supprime les données de caractères de la structure même du document, ce qui rend toute récupération impossible.

Expurgez le texte sensible d'un PDF en quelques lignes de code :

Nuget IconCommencez dès maintenant à créer des PDF avec NuGet :

  1. Installez IronPDF avec le gestionnaire de packages NuGet

    PM > Install-Package IronPdf

  2. Copiez et exécutez cet extrait de code.

    using IronPdf;
    
    PdfDocument pdf = PdfDocument.FromFile("confidential-report.pdf");
    pdf.RedactTextOnAllPages("CONFIDENTIAL");
    pdf.SaveAs("redacted-report.pdf");
  3. Déployez pour tester sur votre environnement de production.

    Commencez à utiliser IronPDF dans votre projet dès aujourd'hui grâce à un essai gratuit.
    arrow pointer

Après avoir acheté ou vous être inscrit à une version d'essai de 30 jours d'IronPDF, ajoutez votre clé de licence au début de votre application.

IronPdf.License.LicenseKey = "KEY";
IronPdf.License.LicenseKey = "KEY";
Imports IronPdf

IronPdf.License.LicenseKey = "KEY"
$vbLabelText   $csharpLabel

Commencez à utiliser IronPDF dans votre projet aujourd'hui avec un essai gratuit.

Première étape :
green arrow pointer
NuGet Installer avec NuGet

PM >  Install-Package IronPdf

Consultez IronPDF sur NuGet pour une installation rapide. Avec plus de 10 millions de téléchargements, il transforme le développement PDF avec C#. Vous pouvez également télécharger le DLL ou l'installateur Windows.

Table des matières

Quelle est la différence entre True Redaction et Visual Overlay?

Comprendre la distinction entre une véritable rédaction et une superposition visuelle est essentiel pour toute personne manipulant des documents sensibles. De nombreux outils et méthodes manuelles donnent l'impression d'être expurgés sans pour autant supprimer les données sous-jacentes. Ce faux sentiment de sécurité est à l'origine de nombreuses violations de données très médiatisées et de manquements à la conformité.

Les approches de superposition visuelle dessinent généralement des formes opaques sur le contenu sensible. Le texte doit rester intact dans la structure du PDF. La personne qui consulte le document voit un rectangle noir, mais les caractères originaux existent toujours dans les flux de contenu du fichier. La sélection de tout le texte de la page, l'utilisation d'outils d'accessibilité ou l'examen des données brutes du PDF révèleront tout ce qui était censé être caché. Des affaires judiciaires ont été compromises lorsque des documents expurgés n'ont pas été expurgés par l'avocat de la partie adverse. Des agences gouvernementales ont accidentellement publié des informations classifiées qui semblaient censurées mais qui étaient tout à fait récupérables.

La rédaction proprement dite fonctionne différemment. Lorsque vous utilisez les méthodes de rédaction d'IronPDF, la bibliothèque localise le texte spécifié dans la structure interne du PDF et le supprime entièrement. Les données de caractère sont supprimées des flux de contenu. La représentation visuelle est remplacée par une marque de rédaction, généralement un rectangle noir, mais le contenu original n'existe plus nulle part dans le fichier. Aucune sélection, copie ou analyse médico-légale ne peut récupérer ce qui a été définitivement effacé.

IronPDF met en œuvre une véritable rédaction en modifiant le PDF à un niveau structurel. La méthode RedactTextOnAllPages et ses variantes recherchent dans le contenu de la page, identifient le texte correspondant, le suppriment du modèle d'objet du document et, éventuellement, dessinent un indicateur visuel à l'endroit où le contenu apparaissait auparavant. Cette approche s'aligne sur les directives d'organisations telles que le NIST en matière de rédaction de documents sécurisés.

Les implications pratiques sont importantes. Si vous avez besoin de partager des documents avec l'extérieur, de soumettre des fichiers dans le cadre d'une enquête judiciaire, de publier des documents dans le cadre de demandes de liberté d'information ou de distribuer des rapports tout en protégeant des informations personnellement identifiables, seule une véritable expurgation offre une protection adéquate. Les superpositions visuelles peuvent suffire pour les projets internes où vous souhaitez simplement attirer l'attention sur certaines sections, mais elles ne doivent jamais être utilisées pour la protection des données. Pour d'autres mesures de sécurité des documents, consultez nos guides sur le chiffrement des PDF et les signatures numériques.


Comment rédiger du texte PDF en C# ; sur l'ensemble d'un document?

Le scénario de rédaction le plus courant consiste à supprimer toutes les occurrences d'un texte spécifique dans un document. Vous devez peut-être éliminer le nom d'une personne d'un rapport, supprimer les numéros de compte des états financiers ou supprimer les codes de référence internes avant la distribution externe. IronPDF facilite cette tâche grâce à la méthode RedactTextOnAllPages.

Entrée

Un document relatif aux dossiers des employés contenant des informations personnelles, notamment des noms, des numéros de sécurité sociale et des identifiants d'employés.

:path=/static-assets/pdf/content-code-examples/tutorials/pdf-redaction-csharp/redact-text-all-pages.cs
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")
$vbLabelText   $csharpLabel

Ce code charge un PDF contenant des informations sur les employés et supprime trois données confidentielles en appelant RedactTextOnAllPages pour chaque valeur. Chaque appel permet de parcourir toutes les pages du document et de supprimer définitivement toutes les occurrences du nom, du numéro de sécurité sociale et de l'identifiant interne de l'employé.

Exemple de résultat

Le comportement par défaut dessine des rectangles noirs à l'emplacement du texte expurgé et remplace les caractères actuels par des astérisques dans la structure du document. Cela permet à la fois de confirmer visuellement que la rédaction a eu lieu et de s'assurer que le contenu original a complètement disparu.

Lorsque vous travaillez avec des documents longs ou des cibles de rédaction multiples, vous pouvez enchaîner ces appels de manière efficace :

:path=/static-assets/pdf/content-code-examples/tutorials/pdf-redaction-csharp/redact-text-list.cs
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")
$vbLabelText   $csharpLabel

Ce modèle fonctionne bien lorsque vous disposez d'une liste connue de valeurs sensibles à supprimer. Le document est chargé une fois, toutes les rédactions sont appliquées en mémoire et le résultat final est sauvegardé. Chaque terme est traité indépendamment, de sorte que les correspondances partielles ou les différences de formatage entre les termes n'affectent pas les autres rédactions.

Comment puis-je expurger du texte sur des pages spécifiques uniquement?

Parfois, vous avez besoin d'un contrôle plus précis sur l'emplacement des caviardages. Un document peut comporter une page de couverture avec des informations qui doivent rester intactes, ou vous pouvez savoir que des données confidentielles n'apparaissent que dans certaines sections. IronPDF propose RedactTextOnPage pour la rédaction d'une seule page et RedactTextOnPages pour le ciblage de plusieurs pages spécifiques.

Entrée

Une liasse de contrats de plusieurs pages avec les noms des clients sur la page de signature et des termes financiers apparaissant sur des pages spécifiques dans le document.

:path=/static-assets/pdf/content-code-examples/tutorials/pdf-redaction-csharp/redact-specific-pages.cs
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")
$vbLabelText   $csharpLabel

Ce code démontre une rédaction ciblée en utilisant RedactTextOnPage pour une seule page et RedactTextOnPages pour plusieurs pages spécifiques. Le nom du client n'est supprimé que de la page 1 (index 0), tandis que les conditions de paiement sont expurgées des pages 3, 5 et 7 (index 2, 4, 6), toutes les autres pages restant intactes.

Exemple de résultat

Les indices de page dans IronPDF sont basés sur le zéro, ce qui signifie que la première page est l'indice 0, la deuxième l'indice 1, et ainsi de suite. Cela correspond aux conventions de programmation standard et s'aligne sur la façon dont la plupart des développeurs conçoivent l'accès aux tableaux.

Le ciblage de pages spécifiques améliore les performances lors du traitement de documents volumineux. Plutôt que de parcourir des centaines de pages à la recherche d'un texte qui n'apparaît qu'à quelques endroits, vous pouvez indiquer au moteur de rédaction l'endroit exact où il doit chercher. Cela est important pour les scénarios de traitement par lots dans lesquels vous pouvez traiter des milliers de documents. Pour un débit maximal, envisagez d'utiliser les techniques async et multithreading.

:path=/static-assets/pdf/content-code-examples/tutorials/pdf-redaction-csharp/redact-large-document.cs
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")
$vbLabelText   $csharpLabel

Cette approche ciblée ne traite que les sections pertinentes d'un document de 500 pages, ce qui réduit considérablement le temps d'exécution par rapport à l'analyse de chaque page pour chaque terme à expurger.

Comment personnaliser l'apparence du contenu expurgé?

IronPDF propose plusieurs paramètres pour contrôler la façon dont les caviardages apparaissent dans le document final. Vous pouvez ajuster la sensibilité à la casse, la correspondance des mots entiers, la possibilité de dessiner des rectangles visuels et le texte de remplacement qui apparaît à la place du contenu expurgé.

Entrée

Un dossier juridique contenant divers termes sensibles, notamment des étiquettes de classification, des mots de passe et des codes de référence internes qui nécessitent différents traitements rédactionnels.

:path=/static-assets/pdf/content-code-examples/tutorials/pdf-redaction-csharp/customize-redaction-appearance.cs
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")
$vbLabelText   $csharpLabel

Ce code démontre quatre configurations de rédaction différentes en utilisant les paramètres optionnels de RedactTextOnAllPages. Elle montre la correspondance exacte sensible à la casse avec le remplacement de "[EXPURGÉ]", la correspondance insensible à la casse avec des astérisques, la correspondance partielle des mots pour attraper des variations comme "mots de passe", et la suppression invisible sans rectangles visuels pour l'élimination transparente du contenu.

Exemple de résultat

Les paramètres servent différents objectifs en fonction de vos besoins :

CaseSensitive détermine si la correspondance tient compte de la casse des lettres. Les documents juridiques utilisent souvent des majuscules spécifiques qui sont porteuses de sens, c'est pourquoi le respect de la casse permet de ne supprimer que les correspondances exactes. Le traitement d'un texte général où la casse varie peut nécessiter une correspondance insensible à la casse afin de prendre en compte toutes les occurrences.

la fonction OnlyMatchWholeWords détermine si la recherche doit porter sur des mots complets ou des chaînes partielles. Lorsque vous caviardez des noms, vous souhaitez généralement que le mot entier corresponde, afin que "Smith" ne caviarde pas accidentellement une partie de "Blacksmith" ou de "Smithfield". Lors de l'expurgation de motifs tels que les préfixes de numéros de compte, une correspondance partielle peut être nécessaire pour détecter les variations.

DrawRectangles spécifie si des boîtes noires apparaissent là où le contenu a été supprimé. La plupart des contextes réglementaires et juridiques exigent des marques de rédaction visibles pour prouver que le contenu a été délibérément supprimé et non accidentellement omis. Les flux de travail internes peuvent préférer la suppression des éléments invisibles pour un résultat plus propre.

le Texte de remplacement définit les caractères qui apparaissent à la place du contenu expurgé. Les choix courants comprennent les astérisques, les étiquettes "EXPURGÉ" ou les chaînes vides. Le texte de remplacement apparaît dans la structure du document si quelqu'un tente de sélectionner ou de copier à partir de la zone expurgée.


Comment utiliser les expressions régulières pour trouver et expurger des motifs sensibles ?

L'expurgation de chaînes de texte connues fonctionne lorsque vous avez des valeurs spécifiques à supprimer, mais de nombreux types de données confidentielles suivent des modèles prévisibles plutôt que des valeurs fixes. Les numéros de sécurité sociale, les numéros de carte de crédit, les adresses électroniques, les numéros de téléphone et les dates ont tous des formats reconnaissables qui peuvent être comparés à l'aide d'expressions régulières. La création d'un système de rédaction basé sur des modèles vous permet de supprimer des informations privées d'un contenu PDF sans connaître chaque valeur spécifique à l'avance.

Les capacités d'extraction de texte d'IronPDF, associées à des méthodes de rédaction, permettent de mettre en place de puissants flux de travail de recherche de motifs. Vous extrayez le texte, identifiez les correspondances à l'aide d'expressions régulières .NET, puis expurgez chaque valeur découverte.

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"
        );
    }
}
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
$vbLabelText   $csharpLabel

Cette approche basée sur des modèles s'adapte bien parce que vous définissez les modèles une fois pour toutes et que vous les appliquez à n'importe quel document. L'ajout de nouveaux types de données ne nécessite que l'ajout de nouveaux motifs regex au dictionnaire.

Comment construire un scanner de données sensibles réutilisable?

Dans les environnements de production, il est souvent nécessaire de scanner les documents et de signaler les informations confidentielles existantes avant de décider de les expurger ou non. Cela facilite l'audit de conformité et permet une révision humaine des décisions de rédaction. La classe suivante offre des capacités de numérisation et de rédaction.

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");
    }
}
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
$vbLabelText   $csharpLabel

Le scanner offre une visibilité sur les informations confidentielles existantes avant toute modification. Cette traduction s'inscrit dans le cadre de flux de travail de conformité pour lesquels vous avez besoin d'une documentation sur ce qui a été trouvé et supprimé. La fonction de masquage permet de s'assurer que les fichiers journaux et les rapports ne deviennent pas eux-mêmes des sources d'exposition des données.


Comment expurger des régions ou des zones spécifiques d'un PDF?

La rédaction de texte traite efficacement le contenu basé sur des caractères, mais les PDF contiennent souvent des informations sensibles sous des formes que la correspondance de texte ne peut pas traiter. Les signatures, les photographies, les annotations manuscrites, les tampons et les éléments graphiques nécessitent une approche différente. La rédaction par région vous permet de spécifier des zones rectangulaires par leurs coordonnées et d'obscurcir de façon permanente tout ce qui se trouve à l'intérieur de ces limites.

IronPDF utilise la structure RectangleF pour définir les régions de rédaction. Vous indiquez les coordonnées X et Y du coin supérieur gauche, puis la largeur et la hauteur de la zone. Les coordonnées sont mesurées en points à partir du bas gauche de la page, ce qui correspond au système de coordonnées de la spécification PDF.

Entrée

Un document d'accord signé contenant des signatures manuscrites et une photo d'identité qui doivent être expurgées à l'aide d'un ciblage de région basé sur les coordonnées.

:path=/static-assets/pdf/content-code-examples/tutorials/pdf-redaction-csharp/redact-region-basic.cs
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")
$vbLabelText   $csharpLabel

Ce code utilise les structures RectangleF pour définir des zones rectangulaires pour la rédaction. La zone de signature est positionnée aux coordonnées (100, 650) avec une zone de 200x50 pixels, tandis que la zone de photo est positionnée aux coordonnées (450, 700) avec une zone de 100x120 pixels. La méthode RedactRegionsOnAllPages applique des rectangles noirs sur ces régions dans toutes les pages.

Exemple de résultat

La détermination des coordonnées correctes nécessite souvent des expériences ou des mesures. Les pages PDF utilisent généralement un système de coordonnées dans lequel un point équivaut à 1/72 de pouce. Une page US Letter standard a une largeur de 612 points et une hauteur de 792 points. Les pages A4 font environ 595 par 842 points. Les outils de visualisation des PDF qui affichent les coordonnées lorsque vous déplacez le curseur peuvent vous aider, ou vous pouvez extraire les dimensions de la page par programme :

:path=/static-assets/pdf/content-code-examples/tutorials/pdf-redaction-csharp/redact-region-dimensions.cs
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")
$vbLabelText   $csharpLabel

Comment puis-je expurger plusieurs régions sur différentes pages ?

Les documents complexes nécessitent souvent que différentes régions soient caviardées sur différentes pages. Un formulaire de plusieurs pages peut comporter des lignes de signature à des positions différentes, ou des pages différentes peuvent contenir des photos, des tampons ou d'autres éléments graphiques à des emplacements uniques. IronPDF inclut des méthodes spécifiques aux pages pour une rédaction ciblée des régions.

:path=/static-assets/pdf/content-code-examples/tutorials/pdf-redaction-csharp/redact-multiple-regions.cs
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")
$vbLabelText   $csharpLabel

Les documents dont la mise en page est cohérente bénéficient de définitions de régions réutilisables :

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");
    }
}
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");
    }
}
Imports IronPdf
Imports IronSoftware.Drawing

Public Class FormRegions
    ' Standard form regions based on common templates
    Public Shared ReadOnly Property HeaderLogo As RectangleF
        Get
            Return New RectangleF(20, 720, 150, 60)
        End Get
    End Property

    Public Shared ReadOnly Property SignatureBlock As RectangleF
        Get
            Return New RectangleF(72, 72, 200, 50)
        End Get
    End Property

    Public Shared ReadOnly Property DateField As RectangleF
        Get
            Return New RectangleF(400, 72, 120, 20)
        End Get
    End Property

    Public Shared ReadOnly Property PhotoId As RectangleF
        Get
            Return New RectangleF(480, 650, 100, 130)
        End Get
    End Property

    Public Shared ReadOnly Property AddressBlock As RectangleF
        Get
            Return New RectangleF(72, 600, 250, 80)
        End Get
    End Property
End Class

Module Program
    Sub Main()
        Dim pdf As PdfDocument = 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")
    End Sub
End Module
$vbLabelText   $csharpLabel

Comment supprimer les métadonnées susceptibles d'exposer des informations sensibles ?

Les métadonnées PDF représentent une source de fuite d'informations souvent négligée. Chaque PDF comporte des propriétés qui peuvent révéler des détails sensibles : le nom de l'auteur et son nom d'utilisateur, le logiciel utilisé pour créer le document, les horodatages de création et de modification, le nom du fichier d'origine, l'historique des révisions et les propriétés personnalisées ajoutées par diverses applications. Avant de partager des documents avec l'extérieur, il est essentiel de supprimer ou d'assainir ces métadonnées. Pour un aperçu complet des opérations de métadonnées, consultez notre guide pratique des métadonnées.

IronPDF expose les métadonnées des documents par le biais de la propriété MetaData, ce qui vous permet de lire les valeurs existantes, de les modifier ou de les supprimer entièrement.

:path=/static-assets/pdf/content-code-examples/tutorials/pdf-redaction-csharp/view-metadata.cs
using IronPdf;

// 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

' 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()
$vbLabelText   $csharpLabel

Pour supprimer les métadonnées sensibles avant la distribution :

Entrée

Un mémo interne contenant des métadonnées intégrées telles que les noms des auteurs, les horodatages de création et les propriétés personnalisées qui pourraient révéler des informations organisationnelles sensibles.

:path=/static-assets/pdf/content-code-examples/tutorials/pdf-redaction-csharp/remove-metadata.cs
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")
$vbLabelText   $csharpLabel

Ce code remplace les champs de métadonnées d'identification par des valeurs génériques, normalise les horodatages à la date actuelle et supprime les clés de métadonnées personnalisées que les applications peuvent avoir ajoutées. La méthode RemoveMetaDataKey cible des propriétés spécifiques telles que "OriginalFilename" et "LastSavedBy" qui pourraient exposer des informations internes.

Exemple de résultat

Le nettoyage approfondi des métadonnées dans le cadre d'opérations par lots nécessite une approche systématique :

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");
    }
}
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");
    }
}
Imports IronPdf
Imports System
Imports System.Collections.Generic

Public Class MetadataCleaner
    Private ReadOnly _defaultAuthor As String
    Private ReadOnly _defaultCreator As String

    Public Sub New(organizationName As String)
        _defaultAuthor = organizationName
        _defaultCreator = $"{organizationName} Document System"
    End Sub

    Public Sub CleanMetadata(pdf As PdfDocument)
        ' Replace standard metadata fields
        pdf.MetaData.Author = _defaultAuthor
        pdf.MetaData.Creator = _defaultCreator
        pdf.MetaData.Producer = ""
        pdf.MetaData.Subject = ""
        pdf.MetaData.Keywords = ""

        ' Normalize timestamps
        Dim now As DateTime = DateTime.Now
        pdf.MetaData.CreationDate = now
        pdf.MetaData.ModifiedDate = now

        ' Get all keys and remove potentially sensitive ones
        Dim keysToRemove As New List(Of String)()
        For Each key As String In pdf.MetaData.Keys()
            ' Keep only essential keys
            If Not IsEssentialKey(key) Then
                keysToRemove.Add(key)
            End If
        Next

        For Each key As String In keysToRemove
            pdf.MetaData.RemoveMetaDataKey(key)
        Next
    End Sub

    Private Function IsEssentialKey(key As String) As Boolean
        ' Keep only the basic display properties
        Dim essentialKeys As String() = {"Title", "Author", "CreationDate", "ModifiedDate"}
        For Each essential As String In essentialKeys
            If key.Equals(essential, StringComparison.OrdinalIgnoreCase) Then
                Return True
            End If
        Next
        Return False
    End Function
End Class

' Usage
Class Program
    Shared Sub Main()
        Dim cleaner As New MetadataCleaner("Acme Corporation")

        Dim pdf As PdfDocument = PdfDocument.FromFile("report.pdf")
        cleaner.CleanMetadata(pdf)
        pdf.SaveAs("report-clean.pdf")
    End Sub
End Class
$vbLabelText   $csharpLabel

Comment assainir un PDF pour supprimer les scripts intégrés et les menaces cachées ?

L'assainissement des PDF répond à des préoccupations de sécurité qui vont au-delà du contenu visible et des métadonnées. Les fichiers PDF peuvent contenir du code JavaScript, des exécutables intégrés, des actions de formulaire qui déclenchent des connexions externes et d'autres éléments potentiellement malveillants. Ces capacités existent à des fins légitimes, comme les formulaires interactifs et le contenu multimédia, mais elles créent également des vecteurs d'attaque. L'assainissement d'un PDF permet de supprimer ces éléments actifs tout en préservant le contenu visuel. Pour plus de détails sur les méthodes d'assainissement, consultez notre guide pratique d'assainissement des PDF.

La classe Cleaner d'IronPDF gère l'assainissement par le biais d'une approche élégante : convertir le PDF dans un format d'image, puis le reconvertir. Ce processus permet de supprimer le JavaScript, les objets intégrés, les actions de formulaire et les annotations, tout en conservant l'aspect visuel intact. La bibliothèque propose deux méthodes d'assainissement aux caractéristiques différentes.

Entrée

Un document PDF reçu d'une source externe qui peut contenir du JavaScript, des objets intégrés ou d'autres contenus actifs potentiellement malveillants.

:path=/static-assets/pdf/content-code-examples/tutorials/pdf-redaction-csharp/sanitize-pdf.cs
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")
$vbLabelText   $csharpLabel

Ce code démontre deux méthodes d'assainissement fournies par la classe Cleaner d'IronPDF. SanitizeWithSvg convertit le PDF dans un format intermédiaire SVG, préservant le texte consultable tout en supprimant le contenu actif. SanitizeWithBitmap convertit d'abord les pages en images, produisant des copies visuelles exactes mais avec le texte rendu sous forme de graphiques non consultables.

Exemple de résultat

La méthode SVG est plus rapide et préserve le texte en tant que contenu consultable, ce qui la rend adaptée aux documents qui doivent rester indexés ou accessibles. La méthode bitmap produit des copies visuelles exactes mais convertit le texte en images, ce qui empêche la sélection et la recherche de texte. Choisissez en fonction de vos exigences pour le document de sortie.

Vous pouvez également appliquer des options de rendu lors de l'assainissement pour ajuster le résultat :

:path=/static-assets/pdf/content-code-examples/tutorials/pdf-redaction-csharp/sanitize-with-options.cs
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")
$vbLabelText   $csharpLabel

Les environnements hautement sécurisés nécessitent souvent de combiner l'assainissement avec d'autres mesures de protection :

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");
    }
}
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
$vbLabelText   $csharpLabel

Comment analyser un PDF pour y déceler des vulnérabilités de sécurité?

Avant de traiter ou d'assainir des documents, il peut être utile d'évaluer les menaces potentielles qu'ils contiennent. La méthode Cleaner.ScanPdf d'IronPDF examine les documents à l'aide de règles YARA, qui sont des définitions de motifs couramment utilisées dans l'analyse des logiciels malveillants et la détection des menaces. L'analyse identifie les caractéristiques associées aux fichiers PDF malveillants.

:path=/static-assets/pdf/content-code-examples/tutorials/pdf-redaction-csharp/scan-vulnerabilities.cs
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
$vbLabelText   $csharpLabel

Vous pouvez fournir des fichiers de règles YARA personnalisés pour des besoins de détection spécifiques. Les organisations ayant des modèles de menaces spécifiques ou des besoins de conformité maintiennent souvent leurs propres ensembles de règles ciblant des modèles de vulnérabilité particuliers.

:path=/static-assets/pdf/content-code-examples/tutorials/pdf-redaction-csharp/scan-custom-yara.cs
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
$vbLabelText   $csharpLabel

L'intégration de la numérisation dans les flux de travail de réception des documents permet d'automatiser les décisions en matière de sécurité :

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");
        }
    }
}
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
$vbLabelText   $csharpLabel

Comment construire un pipeline complet de rédaction et d'assainissement?

Le traitement des documents de production nécessite généralement de combiner plusieurs techniques de protection dans un flux de travail cohérent. Un pipeline complet pourrait analyser les documents entrants à la recherche de menaces, assainir ceux qui passent le premier contrôle, appliquer des rédactions de texte et de région, supprimer les métadonnées et produire des journaux d'audit documentant toutes les actions entreprises. Cet exemple illustre une telle approche intégrée.

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);
        }
    }
}
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
$vbLabelText   $csharpLabel

Entrée

Un formulaire de demande de client contenant plusieurs types de données sensibles, notamment des numéros de sécurité sociale, des numéros de carte de crédit, des adresses électroniques et des blocs de signature, nécessitant une protection complète.

Exemple de résultat

Ce processeur complet combine toutes les techniques abordées dans ce guide en une seule classe configurable. La traduction doit rester professionnelle et préserver l'exactitude technique tout en expliquant les caractéristiques et les avantages de ces outils de développement. Vous pouvez ajuster les modèles de sensibilité, les régions de rédaction et les options de traitement pour répondre à vos besoins spécifiques.


Prochaines étapes

La protection des informations sensibles contenues dans les documents PDF exige plus que des mesures superficielles. La rédaction proprement dite élimine définitivement le contenu de la structure du document. Pattern matching automatise la découverte et la suppression de données telles que les numéros de sécurité sociale, les détails des cartes de crédit et les adresses électroniques. La rédaction par région permet de traiter les signatures, les photos et d'autres éléments graphiques que la concordance de texte ne peut pas prendre en compte. Le nettoyage des métadonnées élimine les informations cachées qui pourraient révéler les auteurs, les horodatages ou les chemins d'accès internes aux fichiers. Sanitization supprime les scripts intégrés et le contenu actif qui présentent des risques pour la sécurité.

IronPDF offre toutes ces capacités grâce à une API cohérente et bien conçue qui s'intègre naturellement aux pratiques de développement C# et .NET. Les méthodes présentées dans ce guide traitent des documents uniques ou s'étendent à des traitement par lots milliers de fichiers. Que vous construisiez des flux de travail de conformité pour les données de santé, que vous prépariez des documents juridiques pour la divulgation, ou que vous vous assuriez simplement que les rapports internes peuvent être partagés en toute sécurité avec l'extérieur, ces techniques constituent la base d'un traitement responsable des documents. Pour une couverture complète de la sécurité, combinez la rédaction avec la protection par mot de passe et les permissions et les signatures numériques.

Prêt à commencer la construction ? Téléchargez IronPDF et essayez-le avec une version d'essai gratuite. La bibliothèque comprend une licence de développement gratuite, qui vous permet d'évaluer pleinement les fonctionnalités de rédaction, extraction de texte et d'assainissement avant de vous engager dans une licence de production. Si vous avez des questions sur la mise en œuvre ou les flux de travail de conformité, prenez contact avec notre équipe d'assistance technique.

Questions Fréquemment Posées

Qu'est-ce que la rédaction PDF ?

La rédaction d'un document PDF est le processus qui consiste à supprimer définitivement les informations sensibles d'un document PDF. Il peut s'agir de textes, d'images et de métadonnées qui doivent être masqués pour des raisons de confidentialité ou de conformité.

Comment caviarder des informations dans un PDF à l'aide de C# ?

Vous pouvez utiliser IronPDF pour expurger des informations dans un PDF à l'aide de C#. Il vous permet de supprimer ou de masquer de façon permanente du texte, des images et des métadonnées dans des documents PDF, en veillant à ce qu'ils respectent les normes de confidentialité et de conformité.

Pourquoi la rédaction des PDF est-elle importante pour la conformité ?

La rédaction de PDF est cruciale pour la conformité avec des normes telles que HIPAA, GDPR et PCI DSS, car elle permet de sécuriser les données sensibles et d'empêcher l'accès non autorisé à des informations confidentielles.

IronPDF peut-il expurger des régions entières d'un PDF ?

Oui, IronPDF peut expurger des régions entières d'un PDF. Cela vous permet de définir des zones spécifiques d'un document qui doivent être cachées ou supprimées à des fins de sécurité.

Quels types de données peuvent être expurgés à l'aide d'IronPdf ?

IronPDF peut expurger différents types de données, notamment du texte, des images et des métadonnées de documents PDF, garantissant ainsi une confidentialité et une sécurité complètes des données.

IronPDF prend-il en charge l'assainissement des documents ?

Oui, IronPDF prend en charge l'assainissement des documents, qui consiste à nettoyer un PDF pour supprimer les données ou métadonnées cachées qui ne sont peut-être pas visibles mais qui pourraient tout de même présenter un risque pour la vie privée.

Est-il possible d'automatiser la rédaction de PDF avec IronPDF ?

Oui, IronPDF permet d'automatiser les processus de rédaction de PDF en C#, facilitant ainsi la gestion de gros volumes de documents nécessitant la suppression de données sensibles.

Comment IronPDF assure-t-il la permanence de la rédaction ?

IronPDF garantit la permanence de la rédaction en supprimant définitivement le texte et les images sélectionnés du document, plutôt que de simplement les obscurcir, ce qui signifie qu'ils ne peuvent pas être récupérés ou visualisés.

IronPDF peut-il expurger les métadonnées d'un PDF ?

Oui, IronPDF peut expurger les métadonnées d'un document PDF, en veillant à ce que toutes les formes de données sensibles, y compris les données cachées ou en arrière-plan, soient soigneusement supprimées.

Quels sont les avantages de l'utilisation d'IronPDF pour la rédaction de PDF ?

L'utilisation d'IronPDF pour la rédaction de PDF offre des avantages tels que la garantie de la conformité aux réglementations sur la protection des données, le renforcement de la sécurité des documents et la mise en place d'un processus efficace et automatisé pour la gestion des informations sensibles.

Curtis Chau
Rédacteur technique

Curtis Chau détient un baccalauréat en informatique (Université de Carleton) et se spécialise dans le développement front-end avec expertise en Node.js, TypeScript, JavaScript et React. Passionné par la création d'interfaces utilisateur intuitives et esthétiquement plaisantes, Curtis aime travailler avec des frameworks modernes ...

Lire la suite
Prêt à commencer?
Nuget Téléchargements 17,386,124 | Version : 2026.2 vient de sortir