如果一个第三方签名不符合要求,如何使PDF PAdES-LTV兼容

时间:2016-03-15 14:50:35

标签: c# pdf itext electronic-signature

这是一个我很难解决的问题。我们希望我们的供应商能够使用LTV签名签署PDF文档,以便文档的有效性不会过期。我读过Bruno Lowagie的书 iText in Action (第2版),他的白皮书 PDF文档的数字签名,并查看了PAdES个人资料文档(PDF文档的数字签名)

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

我们收到并添加签名后,如何在PDF中添加DSS和时间戳,以使PDF符合使用iText的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;

0 个答案:

没有答案