PDF Redaction in C#: Remove Sensitive Data and Sanitize Documents with IronPDF

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

A redação de PDFs em C# .NET com IronPDF remove permanentemente o conteúdo sensível da estrutura interna de um documento, e não apenas o oculta visualmente, de forma que nenhuma quantidade de cópias, buscas ou análises forenses consiga recuperar os dados originais. Isso vai muito além de retângulos pretos sobre o texto: o IronPDF oferece redação de texto com correspondência de padrões regex, redação baseada em região para assinaturas e imagens, remoção de metadados, higienização de documentos para eliminar scripts incorporados e verificação de vulnerabilidades, fornecendo aos desenvolvedores .NET um conjunto completo de ferramentas para editar PDF de forma segura e criar fluxos de trabalho de proteção de documentos em conformidade com HIPAA, GDPR e PCI DSS.

Resumo: Guia de Início Rápido

Este tutorial aborda a remoção permanente de conteúdo sensível de documentos PDF em C# .NET, incluindo padrões de texto, regiões de imagem, metadados e scripts incorporados.

  • Para quem é indicado: Desenvolvedores .NET que lidam com documentos confidenciais em contextos de saúde, jurídicos, financeiros ou governamentais.
  • O que você vai desenvolver: Redação de texto com correspondência de padrões regex (números de segurança social, cartões de crédito, emails), redação de regiões baseada em coordenadas para assinaturas e fotos, limpeza de metadados, higienização de PDFs para remover scripts incorporados e varredura de vulnerabilidades baseada em YARA.
  • Onde funciona: .NET 10, .NET 8 LTS, .NET Framework 4.6.2+ e .NET Standard 2.0. Todas as operações são executadas localmente, sem dependências externas.
  • Quando usar essa abordagem: Quando você precisa compartilhar documentos para fins de descoberta legal, solicitações da Lei de Liberdade de Informação (FOIA) ou distribuição externa, garantindo que o conteúdo removido seja realmente apagado.
  • Por que isso é importante tecnicamente: As sobreposições visuais permitem que o texto original seja recuperado nos fluxos de conteúdo do PDF. A função de redação do IronPDF apaga os dados dos caracteres da própria estrutura do documento, tornando a recuperação impossível.

Redija texto sensível de um PDF com apenas algumas linhas de código:

  1. Instale IronPDF com o Gerenciador de Pacotes NuGet

    PM > Install-Package IronPdf
  2. Copie e execute este trecho de código.

    using IronPdf;
    
    PdfDocument pdf = PdfDocument.FromFile("confidential-report.pdf");
    pdf.RedactTextOnAllPages("CONFIDENTIAL");
    pdf.SaveAs("redacted-report.pdf");
  3. Implante para testar em seu ambiente de produção.

    Comece a usar IronPDF em seu projeto hoje com uma avaliação gratuita

    arrow pointer

Após adquirir ou se inscrever para um período de avaliação de 30 dias do IronPDF, adicione sua chave de licença no início do seu aplicativo.

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

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

!{--010011000100100101000010010100100100000101010010010110010101111101010011010101000100000101010010010101000101111101010001010010010010010010100000101001100010111110100001001001100010011110100001101001011--}

NuGet Instalar com NuGet

PM >  Install-Package IronPdf

Confira o IronPDF no NuGet para uma instalação rápida. Com mais de 10 milhões de downloads, ele está transformando o desenvolvimento de PDFs com C#. Você também pode baixar o arquivo DLL ou o instalador para Windows .

Índice

Qual a diferença entre redação verdadeira e sobreposição visual?

Compreender a distinção entre redação verdadeira e sobreposição visual é fundamental para qualquer pessoa que lide com documentos confidenciais. Muitas ferramentas e métodos manuais criam a aparência de redação sem realmente remover os dados subjacentes. Essa falsa sensação de segurança causou inúmeras violações de dados de alto perfil e falhas de conformidade.

