0

这是一个我很难应对的场景。我们希望我们的供应商能够使用 LTV 签名签署 PDF 文档,这样文档的有效性就不会过期。我已经阅读了 Bruno Lowagie 的著作iText in Action(第 2 版)、他的白皮书PDF 文档的数字签名,并查看了 PAdES 配置文件(PDF 文档的数字签名)。

用户使用具有电子 ID 的手机签署文件。该程序基本上将哈希发送到第三方服务,该服务对其进行签名并发回给我们,我们使用该签名并将其放入 PDF 文件中。这很好用,但这个签名的有效期只有三年左右。

我们如何在收到并添加签名后向 PDF 添加 DSS 和时间戳,以使用 iText 使 PDF 符合 PAdES LTV-Profile。我已经看到很多添加签名以及向它们添加时间戳和 OSCP 信息的示例,但这并不完全相同。

下面是一些代码,展示了我们从 preSign 和 postSign 方法开始所做的事情。这可行,但是如果可能的话,我应该在哪里以及如何添加代码来添加 DSS 和时间戳信息:

    /// <summary>
    /// Creates signature infrastructure to use in the signing process. Start with calling this method in the signature process.
    /// </summary>
    /// <param name="inStream">Byte stream with the PDF document to be signed</param>
    /// <param name="reason">The reason for the signing</param>
    /// <param name="location">Signing location</param>
    /// <returns>Returns a hash of the signed data</returns>
    public void preSign(byte[] inStream, string reason, string location)
    {
        iTextSharp.text.Document document = new iTextSharp.text.Document();

        // Lesum inn PDF skjalið sem á að undirrita inn í iText reader
        PdfReader reader = new PdfReader(inStream);
        reader.Appendable = true;
        Rectangle pageSize = reader.GetPageSizeWithRotation(1); 

        // Tengjum output stream við iText stamper
        _outstream = new MemoryStream();
        PdfStamper stamper = PdfStamper.CreateSignature(reader, _outstream, '\0', null, true);
        stamper.InsertPage(reader.NumberOfPages + 1, reader.GetPageSize(reader.NumberOfPages));

        _sap = stamper.SignatureAppearance;

        float llx = pageSize.Width/2 - 350/2;
        float lly = pageSize.Height/2 - 150/2;
        float urx = llx + 350;
        float ury = lly + 150;
        _sap.SetVisibleSignature(new iTextSharp.text.Rectangle(llx, lly, urx, ury), reader.NumberOfPages, null);
        _sap.Reason = reason;
        _sap.Location = location;
        _transactionTime = DateTime.Now;
        _sap.SignDate = _transactionTime;

        iTextSharp.text.Image img = iTextSharp.text.Image.GetInstance(AppDomain.CurrentDomain.BaseDirectory + "UndirskriftDemo.png");
        img.ScaleToFit(new Rectangle(350, 50));
        _sap.Image = img;

        _sap.Layer2Font = new iTextSharp.text.Font(iTextSharp.text.Font.FontFamily.TIMES_ROMAN, 10.0f, 0, iTextSharp.text.BaseColor.BLACK);
        _sap.Layer2Text = _userFullName + " undirritaði skjalið\nmeð rafrænum hætti \nþann " + _transactionTime.ToString("dd.MM.yyyy") + "\nStaður: " + location;
        _sap.LocationCaption = "Location caption";
        _sap.Contact = "Contact";

        _sap.ReasonCaption = "ReasonCaption";
        _sap.Layer4Text = "Layer 4 text";

        // Create signature infrastructure
        PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED);
        dic.Reason = _sap.Reason;
        dic.Location = _sap.Location;
        dic.Contact = _sap.Contact;
        dic.Date = new PdfDate(_sap.SignDate);
        _sap.CryptoDictionary = dic;

        Dictionary<PdfName, int> exc = new Dictionary<PdfName, int>();
        exc.Add(PdfName.CONTENTS, (15000 * 2) + 2); // TSA: Content estimated er 15000 í stað 8192

        //string tsa_url = ConfigurationManager.AppSettings["TSA_Url"];
        //TSAClientBouncyCastle tsc = new TSAClientBouncyCastle(tsa_url);
        //LtvTimestamp.Timestamp(_sap, tsc, null); // This can not be called here as then an exception will be thrown.

        _sap.PreClose(exc);

        Stream data = _sap.GetRangeStream();
        _hash = DigestAlgorithms.Digest(data, DigestAlgorithms.SHA1);
    }

然后postSign:

    public void PostSign(byte[] signatureData)
    {
        PdfSignatureAppearance sap = _sap;

        byte[] paddedSig = new byte[15000];
        System.Array.Copy(signatureData, 0, paddedSig, 0, signatureData.Length);

        PdfDictionary dic = new PdfDictionary();
        dic.Put(PdfName.CONTENTS, new PdfString(paddedSig).SetHexWriting(true));

        sap.Close(dic);
    }

这些方法是这样调用的:

      // Sign the document
      SignatureHelper signatureHelper = new SignatureHelper(itemID, employeeItemID, oUser.UserName, oUser.FullName);
      signatureHelper.preSign(pdfBytes, "Undirritun til að staðfesta uppruna", "Reykjavík");
      byte[] signatureData = signatureHelper.SignFile(pdfBytes, phoneNumber, itemID);
      signatureHelper.PostSign(signatureData);
      ro.ByteStream = signatureHelper.OutStream;
4

0 回答 0