SignDoc.vb
'' 完毕:
Imports System.IO
Imports System.Drawing
Imports GrapeCity.Documents.Pdf
Imports GrapeCity.Documents.Pdf.AcroForms
Imports GrapeCity.Documents.Text
Imports System.Security.Cryptography.X509Certificates

'' 此示例演示了如何使用 .pfx 文件对创建的 PDF 进行签名,
'' 使用签名字段。
'' 然后,该示例将签名的文件加载回另一个 GcPdfDocument 实例
'' 并验证签名。
Public Class SignDoc
    Function CreatePDF(ByVal stream As Stream) As Integer
        Dim doc = New GcPdfDocument()
        Dim page = doc.NewPage()
        Dim tf = New TextFormat() With {.Font = StandardFonts.Times, .FontSize = 14}
        page.Graphics.DrawString("你好世界!" +
            "",
                tf, New PointF(72, 72))

        '' 初始化测试证书:
        Dim pfxPath = Path.Combine("Resources", "Misc", "DsPdfTest.pfx")
        Dim cert = New X509Certificate2(File.ReadAllBytes(pfxPath), "qq",
            X509KeyStorageFlags.MachineKeySet Or X509KeyStorageFlags.PersistKeySet Or X509KeyStorageFlags.Exportable)
        Dim sp = New SignatureProperties() With {
            .SignatureBuilder = New Pkcs7SignatureBuilder() With {.CertificateChain = New X509Certificate2() {cert}},
            .Location = "DsPdfWeb Demo Browser",
            .SignerName = "DsPdfWeb",
            .SigningDateTime = Util.TimeNow()
        }

        '' 初始化一个签名字段来保存签名:
        Dim sf = New SignatureField()
        sf.Widget.Rect = New RectangleF(72, 72 * 2, 72 * 4, 36)
        sf.Widget.Page = page
        sf.Widget.BackColor = Color.LightSeaGreen
        sf.Widget.DefaultAppearance.Font = StandardFonts.Helvetica
        sf.Widget.ButtonAppearance.Caption = $"Signer: {sp.SignerName}{vbCrLf}Location: {sp.Location}"
        '' 将签名字段添加到文档中:
        doc.AcroForm.Fields.Add(sf)

        '' 连接签名字段和签名属性:
        sp.SignatureField = sf

        '' 签署并保存文档:
        '' 笔记:
        '' - 签名和保存是一个原子操作,两者不能分开。
        '' - 传递给 Sign() 方法的流必须可读。
        doc.Sign(sp, stream)

        '' 倒回流以读取刚刚创建的文档
        '' 进入另一个 GcPdfDocument 并验证签名:
        stream.Seek(0, SeekOrigin.Begin)
        Dim doc2 = New GcPdfDocument()
        doc2.Load(stream)
        Dim sf2 = DirectCast(doc2.AcroForm.Fields(0), SignatureField)
        If Not sf2.Value.VerifySignatureValue() Then
            Throw New Exception("Failed to verify the signature")
        End If
        ''
        '' 完成(生成并签名的文档已保存到“流”)。
        Return doc.Pages.Count
    End Function
End Class