As abordagens de sobreposição visual normalmente desenham formas opacas sobre o conteúdo sensível. O texto permanece totalmente intacto dentro da estrutura do PDF. Quem visualiza o documento vê um retângulo preto, mas os caracteres originais ainda existem nos fluxos de conteúdo do arquivo. Selecionar todo o texto da página, usar ferramentas de acessibilidade ou examinar os dados brutos do PDF revelará tudo o que supostamente estava oculto. Processos judiciais foram comprometidos quando documentos previamente editados foram, por descuido, divulgados pela parte contrária. Agências governamentais divulgaram acidentalmente informações confidenciais que pareciam censuradas, mas que puderam ser totalmente recuperadas.

A verdadeira redação funciona de maneira diferente. Ao utilizar os métodos de redação do IronPDF, a biblioteca localiza o texto especificado na estrutura interna do PDF e o remove completamente. Os dados dos personagens são excluídos dos fluxos de conteúdo. A representação visual é substituída por uma marca de redação, geralmente um retângulo preto, mas o conteúdo original deixa de existir em qualquer lugar do arquivo. Nenhuma quantidade de seleção, cópia ou análise forense consegue recuperar o que foi apagado permanentemente.

O IronPDF implementa a redação verdadeira modificando o PDF em nível estrutural. O método RedactTextOnAllPages e suas variantes pesquisam no conteúdo da página, identificam o texto correspondente, removem-no do modelo de objeto do documento e, opcionalmente, desenham um indicador visual onde o conteúdo costumava aparecer. Essa abordagem está alinhada com as diretrizes de organizações como o NIST para redação segura de documentos.

As implicações práticas são significativas. Se você precisar compartilhar documentos externamente, enviar arquivos para fins de descoberta legal, publicar registros em resposta a pedidos de acesso à informação ou distribuir relatórios, protegendo ao mesmo tempo informações de identificação pessoal, somente a redação verdadeira oferece proteção adequada. Sobreposições visuais podem ser suficientes para rascunhos internos onde você simplesmente deseja desviar a atenção de certas seções, mas nunca devem ser consideradas para proteção de dados em tempo real. Para medidas adicionais de segurança de documentos, consulte nossos guias sobre criptografia de PDFs e assinaturas digitais .


How do I Redact PDF Text in C# Across an Entire Document?

O cenário de redação mais comum envolve a remoção de todas as ocorrências de um texto específico em um documento. Talvez seja necessário eliminar o nome de uma pessoa de um relatório, remover números de contas de demonstrações financeiras ou eliminar códigos de referência internos antes da distribuição externa. O IronPDF torna isso simples com o método RedactTextOnAllPages.

Entrada

Um documento de registro de funcionários contendo informações pessoais, incluindo nomes, números de segurança social e números de identificação de funcionários.

: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

Este código carrega um PDF contendo informações de funcionários e remove três dados confidenciais chamando RedactTextOnAllPages para cada valor. Cada chamada pesquisa todas as páginas do documento e remove permanentemente todas as ocorrências correspondentes ao nome do funcionário, número do Seguro Social e identificador interno.

Exemplo de saída

O comportamento padrão desenha retângulos pretos onde o texto ocultado aparecia e substitui os caracteres reais por asteriscos na estrutura do documento. Isso fornece confirmação visual de que a redação ocorreu e garante que o conteúdo original foi completamente removido.

Ao trabalhar com documentos mais longos ou vários alvos de redação, você pode encadear essas chamadas de forma eficiente:

: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

Esse padrão funciona bem quando você tem uma lista conhecida de valores sensíveis a serem removidos. O documento é carregado uma única vez, todas as redações são aplicadas na memória e o resultado final é salvo. Cada termo é processado de forma independente, portanto, correspondências parciais ou diferenças de formatação entre os termos não afetam outras redações.

Como posso ocultar texto apenas em páginas específicas?

Às vezes, você precisa de um controle mais preciso sobre onde as redações ocorrem. Um documento pode ter uma capa com informações que devem permanecer intactas, ou você pode saber que dados confidenciais aparecem apenas em determinadas seções. O IronPDF oferece RedactTextOnPage para redação de página única e RedactTextOnPages para direcionar várias páginas específicas.

