PowerShell使用iTextSharp实现PDF签名并锁定表单的问题求助
Solution for iTextSharp PDF Signing + Form Locking in PowerShell
Key Fix for Empty PDF Issue
Your third code snippet produces an empty PDF because it only configures the signature appearance but doesn't actually perform the digital signature using a certificate. iTextSharp requires explicit signature execution via the MakeSignature class. Below are complete working examples for your use cases.
1. Sign with Installed Certificate (By Common Name)
Retrieves a certificate from the Windows certificate store, signs the PDF, and locks (flattens) form fields.
# Load required assemblies Add-Type -Path "$ScriptDirectory\data\lib\itextsharp.dll" Add-Type -Path "$ScriptDirectory\data\lib\BouncyCastle.Crypto.dll" # Mandatory for iTextSharp crypto operations # Configuration $PdfFilePath = "$ScriptDirectory\Test_IN.pdf" $NewPdfFilePath = $PdfFilePath -replace '\.pdf$', '_Sig.pdf' $SignatureFieldName = "doctor_signature" $CertCommonName = "Test User" # Fetch certificate from Windows Current User store $certStore = New-Object System.Security.Cryptography.X509Certificates.X509Store("My", "CurrentUser") $certStore.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadOnly) $cert = $certStore.Certificates | Where-Object { $_.Subject -match "CN=$CertCommonName" } | Select-Object -First 1 $certStore.Close() if (-not $cert) { Write-Error "Certificate with common name '$CertCommonName' not found." exit 1 } # Initialize PDF reader and stamper (append mode required for signing) $reader = New-Object iTextSharp.text.pdf.PdfReader($PdfFilePath) $outputStream = New-Object System.IO.FileStream($NewPdfFilePath, [System.IO.FileMode]::Create) $stamper = New-Object iTextSharp.text.pdf.PdfStamper($reader, $outputStream, [char]0, $true) # Configure signature appearance $signatureAppearance = $stamper.SignatureAppearance $signatureAppearance.SetVisibleSignature($SignatureFieldName) $signatureAppearance.Layer2Text = "Digitally signed by: $CertCommonName" $signatureAppearance.Reason = "Document authentication" $signatureAppearance.Location = "PowerShell Tool" $signatureAppearance.SignDate = [DateTime]::Now # Execute detached digital signature (standard PDF signing method) $privateKey = $cert.PrivateKey $chain = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2Collection($cert) [iTextSharp.text.pdf.security.MakeSignature]::SignDetached( $signatureAppearance, $privateKey, $chain, $null, $null, $null, 0, [iTextSharp.text.pdf.security.CryptoStandard]::CMS ) # Enable form flattening to lock all interactive fields $stamper.FormFlattening = $true # Cleanup resources $stamper.Close() $reader.Close() $outputStream.Dispose()
2. Sign with P12 Certificate File
Loads a certificate from a .p12/.pfx file and signs the PDF.
# Load assemblies Add-Type -Path "$ScriptDirectory\data\lib\itextsharp.dll" Add-Type -Path "$ScriptDirectory\data\lib\BouncyCastle.Crypto.dll" # Configuration $PdfFilePath = "$ScriptDirectory\Test_IN.pdf" $NewPdfFilePath = $PdfFilePath -replace '\.pdf$', '_Sig.pdf' $SignatureFieldName = "doctor_signature" $P12FilePath = "$ScriptDirectory\mycert.p12" $P12Password = "your-password-here" # Load P12 certificate $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($P12FilePath, $P12Password, [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable) if (-not $cert) { Write-Error "Failed to load P12 certificate." exit 1 } # Initialize PDF reader and stamper $reader = New-Object iTextSharp.text.pdf.PdfReader($PdfFilePath) $outputStream = New-Object System.IO.FileStream($NewPdfFilePath, [System.IO.FileMode]::Create) $stamper = New-Object iTextSharp.text.pdf.PdfStamper($reader, $outputStream, [char]0, $true) # Configure signature appearance $signatureAppearance = $stamper.SignatureAppearance $signatureAppearance.SetVisibleSignature($SignatureFieldName) $signatureAppearance.Layer2Text = "Digitally signed via P12 file" $signatureAppearance.Reason = "Document authentication" $signatureAppearance.Location = "PowerShell Tool" $signatureAppearance.SignDate = [DateTime]::Now # Execute signature $privateKey = $cert.PrivateKey $chain = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2Collection($cert) [iTextSharp.text.pdf.security.MakeSignature]::SignDetached( $signatureAppearance, $privateKey, $chain, $null, $null, $null, 0, [iTextSharp.text.pdf.security.CryptoStandard]::CMS ) # Lock form fields $stamper.FormFlattening = $true # Cleanup $stamper.Close() $reader.Close() $outputStream.Dispose()
3. Plaintext Signature (Visual Only, No Cryptographic Signing)
Fills the signature field with static text and locks the form without digital signing.
Add-Type -Path "$ScriptDirectory\data\lib\itextsharp.dll" $PdfFilePath = "$ScriptDirectory\Test_IN.pdf" $NewPdfFilePath = $PdfFilePath -replace '\.pdf$', '_Sig.pdf' $SignatureFieldName = "doctor_signature" $PlaintextSignature = "TestUser" $reader = New-Object iTextSharp.text.pdf.PdfReader($PdfFilePath) $outputStream = New-Object System.IO.FileStream($NewPdfFilePath, [System.IO.FileMode]::Create) $stamper = New-Object iTextSharp.text.pdf.PdfStamper($reader, $outputStream) # Fill signature field with plaintext $formFields = $stamper.AcroFields $formFields.SetField($SignatureFieldName, $PlaintextSignature) # Lock all form fields $stamper.FormFlattening = $true # Cleanup $stamper.Close() $reader.Close() $outputStream.Dispose()
Critical Notes
- BouncyCastle Dependency: iTextSharp requires
BouncyCastle.Crypto.dllfor cryptographic operations. Ensure this file exists in your lib directory. - Append Mode: Using
$trueas the fourth parameter inPdfStamperinitializes it in append mode, which prevents corruption of existing PDF content during signing. - Chilkat Locking Fix (Fallback): If you need to use Chilkat again, add
$pdf.SetFormFlattening($true)before callingSignPdfto lock form fields.
内容的提问来源于stack exchange,提问作者Guest
相关产品推荐
相关产品推荐

