如何在一个PDF页面中添加多个签名

问题描述 投票:0回答:1

我在.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 对象的附加模式,但遇到了同样的问题

java itext itext7
1个回答
0
投票

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
也可能会导致验证问题。

© www.soinside.com 2019 - 2024. All rights reserved.