Entrada

Um conjunto de contratos com várias páginas, contendo o nome do cliente na página de assinatura e os termos financeiros em páginas específicas ao longo do documento.

: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

Este código demonstra redação direcionada usando RedactTextOnPage para uma única página e RedactTextOnPages para várias páginas específicas. O nome do cliente é removido apenas da página 1 (índice 0), enquanto as condições de pagamento são omitidas das páginas 3, 5 e 7 (índices 2, 4 e 6), deixando todas as outras páginas intactas.

Exemplo de saída

Em IronPDF, os índices de página começam em zero, ou seja, a primeira página tem índice 0, a segunda tem índice 1 e assim por diante. Isso está de acordo com as convenções de programação padrão e se alinha com a maneira como a maioria dos desenvolvedores pensa sobre o acesso a arrays.

Direcionar o processamento para páginas específicas melhora o desempenho ao processar documentos grandes. Em vez de analisar centenas de páginas em busca de texto que aparece apenas em alguns locais, você pode direcionar o mecanismo de redação exatamente para onde procurar. Isso é importante em cenários de processamento em lote, onde você pode lidar com milhares de documentos. Para obter o máximo desempenho, considere usar técnicas assíncronas e 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

Essa abordagem direcionada processa apenas as seções relevantes de um documento de 500 páginas, reduzindo significativamente o tempo de execução em comparação com a verificação de cada página em busca de cada termo de redação.

Como faço para personalizar a aparência do conteúdo ocultado?

O IronPDF oferece diversos parâmetros para controlar como as redações aparecem no documento final. Você pode ajustar a diferenciação entre maiúsculas e minúsculas, a correspondência de palavras inteiras, se deseja desenhar retângulos visuais e qual texto de substituição aparece no lugar do conteúdo ocultado.

Entrada

Um documento jurídico contendo diversos termos sensíveis, incluindo rótulos de classificação, senhas e códigos de referência internos que exigem diferentes tratamentos de redação.

: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

Este código demonstra quatro configurações diferentes de redação usando os parâmetros opcionais de RedactTextOnAllPages. Mostra correspondência exata que diferencia maiúsculas de minúsculas com substituição por "[REDACTED]", correspondência que ignora maiúsculas e minúsculas com asteriscos, correspondência parcial de palavras para detectar variações como "senhas" e remoção invisível sem retângulos visuais para eliminação de conteúdo perfeita.

Exemplo de saída

Os parâmetros servem a propósitos diferentes, dependendo das suas necessidades:

A opção "CaseSensitive" determina se a correspondência leva em consideração maiúsculas e minúsculas. Documentos jurídicos frequentemente usam maiúsculas específicas que carregam significado, portanto, a correspondência que diferencia maiúsculas de minúsculas garante que você remova apenas as correspondências exatas. O processamento de texto geral onde há variação entre maiúsculas e minúsculas pode exigir uma correspondência que ignore maiúsculas e minúsculas para abranger todas as ocorrências.

OnlyMatchWholeWords controla se a pesquisa corresponde a palavras inteiras ou a sequências parciais. Ao redigir nomes, geralmente se deseja que a correspondência seja feita por completo, para que "Smith" não redija acidentalmente parte de "Blacksmith" ou "Smithfield". Ao redigir padrões como prefixos de números de conta, a correspondência parcial pode ser necessária para detectar variações.

DrawRectangles especifica se caixas pretas aparecem onde o conteúdo foi removido. Na maioria dos contextos regulatórios e legais, são necessárias marcas de redação visíveis como prova de que o conteúdo foi removido deliberadamente e não omitido acidentalmente. Fluxos de trabalho internos podem preferir a remoção invisível para uma saída mais limpa.

ReplacementText define quais caracteres aparecem no lugar do conteúdo ocultado. As opções mais comuns incluem asteriscos, rótulos "REDACTED" ou sequências vazias. O texto de substituição aparece na estrutura do documento se alguém tentar selecionar ou copiar a área ocultada.


