移动签名问题。文档自创建以来已被更改或损坏

Mobile Signature problem. Document has been altered or corrupted since it was created

提问人:tolgahan özden 提问时间:11/4/2023 最后编辑:tolgahan özden 更新时间:11/4/2023 访问量:44

问:

我正在开发一个带有 .net 和 Itext 的移动签名应用程序。问题是当我将标志添加到pdf文件时,它说文档已更改。当我解析响应XML时,我可以获取用户证书和base64符号值。然后我用 itext 将其添加到 pdf 中,它说文档被更改或损坏。

public Envelope Imzala() {

        Byte[] bytes = null;
        PdfReader pdfReader = null;
        FileInfo fInfo = new FileInfo(@"C:\mobilimza\imzasiz.pdf");
        byte[] hashValue = null;
        using (SHA256 mySHA256 = SHA256.Create())
        {
            using (FileStream fileStream = fInfo.Open(FileMode.Open))
            {
                pdfReader = new PdfReader(fileStream);
                try
                {
                    fileStream.Position = 0;
                    hashValue = mySHA256.ComputeHash(fileStream);


                }
                catch (IOException e)
                {
                    Console.WriteLine($"I/O Exception: {e.Message}");
                }
            }
        }
        bytes = hashValue;
        DataToBeSigned = Convert.ToBase64String(bytes);

        string soapResult = string.Empty;
        XmlDocument responseXML = new XmlDocument();
        try
        {
            WebRequest webRequest = CreateWebRequest(GlobalParameters.imzaServisLink);
            XmlDocument soapEnvelopeXml = new XmlDocument();



            string xml1 = @""// my sign request;


            soapEnvelopeXml.LoadXml(xml1);
            using (Stream stream = webRequest.GetRequestStream())
            {
                soapEnvelopeXml.Save(stream);
            }
            using (WebResponse response = webRequest.GetResponse())
            {


                using (StreamReader rd = new StreamReader(response.GetResponseStream()))
                {
                    soapResult = rd.ReadToEnd();
                    Envelope envelope;
                    var mySerializer = new XmlSerializer(typeof(Envelope));
                    using (TextReader reader = new StringReader(soapResult))
                    {
                        envelope = (Envelope)mySerializer.Deserialize(reader);

                        string base64sign = envelope.Body.MSS_SignatureResponse.MSS_SignatureResp.MSS_Signature.Base64Signature;

                        byte[] data = Convert.FromBase64String(base64sign);

                        string decodedText = "<Root>" + Encoding.UTF8.GetString(data) + "</Root>";

                        XmlDocument xmlDoc = new XmlDocument();
                        xmlDoc.LoadXml(decodedText);


                        XmlElement keyInfoElement = (XmlElement)xmlDoc.SelectSingleNode("//KeyInfo");
                        XmlElement x509CertificateElement = (XmlElement)keyInfoElement.SelectSingleNode(".//X509Certificate");

                        XmlElement signvalue = (XmlElement)xmlDoc.SelectSingleNode(".//SignatureValue");

                        if (x509CertificateElement != null)
                        {
                            string x509CertificateText = x509CertificateElement.InnerText;
                            string signText = signvalue.InnerText;
                            byte[] x509data = Convert.FromBase64String(x509CertificateText);
                            X509Certificate2 x509 = new(x509data);

                            PdfWriter pdfWriter = new PdfWriter(@"c:\mobilimza\imzali.pdf");

                            StampingProperties sp = new StampingProperties();
                            sp.UseAppendMode();
                            PdfSigner pdfSigner = new PdfSigner(pdfReader, pdfWriter, sp);

                            PdfSignatureAppearance appearance = pdfSigner.GetSignatureAppearance();

                            //pdfSigner.SetFieldName("Signature");
                            //appearance.SetPageNumber(1);

                            // Set the X.509 certificate chain
                            X509CertificateParser parser = new X509CertificateParser();
                            Org.BouncyCastle.X509.X509Certificate[] chain = new Org.BouncyCastle.X509.X509Certificate[] { DotNetUtilities.FromX509Certificate(x509) };

                            pdfSigner.SignDetached(new CustomExternalSignature1(Convert.FromBase64String(signText)), chain, null, null, null, 0, PdfSigner.CryptoStandard.CMS);

                        }

                        return envelope;
                    }


                }


            }
        }
        catch (Exception ee)
        {
            throw;
        }
    }

错误

C# 数字签名 iText7

评论

0赞 mkl 11/5/2023
为原始 pdf 添加签名。这是错误的做法。PDF 签名要求首先准备文档进行签名(特别是为新签名添加占位符及其某些换行),然后对准备好的 pdf 进行哈希处理(占位符间隙除外),为该哈希创建签名值,并嵌入该签名值。
0赞 tolgahan özden 11/6/2023
我已经尝试准备文档进行签名,但我无法找到解决方案。我如何为原始 pdf 添加必要的间隙?
0赞 mkl 11/10/2023
我只是想写一个答案,但查看您的代码的详细信息,我意识到存在一个问题:您在同一响应中检索证书 () 和签名 ()。但是,对于许多签名容器配置文件,在生成要签名的数据时,您已经需要证书。因此,您的签名服务是否允许在实际签名创建调用之前在单独的调用中检索证书?x509CertificateElementsignvalue
0赞 tolgahan özden 11/12/2023
是的,MSSP 服务有一个 profilequery 服务。响应具有 CertIssuerDN、CertSerialNumber、DigestMethod、DigestValue 和 certIssuerDN-DER。但是我无法弄清楚如何从这个值构造X509certificate对象。

答: 暂无答案