iTextSharp 5 多重签名 - 最后一个签名使以前的签名无效 - 文档已被更改或损坏
iTextSharp 5 multiple signatures - last signature renders previous signatures invalid - Document has been altered or corrupted
我正在尝试使用 iTextSharp 5.5.13.1 添加多个签名。
只有最后一个签名有效。
所有以前的签名都对消息无效:
"Document has been altered or corrupted since it was signed" - 1 页已修改
我不一定需要经过认证的签名。
我使用签名附加模式,但仍然无法弄清楚是什么修改了文档。
在记事本中,文档的第一部分直到第二个签名似乎没有变化。
我使用的代码是:
private string SignFile(string fileToSign, string certname, float xPercent, float yPercent, int page)
{
string signedFile = fileToSign.Replace(".pdf", ".signed.pdf");
using (PdfReader pdfReader = new PdfReader(fileToSign))
{
int pages = pdfReader.NumberOfPages;
var currentSignaturesCount = pdfReader.AcroFields.GetSignatureNames().Count();
using (FileStream signedPdf = new FileStream(signedFile, FileMode.Create, FileAccess.ReadWrite))
{
string tempDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), ".tempfiles");
Directory.CreateDirectory(tempDir);
string tempFileName = Path.Combine(tempDir, Guid.NewGuid().ToString("N") + ".pdf");
if (!File.Exists(tempFileName))
File.Create(tempFileName).Close();
using (PdfStamper pdfStamper = PdfStamper.CreateSignature(pdfReader, signedPdf, '[=10=]', tempFileName, true)) // Append mode
{
// Add signature image
if (page <= pages && page > 0)
{
var pdfContentByte = pdfStamper.GetOverContent(page);
var pageSize = pdfReader.GetPageSize(i);
float pageWidth = pageSize.Width;
float pageHeight = pageSize.Height;
// GenerateStamp() = simplified function that will get a custom bitmap (code not included here)
System.Drawing.Bitmap img = GenerateStamp();
var image = iTextSharp.text.Image.GetInstance(img, true);
image.SetAbsolutePosition(xPercent * pageWidth, pageHeight - yPercent * pageHeight - image.ScaledHeight);
pdfContentByte.AddImage(image);
}
//Also tried adding the image directly to signatureAppearance
//signatureAppearance.SignatureGraphic = image;
//signatureAppearance.SetVisibleSignature(rectangle, page, signatureFieldName);
// and getting the error "Document has been altered or corrupted since it was signed"
PdfSignatureAppearance signatureAppearance = pdfStamper.SignatureAppearance;
signatureAppearance.Reason = "Test";
signatureAppearance.SignDate = DateTime.Now;
signatureAppearance.SignatureRenderingMode = PdfSignatureAppearance.RenderingMode.GRAPHIC;
signatureAppearance.Acro6Layers = false;
//Also tried like this:
//signatureAppearance.CertificationLevel = currentSignaturesCount == 0 ? PdfSignatureAppearance.CERTIFIED_FORM_FILLING_AND_ANNOTATIONS : PdfSignatureAppearance.NOT_CERTIFIED;
// with message: "There have been changes made to this document that invalidate the signature"
// sign document
try
{
X509Certificate2 cert = GetCertificateByName(certname);
Org.BouncyCastle.X509.X509CertificateParser cp = new Org.BouncyCastle.X509.X509CertificateParser();
Org.BouncyCastle.X509.X509Certificate[] chain = new Org.BouncyCastle.X509.X509Certificate[] { cp.ReadCertificate(cert.RawData) };
IExternalSignature externalSignature = new X509Certificate2Signature(cert, "SHA-256");
MakeSignature.SignDetached(signatureAppearance, externalSignature, chain, null, null, null, 0, CryptoStandard.CMS);
}
catch (Exception ex)
{
throw;
}
}
}
}
return signedFile;
}
感谢任何帮助。谢谢
您的代码按原样将图像添加到页面的静态内容中。禁止对签名文件执行此操作。有关允许和不允许更改已签名 PDF 的详细信息,请阅读 this answer。
不过,根据您的代码注释,您还尝试将图像添加到签名外观中。这并不是被禁止的。但是通过分析提供的示例 PDF 可以明显看出,在这次尝试中,额外的内容流已添加到页面中。即使它们本质上是空的,这也被认为是不允许的页面内容更改。
事实证明,您没有在本次尝试中将图像添加到页面内容中,但您仍然检索了页面的 OverContent
:
var pdfContentByte = pdfStamper.GetOverContent(page);
此操作已将额外的内容流添加到页面,以便出现 OverContent。因此,严格来说,该方法应该命名为 CreateOrGetOverContent
而不是...
删除后 GetOverContent
调用签名不再破坏以前的签名。
我正在尝试使用 iTextSharp 5.5.13.1 添加多个签名。
只有最后一个签名有效。
所有以前的签名都对消息无效:
"Document has been altered or corrupted since it was signed" - 1 页已修改
我不一定需要经过认证的签名。
我使用签名附加模式,但仍然无法弄清楚是什么修改了文档。
在记事本中,文档的第一部分直到第二个签名似乎没有变化。
我使用的代码是:
private string SignFile(string fileToSign, string certname, float xPercent, float yPercent, int page)
{
string signedFile = fileToSign.Replace(".pdf", ".signed.pdf");
using (PdfReader pdfReader = new PdfReader(fileToSign))
{
int pages = pdfReader.NumberOfPages;
var currentSignaturesCount = pdfReader.AcroFields.GetSignatureNames().Count();
using (FileStream signedPdf = new FileStream(signedFile, FileMode.Create, FileAccess.ReadWrite))
{
string tempDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), ".tempfiles");
Directory.CreateDirectory(tempDir);
string tempFileName = Path.Combine(tempDir, Guid.NewGuid().ToString("N") + ".pdf");
if (!File.Exists(tempFileName))
File.Create(tempFileName).Close();
using (PdfStamper pdfStamper = PdfStamper.CreateSignature(pdfReader, signedPdf, '[=10=]', tempFileName, true)) // Append mode
{
// Add signature image
if (page <= pages && page > 0)
{
var pdfContentByte = pdfStamper.GetOverContent(page);
var pageSize = pdfReader.GetPageSize(i);
float pageWidth = pageSize.Width;
float pageHeight = pageSize.Height;
// GenerateStamp() = simplified function that will get a custom bitmap (code not included here)
System.Drawing.Bitmap img = GenerateStamp();
var image = iTextSharp.text.Image.GetInstance(img, true);
image.SetAbsolutePosition(xPercent * pageWidth, pageHeight - yPercent * pageHeight - image.ScaledHeight);
pdfContentByte.AddImage(image);
}
//Also tried adding the image directly to signatureAppearance
//signatureAppearance.SignatureGraphic = image;
//signatureAppearance.SetVisibleSignature(rectangle, page, signatureFieldName);
// and getting the error "Document has been altered or corrupted since it was signed"
PdfSignatureAppearance signatureAppearance = pdfStamper.SignatureAppearance;
signatureAppearance.Reason = "Test";
signatureAppearance.SignDate = DateTime.Now;
signatureAppearance.SignatureRenderingMode = PdfSignatureAppearance.RenderingMode.GRAPHIC;
signatureAppearance.Acro6Layers = false;
//Also tried like this:
//signatureAppearance.CertificationLevel = currentSignaturesCount == 0 ? PdfSignatureAppearance.CERTIFIED_FORM_FILLING_AND_ANNOTATIONS : PdfSignatureAppearance.NOT_CERTIFIED;
// with message: "There have been changes made to this document that invalidate the signature"
// sign document
try
{
X509Certificate2 cert = GetCertificateByName(certname);
Org.BouncyCastle.X509.X509CertificateParser cp = new Org.BouncyCastle.X509.X509CertificateParser();
Org.BouncyCastle.X509.X509Certificate[] chain = new Org.BouncyCastle.X509.X509Certificate[] { cp.ReadCertificate(cert.RawData) };
IExternalSignature externalSignature = new X509Certificate2Signature(cert, "SHA-256");
MakeSignature.SignDetached(signatureAppearance, externalSignature, chain, null, null, null, 0, CryptoStandard.CMS);
}
catch (Exception ex)
{
throw;
}
}
}
}
return signedFile;
}
感谢任何帮助。谢谢
您的代码按原样将图像添加到页面的静态内容中。禁止对签名文件执行此操作。有关允许和不允许更改已签名 PDF 的详细信息,请阅读 this answer。
不过,根据您的代码注释,您还尝试将图像添加到签名外观中。这并不是被禁止的。但是通过分析提供的示例 PDF 可以明显看出,在这次尝试中,额外的内容流已添加到页面中。即使它们本质上是空的,这也被认为是不允许的页面内容更改。
事实证明,您没有在本次尝试中将图像添加到页面内容中,但您仍然检索了页面的 OverContent
:
var pdfContentByte = pdfStamper.GetOverContent(page);
此操作已将额外的内容流添加到页面,以便出现 OverContent。因此,严格来说,该方法应该命名为 CreateOrGetOverContent
而不是...
删除后 GetOverContent
调用签名不再破坏以前的签名。