Como posso usar expressões regulares para encontrar e ocultar padrões sensíveis?

A ocultação de sequências de texto conhecidas funciona quando você tem valores específicos para remover, mas muitos tipos de dados confidenciais seguem padrões previsíveis em vez de valores fixos. Números de segurança social, números de cartão de crédito, endereços de e-mail, números de telefone e datas possuem formatos reconhecíveis que podem ser comparados com expressões regulares. Criar um sistema de redação baseado em padrões permite remover informações privadas do conteúdo de PDFs sem precisar conhecer todos os valores específicos antecipadamente.

Os recursos de extração de texto do IronPDF, combinados com métodos de redação, possibilitam fluxos de trabalho de correspondência de padrões poderosos. Você extrai o texto, identifica as correspondências usando expressões regulares do .NET e, em seguida, oculta cada valor encontrado.

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

Essa abordagem baseada em padrões é escalável porque você define os padrões uma única vez e os aplica a qualquer documento. Adicionar novos tipos de dados requer apenas a adição de novos padrões de expressão regular ao dicionário.

Como posso criar um scanner de dados sensíveis reutilizável?

Em ambientes de produção, muitas vezes é necessário digitalizar documentos e relatar quais informações confidenciais existem antes de decidir se é preciso redigir algum conteúdo. Isso auxilia na auditoria de conformidade e permite a revisão humana das decisões de redação. A seguinte classe oferece recursos de digitalização juntamente com redação.

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

O scanner oferece visibilidade das informações confidenciais existentes antes que qualquer modificação ocorra. Isso auxilia nos fluxos de trabalho de conformidade, nos quais é necessário documentar o que foi encontrado e removido. A função de mascaramento garante que os arquivos de log e os relatórios não se tornem fontes de exposição de dados.


Como faço para ocultar regiões ou áreas específicas em um PDF?

A redação de texto lida eficazmente com conteúdo baseado em caracteres, mas os PDFs geralmente contêm informações confidenciais em formatos que a correspondência de texto não consegue resolver. Assinaturas, fotografias, anotações manuscritas, carimbos e elementos gráficos exigem uma abordagem diferente. A redação baseada em região permite especificar áreas retangulares por suas coordenadas e ocultar permanentemente tudo o que estiver dentro desses limites.

O IronPDF utiliza a estrutura RectangleF para definir regiões de redação. Você especifica as coordenadas X e Y do canto superior esquerdo e, em seguida, a largura e a altura da área. As coordenadas são medidas em pontos a partir do canto inferior esquerdo da página, o que corresponde ao sistema de coordenadas da especificação PDF.

Entrada

Um documento de acordo assinado contendo assinaturas manuscritas e uma foto de identificação que precisam ser ocultadas usando segmentação regional baseada em coordenadas.

: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

Este código usa estruturas RectangleF para definir áreas retangulares para redação. A região da assinatura está posicionada nas coordenadas (100, 650) com uma área de 200x50 pixels, enquanto a região da foto está em (450, 700) com uma área de 100x120 pixels. O método RedactRegionsOnAllPages aplica retângulos pretos sobre essas regiões em todas as páginas.

Exemplo de saída

Determinar as coordenadas corretas geralmente requer alguma experimentação ou medição. As páginas em PDF normalmente usam um sistema de coordenadas onde um ponto equivale a 1/72 de polegada. Uma página padrão do formato Carta (US Letter) tem 612 pontos de largura e 792 pontos de altura. As páginas A4 têm aproximadamente 595 por 842 pontos. Ferramentas de visualização de PDF que exibem as coordenadas conforme você move o cursor podem ajudar, ou você pode extrair as dimensões da página programaticamente:

: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

Como posso ocultar várias regiões em páginas diferentes?

Documentos complexos frequentemente exigem que diferentes regiões sejam ocultadas em páginas diferentes. Um formulário com várias páginas pode ter linhas para assinatura em posições variadas, ou páginas diferentes podem conter fotos, carimbos ou outros elementos gráficos em locais específicos. O IronPDF inclui métodos específicos de página para redação de regiões específicas.

