SignDoc.cs
  1. //
  2. // This code is part of Document Solutions for PDF demos.
  3. // Copyright (c) MESCIUS inc. All rights reserved.
  4. //
  5. using System;
  6. using System.IO;
  7. using System.Drawing;
  8. using GrapeCity.Documents.Pdf;
  9. using GrapeCity.Documents.Pdf.AcroForms;
  10. using GrapeCity.Documents.Text;
  11. using System.Security.Cryptography.X509Certificates;
  12.  
  13. namespace DsPdfWeb.Demos
  14. {
  15. // This sample demonstrates how to create and sign a PDF with a .pfx file,
  16. // using a SignatureField.
  17. // The sample then loads the signed file back into another GcPdfDocument instance
  18. // and verifies the signature.
  19. // See also VisualSignature which is similar but adds a visual representation
  20. // of the signature.
  21. public class SignDoc
  22. {
  23. public int CreatePDF(Stream stream)
  24. {
  25. var doc = new GcPdfDocument();
  26. var page = doc.NewPage();
  27. var tf = new TextFormat() { Font = StandardFonts.Times, FontSize = 14 };
  28. page.Graphics.DrawString("Hello, World!\n" +
  29. "Signed by DsPdfWeb SignDoc sample.",
  30. tf, new PointF(72, 72));
  31.  
  32. // Init a test certificate:
  33. var pfxPath = Path.Combine("Resources", "Misc", "DsPdfTest.pfx");
  34. var cert = new X509Certificate2(File.ReadAllBytes(pfxPath), "qq",
  35. X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
  36. var sp = new SignatureProperties()
  37. {
  38. SignatureBuilder = new Pkcs7SignatureBuilder()
  39. {
  40. CertificateChain = new X509Certificate2[] { cert }
  41. },
  42. Location = "DsPdfWeb Demo Browser",
  43. SignerName = "DsPdfWeb",
  44. SigningDateTime = Common.Util.TimeNow(),
  45. };
  46.  
  47. // Init a signature field to hold the signature:
  48. var sf = new SignatureField();
  49. sf.Widget.Rect = new RectangleF(72, 72 * 2, 72 * 4, 36);
  50. sf.Widget.Page = page;
  51. sf.Widget.BackColor = Color.LightSeaGreen;
  52. sf.Widget.DefaultAppearance.Font = StandardFonts.Helvetica;
  53. sf.Widget.ButtonAppearance.Caption = $"Signer: {sp.SignerName}\r\nLocation: {sp.Location}";
  54. // Add the signature field to the document:
  55. doc.AcroForm.Fields.Add(sf);
  56. // Connect the signature field and signature props:
  57. sp.SignatureField = sf;
  58.  
  59. // Sign and save the document:
  60. // NOTES:
  61. // - Signing and saving is an atomic operation, the two cannot be separated.
  62. // - The stream passed to the Sign() method must be readable.
  63. doc.Sign(sp, stream);
  64.  
  65. // Rewind the stream to read the document just created
  66. // into another GcPdfDocument and verify the signature:
  67. stream.Seek(0, SeekOrigin.Begin);
  68. var doc2 = new GcPdfDocument();
  69. doc2.Load(stream);
  70. SignatureField sf2 = (SignatureField)doc2.AcroForm.Fields[0];
  71. if (!sf2.Value.VerifySignatureValue())
  72. throw new Exception("Failed to verify the signature");
  73.  
  74. // Done (the generated and signed document has already been saved to 'stream').
  75. return doc.Pages.Count;
  76. }
  77. }
  78. }
  79.