我在.net中使用itext7来处理PDF页面上的电子签名,我使用下面的代码,它可以很好地进行一次性签名。但是我想在一页中添加 3 个签名,然后出现错误“iText.Kernel.Exceptions.PdfException:'文档已关闭。无法执行操作。'” 请帮忙协助如何在一页pdf中添加一个签名
public void sign()
{
string KEYSTORE = @"D:\resources\cert.pfx";
char[] PASSWORD = "password".ToCharArray();
Pkcs12Store pk12 = new Pkcs12Store(new FileStream(KEYSTORE, FileMode.Open, FileAccess.Read), PASSWORD);
string alias = null;
foreach (object a in pk12.Aliases)
{
alias = ((string)a);
if (pk12.IsKeyEntry(alias))
{
break;
}
}
ICipherParameters pk = pk12.GetKey(alias).Key;
X509CertificateEntry[] ce = pk12.GetCertificateChain(alias);
IX509Certificate[] chain = new IX509Certificate[ce.Length];
for (int k = 0; k < ce.Length; ++k)
{
chain[k] = new X509CertificateBC(ce[k].Certificate);
}
string DEST = "D:\\resources\\PR_signed.pdf";
string SRC = "D:\\resources\\PR.pdf";
Rectangle requesterPosition = new Rectangle(10, 140, 130, 180);
Rectangle headOfPosition = new Rectangle(160, 140, 300, 180);
PdfReader reader = new PdfReader(SRC);
PdfSigner signer = new PdfSigner(reader, new FileStream(DEST, FileMode.Create),
new StampingProperties().PreserveEncryption().UseAppendMode());
string sig1 = "req";
string sig2 = "scm";
// sign document for first time
signDetail( signer, chain, pk, sig1, requesterPosition);
// sign document for second time
signDetail(signer, chain, pk, sig2, headOfPosition);
}
public void signDetail(PdfSigner signer, IX509Certificate[] chain, ICipherParameters pk, string sigName, Rectangle rect)
{
// Set signer options
signer.SetFieldName(signer.GetNewSigFieldName());
signer.SetCertificationLevel(PdfSigner.CERTIFIED_FORM_FILLING_AND_ANNOTATIONS);
PdfSignatureAppearance appearance = signer.GetSignatureAppearance();
appearance.SetReason("test signature")
.SetLocation("VN")
.SetPageRect(rect)
.SetPageNumber(1);
IExternalSignature pks = new PrivateKeySignature(new PrivateKeyBC(pk), DigestAlgorithms.SHA256);
// Sign the document using the detached mode, CMS or CAdES equivalent.
signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CMS);
}
我尝试启用 StampingProperties 对象的附加模式,但遇到了同样的问题
PdfSigner
(或更准确地说,底层的PdfDocument
)在每次签名过程后都会关闭(在您的情况下,在 signer.SignDetached
调用之后)。
要添加多个签名,您必须每次打开一个新的签名者,例如这样
string INT = "D:\\resources\\PR_intermediate.pdf";
string sig1 = "req";
string sig2 = "scm";
// sign document for first time
PdfReader reader = new PdfReader(SRC);
PdfSigner signer = new PdfSigner(reader, new FileStream(INT, FileMode.Create),
new StampingProperties().PreserveEncryption().UseAppendMode());
signDetail( signer, chain, pk, sig1, requesterPosition);
// sign document for second time
reader = new PdfReader(INT);
signer = new PdfSigner(reader, new FileStream(INT, FileMode.Create),
new StampingProperties().PreserveEncryption().UseAppendMode());
signDetail(signer, chain, pk, sig2, headOfPosition);
顺便说一句,只有 PDF 中的第一个签名才可以是认证签名。对第二个使用
SetCertificationLevel
也可能会导致验证问题。