: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

Documentos com layouts consistentes se beneficiam de definições de região reutilizáveis:

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

Como faço para remover metadados que possam expor informações confidenciais?

Os metadados de PDFs representam uma fonte de vazamento de informações frequentemente negligenciada. Todo PDF contém propriedades que podem revelar detalhes confidenciais: o nome e o nome de usuário do autor, o software usado para criar o documento, os registros de criação e modificação, o nome original do arquivo, o histórico de revisões e propriedades personalizadas adicionadas por diversos aplicativos. Antes de compartilhar documentos externamente, é essencial remover ou anonimizar esses metadados. Para uma visão geral completa das operações de metadados, consulte nosso guia prático de metadados .

O IronPDF expõe metadados do documento através da propriedade MetaData, permitindo que você leia valores existentes, os modifique ou os remova completamente.

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

// Load a document containing sensitive metadata
PdfDocument pdf = PdfDocument.FromFile("internal-report.pdf");

// Access current metadata properties
string author = pdf.MetaData.Author;
string title = pdf.MetaData.Title;
string subject = pdf.MetaData.Subject;
string keywords = pdf.MetaData.Keywords;
string creator = pdf.MetaData.Creator;
string producer = pdf.MetaData.Producer;
DateTime? creationDate = pdf.MetaData.CreationDate;
DateTime? modifiedDate = pdf.MetaData.ModifiedDate;

// Get all metadata keys including custom properties
var allKeys = pdf.MetaData.Keys();
Imports IronPdf
Imports System

' Load a document containing sensitive metadata
Dim pdf As PdfDocument = PdfDocument.FromFile("internal-report.pdf")

' Access current metadata properties
Dim author As String = pdf.MetaData.Author
Dim title As String = pdf.MetaData.Title
Dim subject As String = pdf.MetaData.Subject
Dim keywords As String = pdf.MetaData.Keywords
Dim creator As String = pdf.MetaData.Creator
Dim producer As String = pdf.MetaData.Producer
Dim creationDate As DateTime? = pdf.MetaData.CreationDate
Dim modifiedDate As DateTime? = pdf.MetaData.ModifiedDate

' Get all metadata keys including custom properties
Dim allKeys = pdf.MetaData.Keys()
$vbLabelText   $csharpLabel

Para remover metadados sensíveis antes da distribuição:

Entrada

Um memorando interno contendo metadados incorporados, como nomes de autores, datas de criação e propriedades personalizadas, que podem revelar informações organizacionais confidenciais.

: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

Este código substitui os campos de metadados de identificação por valores genéricos, normaliza os registros de data e hora para a data atual e remove as chaves de metadados personalizadas que os aplicativos possam ter adicionado. O método RemoveMetaDataKey direciona propriedades específicas como 'OriginalFilename' e 'LastSavedBy' que poderiam expor informações internas.

Exemplo de saída

A limpeza completa de metadados em operações em lote requer uma abordagem sistemática:

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

Como posso higienizar um PDF para remover scripts incorporados e ameaças ocultas?

A higienização de PDFs aborda preocupações de segurança que vão além do conteúdo visível e dos metadados. Os arquivos PDF podem conter código JavaScript , executáveis ​​incorporados, ações de formulário que acionam conexões externas e outros elementos potencialmente maliciosos. Essas funcionalidades existem para fins legítimos, como formulários interativos e conteúdo multimídia, mas também criam vetores de ataque. A higienização de um PDF remove esses elementos ativos, preservando o conteúdo visual. Para obter mais detalhes sobre os métodos de higienização, consulte nosso guia prático de higienização em PDF .

A classe Cleaner do IronPDF lida com a sanitização por meio de uma abordagem elegante: convertendo o PDF para um formato de imagem e depois convertendo-o de volta. Esse processo remove o JavaScript, objetos incorporados, ações de formulário e anotações, mantendo a aparência visual intacta. A biblioteca oferece dois métodos de higienização com características diferentes.

