数字签名添加新签名使旧签名无效

发布于 2025-02-01 13:04:54 字数 4884 浏览 2 评论 0原文

我正在尝试在单个PDF文件中添加多个数字签名。

这是成功的,但是该程序添加了一个新的签名的时间,Adobe Reader现在将旧签名视为无效。

我所做的只是调用signer.sign()方法来执行多个签名,我不知道这是否是正确的方法。

请参阅图像,请参见图像。例如PDF签名输出< /strong>

“在此处输入图像描述”

以下是我的代码

public class Signer
{
    private readonly string source;
    private readonly string destination;

    private readonly Certificate certificate;

    public Signer(string source, string destination, Certificate certificate)
    {
        this.source =  source;
        this.destination = destination;
        this.certificate = certificate;
    }

    public void Sign(Signature signature, string hashAlgorithm, PdfSigner.CryptoStandard signatureType)
    {
        PdfReader reader = new(source);
        PdfSigner signer = new(reader, new FileStream(this.destination, FileMode.Create), new StampingProperties());

        PdfSignatureAppearance appearance = signer.GetSignatureAppearance();
        appearance.SetPageNumber(signature.PageNumber)
            .SetPageRect(signature.Bounds)
            .SetContact(signature.Contact)
            .SetLocation(signature.Location)
            .SetReason(signature.Reason)
            .SetSignatureGraphic(signature.Image)
            .SetRenderingMode(signature.RenderMode);
        signer.SetFieldName(signature.FieldName);

        IExternalSignature pks = new PrivateKeySignature(certificate.Key, hashAlgorithm);
        signer.SignDetached(pks, certificate.Chain, null, null, null, 0, signatureType);
        
        reader.Close();
    }

    public class Certificate
    {
        private readonly X509Certificate[] chain;
        private readonly ICipherParameters key;

        public X509Certificate[] Chain
        {
            get { return chain; }
        }

        public ICipherParameters Key
        {
            get { return key; }
        }

        public Certificate(string keystore, string password)
        {
            Pkcs12Store pk12 = new(new FileStream(keystore, FileMode.Open, FileAccess.Read), password.ToCharArray());
            string? alias = null;
            foreach (object a in pk12.Aliases)
            {
                alias = ((string)a);
                if (pk12.IsKeyEntry(alias))
                {
                    break;
                }
            }
            key = pk12.GetKey(alias).Key;

            X509CertificateEntry[] ce = pk12.GetCertificateChain(alias);
            chain = new X509Certificate[ce.Length];
            for (int k = 0; k < ce.Length; ++k)
            {
                chain[k] = ce[k].Certificate;
            }
        }
    }

    public class Signature
    {
        private readonly string fieldName;
        private readonly int pageNumber;
        
        public string FieldName { 
            get { return fieldName; }
        }
        public int PageNumber {
            get { return pageNumber; }
        }

        public string Contact { get; set; } = String.Empty;
        public string Reason { get; set; } = String.Empty;
        public string Location { get; set; } = String.Empty;
        public RenderingMode RenderMode { get; set; } = RenderingMode.GRAPHIC;

        public Rectangle? Bounds { get; set; }
        public ImageData? Image { get; set; }

        public Signature(string fieldName, int pageNumber)
        {
            this.fieldName = fieldName;
            this.pageNumber = pageNumber;
        }
    }
}

实施

    public static void Sign()
    {
        string source = "V06.pdf";
        string destination1 = "V06.signed1.pdf";
        string destination2 = "V06.signed2.pdf";
        Certificate certificate = new("121550.p12", "password");
        
        Signer sign1 = new(source, destination1, certificate);

        Signature signature1 = new("Sign1", 1)
        {
            RenderMode = RenderingMode.GRAPHIC,
            Contact = "000000",
            Location = "PH",
            Reason = "Valid",
            Bounds = new Rectangle(70, 148, 100, 35),
            Image = ImageDataFactory.Create("Untitled.png")
        };
        sign1.Sign(signature1, DigestAlgorithms.SHA256, PdfSigner.CryptoStandard.CMS);



        Signer sign2 = new(destination1, destination2, certificate);
        
        Signature signature2 = new("Sign2", 1)
        {
            RenderMode = RenderingMode.GRAPHIC,
            Contact = "000000",
            Location = "PH",
            Reason = "OK",
            Bounds = new Rectangle(170, 148, 100, 35),
            Image = ImageDataFactory.Create("Untitled.png")
        };

        sign2.Sign(signature2, DigestAlgorithms.SHA256, PdfSigner.CryptoStandard.CMS);
    }

I am trying to add multiple digital signature in a single PDF file.

It was successful but the time the program added a new signature, old ones is now detected by Adobe reader as invalid.

What I did is just call the Signer.Sign() method to do the multiple signing, I do not know if this is the right way to do.

