【问题标题】:MakeSignature.SignDetached() closes all streams - Create signed PDF in memorystreamMakeSignature.SignDetached() 关闭所有流 - 在内存流中创建签名 PDF
【发布时间】:2016-04-14 08:04:55
【问题描述】:

我开发了一个功能来签署在内存流中创建的 PDF 并将其写入 PDF。现在我正在寻找扩展功能,而不是创建物理签名的 PDF,我想在内存中创建签名的 PDF,以便将其附加到电子邮件中。

这就是我所拥有的:

    Using myPdfReader As New PdfReader(sourcePDFStream)
        Using myFileStream As New MemoryStream()
            Using myPdfStamper As PdfStamper = PdfStamper.CreateSignature(myPdfReader, myFileStream, "0"c)

                Dim myPdfSignatureAppearance As PdfSignatureAppearance = myPdfStamper.SignatureAppearance
                myPdfSignatureAppearance.SetVisibleSignature(New iTextSharp.text.Rectangle(100, 100, 250, 150), myPdfReader.NumberOfPages, "Digital Signature")

                Dim myExternalSignature As IExternalSignature = New PrivateKeySignature(pk, "SHA-256")
                MakeSignature.SignDetached(myPdfSignatureAppearance, myExternalSignature, chain, Nothing, Nothing, Nothing, 0, CryptoStandard.CMS)

                clsMail.SendHTMLMailPackStream("niels@email.be", "EFFFFactuurFEB", "NL", "docname", myVars, myFileStream)
            End Using
        End Using
    End Using

我面临的问题是,当我调用“SendHTMLMailPackStream”方法时,“myfilestream”已经关闭。

有人知道这个问题的答案吗?

编辑:

我发现每次调用 MakeSignature.SignDetached() 方法时,它都会关闭我的所有流。但我不知道如何取消它..

【问题讨论】:

  • 由于myPdfStamper.Writer.CloseStream = false; 不起作用,我删除了我的答案。也许这是 iText 支持应该关注的问题。你们有支持合同吗?
  • @BrunoLowagie 不,我不知道。

标签: vb.net pdf itext digital-signature


【解决方案1】:

当您创建签名时,我检查了正在运行的 writer 类。这个类被称为PdfSignatureAppearance。它的Close() 方法确实不允许您保持原始流打开。这大概是有原因的。您不希望通过添加额外字节来危害已签名的 PDF。

查看您的代码,我不明白为什么必须保持 MemoryStream 处于打开状态。

你自己写过SendHTMLMailPackStream方法吗?我不知道参数应该是什么,但它会接受已经包含完整 PDF(除了完整的 PDF)的MemoryStream,这非常尴尬。人们会期望它要么期望一个可以添加为多部分数据的byte[],要么期望一个写入邮件消息和多部分数据的MemoryStream

我没有看到任何用例可以传递包含 PDF 的 MemoryStream。您会在该 PDF 的 %%EOF 之后添加哪些字节?

你确定你做对了吗?顺便说一句:Olivier 给我发了邮件,我建议他与 iText Software 联系,以防问题仍未解决。

【讨论】:

  • 流将用于创建电子邮件的附件:Dim att As New Attachment(stream, "filename.pdf")
  • 我不是 .NET 开发人员,但如果 .NET 类似于 Java(确实如此),我认为 stream 应该是 InputStream,而不是 OutputStream。为什么不使用存储在MemoryStream 中的byte[] 创建一个InputStream
  • 据我所知,我需要先点击 MakeSignature.SignDetached() 方法,否则流/字节 [] 中的内容无关紧要,PDF 不会被签名。目的是获得一个已签名但未保存在磁盘上的 PDF,并立即通过邮件发送。
  • 是的,需要调用SignDetached()。这将导致byte[] 包含正确签名的 PDF 的所有字节。此byte[] 未存储在磁盘上。它保存在MemoryStream 中。这个MemoryStream 已关闭,因为我们不希望任何人不小心将字节添加到完整的 PDF 中。 byte[] 以字节 %PDF- 开头,以 %%EOF 结尾。显然,您可以使用 byte[] 并将其嵌入到邮件中,但是当 byte[]%PDF 开头时,在 %%EOF 之后添加字节是没有意义的。我依靠你的常识来理解这一点。
  • 我找到了解决方案。问题是我不知道你可以从一个封闭的 MemoryStream 中创建一个 byte[]。这是我第一次使用 memorystreams。感谢您的回答和时间!
【解决方案2】:

我需要从关闭的 MemoryStream 创建一个 Byte[]。

有了那个字节[],我能够创建一个新的 MemoryStream 来创建签名的 PDF:

Dim myExternalSignature As IExternalSignature = New PrivateKeySignature(pk, "SHA-256")
MakeSignature.SignDetached(myPdfSignatureAppearance, myExternalSignature, chain, Nothing, Nothing, Nothing, 0, CryptoStandard.CMS)

byteArray = myFileStream.ToArray()

外用:

Dim EndFileStream As New MemoryStream(byteArray)
clsMail.SendHTMLMailPackStream("niels@email.be", "EFFFFactuurFEB", "NL", "docname", myVars, EndFileStream)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-10
    • 2012-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多