Entrada

Um documento PDF recebido de uma fonte externa que pode conter JavaScript, objetos incorporados ou outro conteúdo ativo potencialmente malicioso.

: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

Este código demonstra dois métodos de sanitização fornecidos pela classe Cleaner do IronPDF. SanitizeWithSvg converte o PDF por meio de um formato intermediário SVG, preservando o texto pesquisável enquanto remove o conteúdo ativo. SanitizeWithBitmap converte as páginas em imagens primeiro, produzindo cópias visuais exatas, mas com o texto renderizado como gráficos não pesquisáveis.

Exemplo de saída

O método SVG funciona mais rápido e preserva o texto como conteúdo pesquisável, tornando-o adequado para documentos que precisam permanecer indexados ou acessíveis. O método bitmap produz cópias visuais exatas, mas converte o texto em imagens, o que impede a seleção e a busca de texto. Escolha com base nos seus requisitos para o documento de saída.

Você também pode aplicar opções de renderização durante a sanitização para ajustar a saída:

: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

Ambientes de alta segurança frequentemente exigem a combinação da higienização com outras medidas de proteção:

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

Como faço para verificar vulnerabilidades de segurança em um PDF?

Antes de processar ou higienizar documentos, convém avaliar as potenciais ameaças que eles contêm. O método Cleaner.ScanPdf do IronPDF examina documentos usando regras YARA, que são definições de padrões comumente usadas na análise de malware e detecção de ameaças. A verificação identifica características associadas a arquivos PDF maliciosos.

: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

Você pode fornecer arquivos de regras YARA personalizados para requisitos de detecção específicos. Organizações com modelos de ameaça específicos ou necessidades de conformidade geralmente mantêm seus próprios conjuntos de regras direcionados a padrões de vulnerabilidade específicos.

: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

A integração da digitalização nos fluxos de trabalho de entrada de documentos ajuda a automatizar as decisões de segurança:

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

Como posso construir um pipeline completo de redação e higienização?

O processamento de documentos de produção normalmente exige a combinação de múltiplas técnicas de proteção em um fluxo de trabalho coeso. Um pipeline completo pode analisar documentos recebidos em busca de ameaças, higienizar aqueles que passam pela triagem inicial, aplicar redações de texto e região, remover metadados e gerar registros de auditoria que documentam todas as ações realizadas. Este exemplo demonstra essa abordagem integrada.

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

Entrada

Um formulário de solicitação de cliente contendo vários tipos de dados sensíveis, incluindo números de segurança social, números de cartão de crédito, endereços de e-mail e blocos de assinatura, que requer proteção abrangente.

Exemplo de saída

Este processador abrangente combina todas as técnicas abordadas neste guia em uma única classe configurável. Ele verifica a presença de ameaças, higieniza os dados quando necessário, encontra e oculta padrões sensíveis, aplica ocultação de regiões, limpa metadados e gera relatórios detalhados. Você pode ajustar os padrões de sensibilidade, as regiões de redação e as opções de processamento para atender às suas necessidades específicas.


Próximos passos

Proteger informações sensíveis em documentos PDF exige mais do que medidas superficiais. A redação verdadeira elimina o conteúdo da estrutura do documento de forma permanente. A correspondência de padrões automatiza a descoberta e remoção de dados como números de segurança social, detalhes de cartões de crédito e endereços de e-mail. A redação baseada em região lida com assinaturas, fotos e outros elementos gráficos que a correspondência de texto não consegue processar. A limpeza de metadados elimina informações ocultas que poderiam revelar autores, datas e horas ou caminhos internos de arquivos. A higienização remove scripts incorporados e conteúdo ativo que representam riscos de segurança.