See image for example PDF Signature output

enter image description here

Below is my code

public class Signer
{
    private readonly string source;
    private readonly string destination;

    private readonly Certificate certificate;

    public Signer(string source, string destination, Certificate certificate)
    {
        this.source =  source;
        this.destination = destination;
        this.certificate = certificate;
    }

    public void Sign(Signature signature, string hashAlgorithm, PdfSigner.CryptoStandard signatureType)
    {
        PdfReader reader = new(source);
        PdfSigner signer = new(reader, new FileStream(this.destination, FileMode.Create), new StampingProperties());

        PdfSignatureAppearance appearance = signer.GetSignatureAppearance();
        appearance.SetPageNumber(signature.PageNumber)
            .SetPageRect(signature.Bounds)
            .SetContact(signature.Contact)
            .SetLocation(signature.Location)
            .SetReason(signature.Reason)
            .SetSignatureGraphic(signature.Image)
            .SetRenderingMode(signature.RenderMode);
        signer.SetFieldName(signature.FieldName);

        IExternalSignature pks = new PrivateKeySignature(certificate.Key, hashAlgorithm);
        signer.SignDetached(pks, certificate.Chain, null, null, null, 0, signatureType);
        
        reader.Close();
    }

    public class Certificate
    {
        private readonly X509Certificate[] chain;
        private readonly ICipherParameters key;

        public X509Certificate[] Chain
        {
            get { return chain; }
        }

        public ICipherParameters Key
        {
            get { return key; }
        }

        public Certificate(string keystore, string password)
        {
            Pkcs12Store pk12 = new(new FileStream(keystore, FileMode.Open, FileAccess.Read), password.ToCharArray());
            string? alias = null;
            foreach (object a in pk12.Aliases)
            {
                alias = ((string)a);
                if (pk12.IsKeyEntry(alias))
                {
                    break;
                }
            }
            key = pk12.GetKey(alias).Key;

            X509CertificateEntry[] ce = pk12.GetCertificateChain(alias);
            chain = new X509Certificate[ce.Length];
            for (int k = 0; k < ce.Length; ++k)
            {
                chain[k] = ce[k].Certificate;
            }
        }
    }

    public class Signature
    {
        private readonly string fieldName;
        private readonly int pageNumber;
        
        public string FieldName { 
            get { return fieldName; }
        }
        public int PageNumber {
            get { return pageNumber; }
        }

        public string Contact { get; set; } = String.Empty;
        public string Reason { get; set; } = String.Empty;
        public string Location { get; set; } = String.Empty;
        public RenderingMode RenderMode { get; set; } = RenderingMode.GRAPHIC;

        public Rectangle? Bounds { get; set; }
        public ImageData? Image { get; set; }

        public Signature(string fieldName, int pageNumber)
        {
            this.fieldName = fieldName;
            this.pageNumber = pageNumber;
        }
    }
}

Implementation

    public static void Sign()
    {
        string source = "V06.pdf";
        string destination1 = "V06.signed1.pdf";
        string destination2 = "V06.signed2.pdf";
        Certificate certificate = new("121550.p12", "password");
        
        Signer sign1 = new(source, destination1, certificate);

        Signature signature1 = new("Sign1", 1)
        {
            RenderMode = RenderingMode.GRAPHIC,
            Contact = "000000",
            Location = "PH",
            Reason = "Valid",
            Bounds = new Rectangle(70, 148, 100, 35),
            Image = ImageDataFactory.Create("Untitled.png")
        };
        sign1.Sign(signature1, DigestAlgorithms.SHA256, PdfSigner.CryptoStandard.CMS);



        Signer sign2 = new(destination1, destination2, certificate);
        
        Signature signature2 = new("Sign2", 1)
        {
            RenderMode = RenderingMode.GRAPHIC,
            Contact = "000000",
            Location = "PH",
            Reason = "OK",
            Bounds = new Rectangle(170, 148, 100, 35),
            Image = ImageDataFactory.Create("Untitled.png")
        };

        sign2.Sign(signature2, DigestAlgorithms.SHA256, PdfSigner.CryptoStandard.CMS);
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

生来就爱笑 2025-02-08 13:04:54

如果您使用的是Itext 7,我想您应该尝试使用useappendmode()

PdfSigner signer = new PdfSigner(reader, new FileStream(dest, FileMode.Create), tmp, new StampingProperties().UseAppendMode());

请参阅 https:// stackoverflow.com/a/64386351/6235557

If you are using iText 7, I guess you should try using UseAppendMode()

PdfSigner signer = new PdfSigner(reader, new FileStream(dest, FileMode.Create), tmp, new StampingProperties().UseAppendMode());

Please refer to https://stackoverflow.com/a/64386351/6235557

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文