'''' This code is part of Document Solutions for PDF .NET demos.'' Copyright (c) MESCIUS inc. All rights reserved.''ImportsSystemImportsSystem.IOImportsSystem.LinqImportsSystem.Collections.GenericImportsSystem.Security.CryptographyImportsSystem.Security.Cryptography.X509CertificatesImportsGrapeCity.Documents.PdfImportsGrapeCity.Documents.Pdf.SecurityImportsGrapeCity.Documents.Pdf.AcroForms '' This sample shows how to sign an existing PDF file containing'' an empty signature field with a signature that complies with'' the various PAdES (PDF Advanced Electronic Signatures) levels.'' Note that when run online, this sample simply returns an unsigned'' PDF with an empty signature field. To actually sign the PDF'' you will need to provide a valid .pfx file (see "JohnDoe.pfx").'' The sample contains 5 methods that can be used to sign a PDF'' with the various PAdES levels, the last 3 methods can be'' used in a chain to incrementally increase the signature strength.'' To check the signature compliance, open the signed PDF in Acrobat'' Reader and inspect the signature properties.'''' IMPORTANT! The code in this sample WILL NOT work correctly'' unless DsPdf is licensed with a valid license key.'' Email us.sales@mescius.com to obtain a trial key.PublicClassPadesLevels'' Certificate issued by CA Cert Signing Authority, used for verification:Shareds_caCertRootAsNewX509Certificate2(Path.Combine("Resources", "Misc", "CACertRoot.crt"))'' TODO: replace with a real certificate:Shareds_certAsNewX509Certificate2(Path.Combine("Resources", "Misc", "JohnDoe.pfx"), "secret") SharedSubNew()'' TODO: GcPdfDocument MUST BE LICENSED for the signatures to remain valid,'' as otherwise the license nag text added when saving the PDF invalidates'' incremental updates. Email us.sales@mescius.com to obtain a trial key.'' GcPdfDocument.SetLicenseKey("my key")EndSub FunctionCreatePDF(ByVal stream AsStream, Optional paramsIdx AsInteger = 0) AsIntegerReturnCreatePDF(stream, GetSampleParamsList()(paramsIdx))EndFunction '' While this sample includes code that does the actual signing and time stamping,'' that code is NOT executed by the online demo. So the online sample driver'' simply returns the PDF that includes info about the selected PAdES level,'' and can be signed or time stamped using a valid certificate.'' You can copy the corresponding code and use it in your applications.FunctionCreatePDF(ByVal stream AsStream, ByVal sampleParams AsString()) AsInteger'' TODO: change to True to actually run the signing/time stamping code:Dim doSigning = False '' The unsigned PDF with a signature field to sign:Dim fn = Path.Combine("Resources", "PDFs", sampleParams(3)) If doSigning Then'' Running this code will produce 5 PDFs with increasing PAdES levels: '' PAdES B-B:Do_B_B(fn)'' PAdES B-T:Do_B_T(fn)'' Note that the next 3 steps use PDFs produced by the previous step,'' incrementally adding verification info:'' PAdES B-LT:Do_B_LT("B-T.pdf")'' PAdES B-LTA:Do_B_LTA("B-LT.pdf")'' LTV Enabled:Do_B_LTA_LTV("B-LTA.pdf")EndIf '' Copy the source PDF to output stream to provide the demo result:Using fs = File.OpenRead(fn)Dim doc = NewGcPdfDocument() doc.Load(fs)Dim pageCount = doc.Pages.Count fs.Seek(0, SeekOrigin.Begin) fs.CopyTo(stream)Return pageCountEndUsingEndFunction '' Signs a PDF with a PAdES B-B Level signature:SubDo_B_B(ByVal fn AsString)Using fs AsFileStream = File.OpenRead(fn)Dim doc = NewGcPdfDocument() doc.Load(fs) Dim signField = doc.AcroForm.Fields.FirstOrDefault(Function(f_) TypeOf f_ IsSignatureField)If signField IsNothingThenThrowNewException("Could not find a signature field.")EndIf Dim sp = NewSignatureProperties() With { .SignatureField = signField, .SignatureBuilder = NewPkcs7SignatureBuilder(s_cert) With { .Format = Pkcs7SignatureBuilder.SignatureFormat.ETSI_CAdES_detached } }'' Sign and save the PDF to a file: doc.Sign(sp, "B-B.pdf")EndUsingEndSub '' Signs a PDF with a PAdES B-T Level signature:SubDo_B_T(ByVal fn AsString)Using fs AsFileStream = File.OpenRead(fn)Dim doc = NewGcPdfDocument() doc.Load(fs) Dim signField = doc.AcroForm.Fields.FirstOrDefault(Function(f_) TypeOf f_ IsSignatureField)If signField IsNothingThenThrowNewException("Could not find a signature field.")EndIf Dim sp = NewSignatureProperties() With { .SignatureField = signField, .SignatureBuilder = NewPkcs7SignatureBuilder(s_cert) With { .Format = Pkcs7SignatureBuilder.SignatureFormat.ETSI_CAdES_detached }, .TimeStamp = NewTimeStamp("http://ts.ssl.com") }'' Sign and save the PDF to a file: doc.Sign(sp, "B-T.pdf")EndUsingEndSub '' Adds LTV information to a B-T level signature (e.g. as created by the Do_B_T method above),'' which makes the signature compliant with PAdES B-LT:SubDo_B_LT(ByVal fn AsString)Using fs AsFileStream = File.OpenRead(fn)Dim doc = NewGcPdfDocument() doc.Load(fs) Dim signField = doc.AcroForm.Fields.FirstOrDefault(Function(f_) TypeOf f_ IsSignatureField)If signField IsNothingThenThrowNewException("Could not find a signature field.")EndIf '' Get the signature and add verification information for it:Dim sig = DirectCast(signField.Value, Signature)Dim vp = NewDocumentSecurityStore.VerificationParams() vp.Certificates = NewX509Certificate2() {s_caCertRoot}IfNot doc.SecurityStore.AddVerification(sig, vp) ThenThrowNewException($"Could not add verification for {sig.Name}.")EndIf '' Save the PDF to a file using incremental update so that the signature remains valid: doc.Save("B-LT.pdf", SaveMode.IncrementalUpdate)EndUsingEndSub '' Adds time stamp to a signed PDF (e.g. as created by the Do_B_LT method above),'' which makes the document compliant with B-LTA level:SubDo_B_LTA(ByVal fn AsString)Using fs AsFileStream = File.OpenRead(fn)Dim doc = NewGcPdfDocument() doc.Load(fs) Dim ts = NewTimeStampProperties() With { .TimeStamp = NewTimeStamp("http://ts.ssl.com") }'' Save the PDF to a file adding a time stamp to it: doc.TimeStamp(ts, "B-LTA.pdf")EndUsingEndSub '' Adds verification information for a PDF time-stamp (e.g. as created by the Do_B_LTA method above)'' which makes the signature LTV enabled:SubDo_B_LTA_LTV(ByVal fn AsString)Using fs AsFileStream = File.OpenRead(fn)Dim doc = NewGcPdfDocument() doc.Load(fs) Dim signField = doc.AcroForm.Fields.FirstOrDefault(Function(f_) TypeOf f_ IsSignatureField)If signField IsNothingThenThrowNewException("Could not find a signature field.")EndIf '' Get the signature and add verification information for it:Dim sig = DirectCast(signField.Value, Signature)IfNot doc.SecurityStore.AddVerification(sig) ThenThrowNewException($"Could not add verification for {sig.Name}.")EndIf '' Save the PDF to a file using incremental update so that the signature remains valid: doc.Save("B-LTA_LTV.pdf", SaveMode.IncrementalUpdate)EndUsingEndSub PublicSharedFunctionGetSampleParamsList() AsList(OfString())'' Strings are name, description, info, rest are arbitrary strings:ReturnNewList(OfString())() From {NewString() {"@b-sign/PAdES B-B Level", "How to sign a PDF complying with PAdES B-B level", "","PAdES-B-B.pdf"},NewString() {"@b-sign/PAdES B-T Level", "How to sign a PDF complying with PAdES B-T level", "","PAdES-B-T.pdf"},NewString() {"@b-sign/PAdES B-LT Level", "How to add LTV information to a signature", "","PAdES-B-LT.pdf"},NewString() {"@b-sign/PAdES B-LTA Level", "How to time stamp a signed PDF", "","PAdES-B-LTA.pdf"},NewString() {"@b-sign/LTV Enabled Signature", "How to make a signature LTV enabled", "","PAdES-B-LTA-LTV.pdf"} }EndFunctionEndClass