O IronPDF oferece todas essas funcionalidades por meio de uma API consistente e bem projetada, que se integra naturalmente às práticas de desenvolvimento em C# e .NET . Os métodos demonstrados neste guia permitem lidar com documentos individuais ou são escaláveis ​​para o processamento em lote de milhares de arquivos. Seja para criar fluxos de trabalho de conformidade para dados de saúde, preparar documentos jurídicos para descoberta de provas ou simplesmente garantir que relatórios internos possam ser compartilhados externamente com segurança, essas técnicas formam a base do manuseio responsável de documentos. Para uma cobertura de segurança abrangente, combine a redação com a proteção por senha, permissões e assinaturas digitais .

Pronto para começar a construir? Baixe o IronPDF e experimente com um período de teste gratuito. A biblioteca inclui uma licença de desenvolvimento gratuita, para que você possa avaliar completamente os recursos de redação, extração de texto e higienização antes de adquirir uma licença de produção. Se você tiver dúvidas sobre implementação ou fluxos de trabalho de conformidade, entre em contato com nossa equipe de suporte de engenharia .

Perguntas frequentes

O que é redação de PDF?

A redação de PDFs é o processo de remoção permanente de informações sensíveis de um documento PDF. Isso pode incluir texto, imagens e metadados que precisam ser ocultados por motivos de privacidade ou conformidade.

Como posso ocultar informações em um PDF usando C#?

Você pode usar o IronPDF para ocultar informações em um PDF usando C#. Ele permite remover ou ocultar permanentemente texto, imagens e metadados em documentos PDF, garantindo que atendam aos padrões de privacidade e conformidade.

Por que a redação de PDFs é importante para a conformidade?

A redação de PDFs é crucial para a conformidade com normas como HIPAA, GDPR e PCI DSS, pois ajuda a proteger dados sensíveis e a impedir o acesso não autorizado a informações confidenciais.

O IronPDF consegue redigir regiões inteiras de um PDF?

Sim, o IronPDF pode ocultar regiões inteiras de um PDF. Isso permite definir áreas específicas dentro de um documento que precisam ser ocultadas ou removidas por motivos de segurança.

Que tipos de dados podem ser ocultados usando o IronPDF?

O IronPDF pode redigir diversos tipos de dados, incluindo texto, imagens e metadados de documentos PDF, garantindo total privacidade e segurança dos dados.

O IronPDF suporta a higienização de documentos?

Sim, o IronPDF suporta a higienização de documentos, que consiste em limpar um PDF para remover dados ocultos ou metadados que podem não ser visíveis, mas ainda assim representar um risco à privacidade.

É possível automatizar a redação de PDFs com o IronPDF?

Sim, o IronPDF permite a automatização dos processos de redação de PDFs em C#, facilitando o processamento de grandes volumes de documentos que exigem a remoção de dados sensíveis.

Como o IronPDF garante a permanência da redação?

O IronPDF garante a permanência da redação, removendo permanentemente o texto e as imagens selecionados do documento, em vez de apenas os ocultar, o que significa que não podem ser recuperados ou visualizados.

O IronPDF consegue ocultar metadados em um PDF?

Sim, o IronPDF pode ocultar metadados em um documento PDF, garantindo que todas as formas de dados sensíveis, incluindo dados ocultos ou de fundo, sejam completamente removidas.

Quais são os benefícios de usar o IronPDF para redação de PDFs?

Utilizar o IronPDF para redação de PDFs oferece benefícios como garantir a conformidade com as normas de proteção de dados, aumentar a segurança dos documentos e fornecer um processo eficiente e automatizado para gerenciar informações confidenciais.

Curtis Chau
Redator Técnico

Curtis Chau é bacharel em Ciência da Computação (Universidade Carleton) e se especializa em desenvolvimento front-end, com experiência em Node.js, TypeScript, JavaScript e React. Apaixonado por criar interfaces de usuário intuitivas e esteticamente agradáveis, Curtis gosta de trabalhar com frameworks modernos e criar manuais ...

Leia mais
Pronto para começar?
Nuget Downloads 18,318,263 | Versão: 2026.4 acaba de ser lançado
Still Scrolling Icon

Ainda está rolando a tela?

Quer provas rápidas? PM > Install-Package IronPdf
executar um exemplo Veja seu HTML se transformar em um PDF.