使用iText创建具有完整外观的签名

本文关键字:外观 iText 创建 使用 | 更新日期: 2023-09-27 18:22:01

我需要创建签名,它只包含签名名称和日期。此外,由于这两个字段必须放置在预定义的"修订表"中,因此这两个域必须放置在精确的坐标处。

这可能吗?

这是我的代码,它与Bruno Lowagie的样本非常(!)相似,可能甚至不接近问题的解决方案:

namespace signatures.chapter3 {
    public class C3_11_SignWithToken
    {
        public static String SRC = "../../../../resources/hello.pdf";
        public static String DEST = "../../../../results/chapter3/hello_token.pdf";
        public void Sign(String src, String dest,
                         ICollection<X509Certificate> chain, X509Certificate2 pk,
                         String digestAlgorithm, CryptoStandard subfilter,
                         String reason, String location,
                         ICollection<ICrlClient> crlList,
                         IOcspClient ocspClient,
                         ITSAClient tsaClient,
                         int estimatedSize)
        {
            // Creating the reader and the stamper
            PdfReader reader = null;
            PdfStamper stamper = null;
            FileStream os = null;
            try
            {
                reader = new PdfReader(src);
                os = new FileStream(dest, FileMode.Create);
                // os = new FileStream(dest, FileMode.Create, FileAccess.Write);
                //Activate MultiSignatures
                stamper = PdfStamper.CreateSignature(reader, os, ''0', null, true);
                //To disable Multi signatures uncomment this line : every new signature will invalidate older ones !
                //stamper = PdfStamper.CreateSignature(reader, os, ''0');

                // Creating the appearance
                PdfSignatureAppearance appearance = stamper.SignatureAppearance;
                //appearance.Location = location;
                //appearance.SetVisibleSignature(new Rectangle(36, 612, 144, 644), 1, "sig4");
                appearance.Reason = "marked as changed";
                appearance.Location = location;
                //appearance.SetVisibleSignature("Reason");
                appearance.Layer2Text = "Signed on " + DateTime.Now;
                appearance.SignatureRenderingMode = PdfSignatureAppearance.RenderingMode.DESCRIPTION;

                // Creating the signature
                IExternalSignature pks = new X509Certificate2Signature(pk, digestAlgorithm);
                MakeSignature.SignDetached(appearance, pks, chain, crlList, ocspClient, tsaClient, estimatedSize, subfilter);
            }
            catch (Exception ex) {
                Console.WriteLine("GMA: " + ex.Message);
            }
            finally
            {
                if (reader != null)
                    reader.Close();
                if (stamper != null)
                    stamper.Close();
                if (os != null)
                    os.Close();
            }
        }
    }

非常感谢!

使用iText创建具有完整外观的签名

谢谢@mkl。你的提示很有帮助,解决了这个问题。这是我的代码,它的工作方式很有魅力:

public class SignWithToken   {
    public void Sign(String src, String dest,
                     ICollection<X509Certificate> chain, X509Certificate2 pk,
                     String digestAlgorithm, CryptoStandard subfilter,
                     String reason, String location,
                     ICollection<ICrlClient> crlList,
                     IOcspClient ocspClient,
                     ITSAClient tsaClient,
                     int estimatedSize, int RowIdx, int RowHeight, int x, int y, int NameWidth, int DateWidth, 
                     String RevIndex, String RevStep, String Reason, String Name, String Date)
    {
        // Creating the reader and the stamper
        PdfReader reader = null;
        PdfStamper stamper = null;
        FileStream os = null;
        try
        {
            reader = new PdfReader(src);
            os = new FileStream(dest, FileMode.Create);
            // os = new FileStream(dest, FileMode.Create, FileAccess.Write);
            //Activate MultiSignatures
            stamper = PdfStamper.CreateSignature(reader, os, ''0', null, true);
            //To disable Multi signatures uncomment this line : every new signature will invalidate older ones !
            //stamper = PdfStamper.CreateSignature(reader, os, ''0');

            // Creating the appearance
            PdfSignatureAppearance appearance = stamper.SignatureAppearance;
            Rectangle rectangle = new Rectangle(x, y + RowIdx * RowHeight, x + NameWidth + DateWidth, y + (RowIdx+1) * RowHeight);
            appearance.SetVisibleSignature(rectangle, 1, "Revision " + RevIndex + "|" + RevStep);
            appearance.Reason = "marked as changed";
            appearance.Location = location;
            appearance.Layer2Text = "Signed on " + DateTime.Now;
            appearance.SignatureRenderingMode = PdfSignatureAppearance.RenderingMode.DESCRIPTION;
            PdfTemplate n2 = appearance.GetLayer(2);
            Font font = new Font();
            font.SetColor(255, 0, 0);
            font.Size = 10;
            ColumnText ct1 = new ColumnText(n2);
            ct1.SetSimpleColumn(new Phrase(Name, font), 0, 0, NameWidth, rectangle.Height, 15, Element.ALIGN_LEFT);
            ct1.Go();
            ColumnText ct2 = new ColumnText(n2);
            ct2.SetSimpleColumn(new Phrase(Date, font), NameWidth, 0, rectangle.Width, rectangle.Height, 15, Element.ALIGN_LEFT);
            ct2.Go();
            //n2.ConcatCTM(1, 0, 0, -1, 0, 0);
            //n2.SaveState();
            // Creating the signature
            IExternalSignature pks = new X509Certificate2Signature(pk, digestAlgorithm);
            MakeSignature.SignDetached(appearance, pks, chain, crlList, ocspClient, tsaClient, estimatedSize, subfilter);
        }
        catch (Exception ex)
        {
            Console.WriteLine("GMA: " + ex.Message);
        }
        finally
        {
            if (reader != null)
                reader.Close();
            if (stamper != null)
                stamper.Close();
            if (os != null)
                os.Close();
        }
    }
}