使用 iText 和 nexU 延迟 pdf 签名

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

我正在尝试按照欧洲委员会数字签名服务实施将 Web 浏览器中的客户端 pdf 签名与 iText 8 集成(可以在此处找到演示 Web 应用程序 https://ec.europa.eu/digital-building-blocks/ DSS/webapp-demo/sign-a-pdf,源代码可在此处获取https://github.com/esig/dss-demonstrations/tree/master/dss-demo-webapp)。

此实现使用桌面签名工具 NexU,该工具公开 REST API 来与客户端证书进行交互。根据我收集的信息,它会执行延迟签名(它准备 pdf 文档,将哈希值发送回客户端,客户端将其发送到 NexU 进行签名,然后返回到服务器以将签名添加到 pdf 文件中)。

表单将文件发布到服务器,然后遵循 NexU 流程 https://github.com/esig/dss-demonstrations/blob/master/dss-demo-webapp/src/main/webapp/WEB-INF /thymeleaf/nexu-signature-process.html(客户端)和https://github.com/esig/dss-demonstrations/blob/master/dss-demo-webapp/src/main/java/eu/europa/ esig/dss/web/controller/SignaturePdfController.java(服务器)

我正在尝试使用与此处相同的流程来复制相同的流程iTextSharp - 如何获取 PDF 内容进行签名,然后稍后签名

 public static byte[] GetBytesToSign(List<byte[]> chain)
        {
            using (var reader = new PdfReader(@"C:\sample.pdf"))
            {
                var x509 = new X509Certificate2(chain[0]);
                var cert = new X509CertificateParser().ReadCertificate(x509.GetRawCertData());

                PdfSigner2 signer = new PdfSigner2(reader, new FileStream("D:\\test.pdf", FileMode.Create), new StampingProperties());
                PdfSignatureAppearance appearance = signer.GetSignatureAppearance();
                appearance
                        .SetPageRect(new Rectangle(36, 748, 200, 100))
                        .SetPageNumber(1)
                .SetCertificate(new X509CertificateBC(cert));

                signer.SetFieldName("sig");

                /* ExternalBlankSignatureContainer constructor will create the PdfDictionary for the signature
                 * information and will insert the /Filter and /SubFilter values into this dictionary.
                 * It will leave just a blank placeholder for the signature that is to be inserted later.
                 */
                IExternalSignatureContainer external = new ExternalBlankSignatureContainer(PdfName.Adobe_PPKLite,
                        PdfName.Adbe_pkcs7_detached);

                // Sign the document using an external container.
                // 8192 is the size of the empty signature placeholder.
                signer.SignExternalContainer(external, 8192);
                byte[] hash = DigestAlgorithms.Digest(signer.GetNewRangeStream(), "SHA256");
                return hash;
            }
        }

        public static void EmbedSignature(string signatureFieldName, byte[] signedBytes)
        {
            using (PdfReader reader = new PdfReader("D:\\test.pdf"))
            {
                using (FileStream os = new FileStream("D:\\test-signed.pdf", FileMode.Create))
                {
                    PdfSigner signer = new PdfSigner(reader, os, new StampingProperties());

                    
                    IExternalSignatureContainer external = new MyExternalSignatureContainer(signedBytes);

                    // Signs a PDF where space was already reserved. The field must cover the whole document.
                    PdfSigner.SignDeferred(signer.GetDocument(), signatureFieldName, os, external);
                }
            }
        }

        private class MyExternalSignatureContainer : IExternalSignatureContainer
        {
            private readonly byte[] signedBytes;

            public MyExternalSignatureContainer(byte[] signedBytes)
            {
                this.signedBytes = signedBytes;
            }

            public byte[] Sign(Stream data)
            {
                return signedBytes;
            }

            public void ModifySigningDictionary(PdfDictionary signDic)
            {
            }
        }

PdfSigner2 是 PdfSigner 的子级,因此我可以将受保护的 GetRangeStream() 调用为 GetNewRangeStream()。

我面临的问题是生成的pdf没有有效的签名(Adobe说BER解码错误)。从头开始比较,我注意到使用 GetBytesToSign 返回的哈希值与演示 Web 应用程序中的 getDataToSign 方法返回的哈希值非常不同。

GetBytesToSign 返回的哈希mzxCQT030gx2DAFb+AmU7Vq4F+rFlkm8+AwlBT54mxw=

getDataToSign 返回的哈希值

MYH7MBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwLwYJKoZIhvcNAQkEMSIEIGqOoVxG7wK2ipK+1GYavLGSy9TI5yRH+fowIKpTm2uSMIGtBgsqhkiG9w0BCRACLzGBnTCBmjC BLZCBlAQgl7+3/3JM2gFd0RDTmxbtLLHqzppW6bvAyt0dJl30XRowcDBgpF4wXDELMAkGA1UEBhMCUk8xFDASBgNVBAoTC0NFUlRTSUdOIFNBMR4wHAYDVQQDExVjZXJ0U0lHTiBRdWFsaWZpZWQgQ0ExFzAV BgNVBGETDlZBVFJPLTE4Mjg4MjUwAgwiDVS0PlmQu/IQU+A=

是否可以以与iText相同的格式返回哈希值?

c# .net itext digital-signature
1个回答
0
投票
GetBytesToSign 返回的哈希值

它是一个固定大小的

SHA256

哈希值

getDataToSign 返回的哈希值

它实际上是一个要进行哈希和签名的字节数组。您需要对这些字节进行哈希处理才能获得与

GetBytesToSign

 相同的输出
    

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