DigitalSignatureTest.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. using ComPDFKit.DigitalSign;
  2. using ComPDFKit.Import;
  3. using ComPDFKit.PDFAnnotation.Form;
  4. using ComPDFKit.PDFDocument;
  5. using ComPDFKit.PDFPage;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Diagnostics;
  9. using System.Drawing;
  10. using System.IO;
  11. using System.Runtime.InteropServices;
  12. using System.Security.AccessControl;
  13. using System.Xml.Linq;
  14. using ImageMagick;
  15. namespace DigitalSignatureTest
  16. {
  17. internal class DigitalSignatureTestCertPathInPath
  18. {
  19. static private string parentPath = Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(System.IO.Directory.GetCurrentDirectory())));
  20. static private string outputPath = Path.Combine(parentPath, "Output", "CS");
  21. static string trustedFolder = AppDomain.CurrentDomain.BaseDirectory + @"\TrustedFolder\";
  22. static void Main()
  23. {
  24. #region Preparation work
  25. Console.WriteLine("Running digital signature sample...\n");
  26. SDKLicenseHelper.LicenseVerify();
  27. string certificatePath = "Certificate.pfx";
  28. string password = "ComPDFKit";
  29. if (!Directory.Exists(outputPath))
  30. {
  31. Directory.CreateDirectory(outputPath);
  32. }
  33. if (!Directory.Exists(trustedFolder))
  34. {
  35. Directory.CreateDirectory(trustedFolder);
  36. }
  37. CPDFSignature.SignCertTrustedFolder = trustedFolder;
  38. #endregion
  39. #region Sample 0: Create certificate
  40. GenerateCertificate();
  41. #endregion
  42. #region Sample 1: Create digital signature
  43. CPDFDocument document = CPDFDocument.InitWithFilePath("CommonFivePage.pdf");
  44. CreateDigitalSignature(document, certificatePath, password);
  45. document.Release();
  46. #endregion
  47. #region Sample 2: Verify signature
  48. CPDFDocument signedDoc = CPDFDocument.InitWithFilePath("Signed.pdf");
  49. VerifyDigitalSignature(signedDoc);
  50. #endregion
  51. #region Sample 3: Verify certificate
  52. VerifyCertificate(certificatePath, password);
  53. #endregion
  54. #region Sample 4: Print digital signature info
  55. PrintDigitalSignatureInfo(signedDoc);
  56. #endregion
  57. #region Sample 5: Trust Certificate
  58. TrustCertificate(signedDoc);
  59. #endregion
  60. #region Sample 6: Remove digital signature
  61. RemoveDigitalSignature(signedDoc);
  62. signedDoc.Release();
  63. #endregion
  64. Console.WriteLine("Done!");
  65. Console.ReadLine();
  66. }
  67. /// <summary>
  68. /// in the core function "CPDFPKCS12CertHelper.GeneratePKCS12Cert":
  69. ///
  70. /// Generate certificate
  71. ///
  72. /// Password: ComPDFKit
  73. ///
  74. /// info: /C=SG/O=ComPDFKit/D=R&D Department/CN=Alan/emailAddress=xxxx@example.com
  75. ///
  76. /// C=SG: This represents the country code "SG," which typically stands for Singapore.
  77. /// O=ComPDFKit: This is the Organization (O) field, indicating the name of the organization or entity, in this case, "ComPDFKit."
  78. /// D=R&D Department: This is the Department (D) field, indicating the specific department within the organization, in this case, "R&D Department."
  79. /// CN=Alan: This is the Common Name (CN) field, which usually represents the name of the individual or entity. In this case, it is "Alan."
  80. /// emailAddress=xxxx@example.com: Email is xxxx@example.com
  81. ///
  82. /// CPDFCertUsage.CPDFCertUsageAll: Used for both digital signing and data validation simultaneously.
  83. ///
  84. /// is_2048 = true: Enhanced security encryption.
  85. /// </summary>
  86. private static void GenerateCertificate()
  87. {
  88. Console.WriteLine("--------------------");
  89. Console.WriteLine("Generate certificate signature.");
  90. string info = "/C=SG/O=ComPDFKit/D=R&D Department/CN=Alan/emailAddress=xxxx@example.com";
  91. string password = "ComPDFKit";
  92. string filePath = "Certificate.pfx";
  93. if (CPDFPKCS12CertHelper.GeneratePKCS12Cert(info, password, filePath, CPDFCertUsage.CPDFCertUsageAll, true))
  94. {
  95. Console.WriteLine("File saved in " + filePath);
  96. Console.WriteLine("Generate PKCS12 certificate done.");
  97. }
  98. else
  99. {
  100. Console.WriteLine("Generate PKCS12 certificate failed.");
  101. }
  102. Console.WriteLine("--------------------");
  103. }
  104. /// <summary>
  105. ///
  106. /// Adding a signature is divided into two steps:
  107. /// creating a signature field and filling in the signature.
  108. ///
  109. /// Page Index: 0
  110. /// Rect: CRect(28, 420, 150, 370)
  111. /// Border RGB:{ 0, 0, 0 }
  112. /// Widget Background RGB: { 150, 180, 210 }
  113. ///
  114. /// Text: Grantor Name
  115. /// Content:
  116. /// Name: get grantor name from certificate
  117. /// Date: now(yyyy.mm.dd)
  118. /// Reason: I am the owner of the document.
  119. /// DN: Subject
  120. /// Location: Singapor
  121. /// IsContentAlignLeft: false
  122. /// IsDrawLogo: True
  123. /// LogoBitmap: logo.png
  124. /// text color RGB: { 0, 0, 0 }
  125. /// content color RGB: { 0, 0, 0 }
  126. /// Output file name: document.FileName + "_Signed.pdf"
  127. /// </summary>
  128. private static void CreateDigitalSignature(CPDFDocument document, string certificatePath, string password)
  129. {
  130. Console.WriteLine("--------------------");
  131. Console.WriteLine("Create digital signature.");
  132. CPDFSignatureCertificate certificate = CPDFPKCS12CertHelper.GetCertificateWithPKCS12Path("Certificate.pfx", "ComPDFKit");
  133. CPDFPage page = document.PageAtIndex(0);
  134. CPDFSignatureWidget signatureField = page.CreateWidget(C_WIDGET_TYPE.WIDGET_SIGNATUREFIELDS) as CPDFSignatureWidget;
  135. signatureField.SetRect(new CRect(28, 420, 150, 370));
  136. signatureField.SetWidgetBorderRGBColor(new byte[] { 0, 0, 0 });
  137. signatureField.SetWidgetBgRGBColor(new byte[] { 150, 180, 210 });
  138. signatureField.UpdateAp();
  139. string name = GetGrantorFromDictionary(certificate.SubjectDict) + "\n";
  140. string date = DateTime.Now.ToString("yyyy.MM.dd HH:mm:ss");
  141. string reason = "I am the owner of the document.";
  142. string location = certificate.SubjectDict["C"];
  143. string DN = certificate.Subject;
  144. CPDFSignatureConfig signatureConfig = new CPDFSignatureConfig
  145. {
  146. Text = GetGrantorFromDictionary(certificate.SubjectDict),
  147. Content =
  148. "Name: " + name + "\n" +
  149. "Date: " + date + "\n" +
  150. "Reason: " + reason + " \n" +
  151. "Location: " + location + "\n" +
  152. "DN: " + DN + "\n",
  153. IsContentAlignLeft = false,
  154. IsDrawLogo = true,
  155. TextColor = new float[] { 0, 0, 0 },
  156. ContentColor = new float[] { 0, 0, 0 }
  157. };
  158. using (var image = new MagickImage("Logo.png"))
  159. {
  160. byte[] byteArray = image.ToByteArray(MagickFormat.Bgra);
  161. signatureConfig.LogoData = byteArray;
  162. signatureConfig.LogoHeight = image.Height;
  163. signatureConfig.LogoWidth = image.Width;
  164. }
  165. string filePath = Path.Combine(outputPath, document.FileName + "_Signed.pdf");
  166. signatureField.UpdataApWithSignature(signatureConfig);
  167. if (document.WriteSignatureToFilePath(signatureField,
  168. filePath,
  169. certificatePath, password,
  170. location,
  171. reason, CPDFSignaturePermissions.CPDFSignaturePermissionsNone))
  172. {
  173. Console.WriteLine("File saved in " + filePath);
  174. Console.WriteLine("Create digital signature done.");
  175. }
  176. else
  177. {
  178. Console.WriteLine("Create digital signature failed.");
  179. }
  180. Console.WriteLine("--------------------");
  181. }
  182. /// <summary>
  183. /// Remove digital signature
  184. /// You can choose if you want to remove the appearance
  185. /// </summary>
  186. /// <param name="document"></param>
  187. private static void RemoveDigitalSignature(CPDFDocument document)
  188. {
  189. Console.WriteLine("--------------------");
  190. Console.WriteLine("Remove digital signature.");
  191. CPDFSignature signature = document.GetSignatureList()[0];
  192. document.RemoveSignature(signature, true);
  193. string filePath = Path.Combine(outputPath, "" + document.FileName + "_RemovedSign.pdf");
  194. document.WriteToFilePath(filePath);
  195. Console.WriteLine("File saved in " + filePath);
  196. Console.WriteLine("Remove digital signature done.");
  197. Console.WriteLine("--------------------");
  198. }
  199. /// <summary>
  200. /// There are two steps can help you to trust a certificate.
  201. /// Set your trust path as a folder path,
  202. /// then add your certificate to the trust path.
  203. /// </summary>
  204. private static void TrustCertificate(CPDFDocument document)
  205. {
  206. Console.WriteLine("--------------------");
  207. Console.WriteLine("Trust certificate.");
  208. CPDFSignature signature = document.GetSignatureList()[0];
  209. CPDFSignatureCertificate signatureCertificate = signature.SignerList[0].CertificateList[0];
  210. Console.WriteLine("Certificate trusted status: " + signatureCertificate.IsTrusted.ToString());
  211. Console.WriteLine("---Begin trusted---");
  212. if (signatureCertificate.AddToTrustedCertificates())
  213. {
  214. Console.WriteLine("Certificate trusted status: " + signatureCertificate.IsTrusted.ToString());
  215. Console.WriteLine("Trust certificate done.");
  216. }
  217. else
  218. {
  219. Console.WriteLine("Trust certificate failed.");
  220. }
  221. Console.WriteLine("--------------------");
  222. }
  223. /// <summary>
  224. /// Verify certificate
  225. ///
  226. /// To verify the trustworthiness of a certificate,
  227. /// you need to verify that all certificates in the certificate chain are trustworthy.
  228. ///
  229. /// In ComPDFKit,this progess is automatic.
  230. /// You should call the "CPDFSignatureCertificate.CheckCertificateIsTrusted" first.
  231. /// then you can view the "CPDFSignatureCertificate.IsTrusted" property.
  232. /// </summary>
  233. /// <param name="document">A signed document</param>
  234. private static void VerifyCertificate(string certificatePath, string password)
  235. {
  236. Console.WriteLine("--------------------");
  237. Console.WriteLine("Verify certificate.");
  238. CPDFSignatureCertificate certificate = CPDFPKCS12CertHelper.GetCertificateWithPKCS12Path(certificatePath, password);
  239. certificate.CheckCertificateIsTrusted();
  240. if (certificate.IsTrusted)
  241. {
  242. Console.WriteLine("Certificate is trusted");
  243. }
  244. else
  245. {
  246. Console.WriteLine("Certificate is not trusted");
  247. }
  248. Console.WriteLine("Verify certificate done.");
  249. Console.WriteLine("--------------------");
  250. }
  251. /// <summary>
  252. /// Verify digital signature
  253. ///
  254. /// Refresh the validation status before reading the attributes, or else you may obtain inaccurate results.
  255. /// Is the signature verified: indicating whether the document has been tampered with.
  256. /// Is the certificate trusted: referring to the trust status of the certificate.
  257. /// </summary>
  258. private static void VerifyDigitalSignature(CPDFDocument document)
  259. {
  260. Console.WriteLine("--------------------");
  261. Console.WriteLine("Verify digital signature.");
  262. foreach (var signature in document.GetSignatureList())
  263. {
  264. signature.VerifySignatureWithDocument(document);
  265. foreach (var signer in signature.SignerList)
  266. {
  267. Console.WriteLine("Is the certificate trusted: " + signer.IsCertTrusted.ToString());
  268. Console.WriteLine("Is the signature verified: " + signer.IsSignVerified.ToString());
  269. if (signer.IsCertTrusted && signer.IsSignVerified)
  270. {
  271. // Signature is valid and the certificate is trusted
  272. // Perform corresponding actions
  273. }
  274. else if (!signer.IsCertTrusted && signer.IsSignVerified)
  275. {
  276. // Signature is valid but the certificate is not trusted
  277. // Perform corresponding actions
  278. }
  279. else
  280. {
  281. // Signature is invalid
  282. // Perform corresponding actions
  283. }
  284. }
  285. }
  286. Console.WriteLine("Verify digital signature done.");
  287. Console.WriteLine("--------------------");
  288. }
  289. public static string GetGrantorFromDictionary(Dictionary<string, string> dictionary)
  290. {
  291. string grantor = string.Empty;
  292. dictionary.TryGetValue("CN", out grantor);
  293. if (string.IsNullOrEmpty(grantor))
  294. {
  295. dictionary.TryGetValue("OU", out grantor);
  296. }
  297. if (string.IsNullOrEmpty(grantor))
  298. {
  299. dictionary.TryGetValue("O", out grantor);
  300. }
  301. if (string.IsNullOrEmpty(grantor))
  302. {
  303. grantor = "Unknown Signer";
  304. }
  305. return grantor;
  306. }
  307. /// <summary>
  308. /// this samples shows how to get main properties in digital signature.
  309. /// read API reference to see all of the properties can get
  310. /// </summary>
  311. /// <param name="document"></param>
  312. private static void PrintDigitalSignatureInfo(CPDFDocument document)
  313. {
  314. Console.WriteLine("--------------------");
  315. Console.WriteLine("Print digital signature info.");
  316. foreach (var signature in document.GetSignatureList())
  317. {
  318. signature.VerifySignatureWithDocument(document);
  319. Console.WriteLine("Name: " + signature.Name);
  320. Console.WriteLine("Location: " + signature.Location);
  321. Console.WriteLine("Reason: " + signature.Reason);
  322. foreach (var signer in signature.SignerList)
  323. {
  324. Console.WriteLine("Date: " + signer.AuthenDate);
  325. foreach (var certificate in signer.CertificateList)
  326. {
  327. Console.WriteLine("Subject: " + certificate.Subject);
  328. }
  329. }
  330. }
  331. Console.WriteLine("Print digital signature info done.");
  332. Console.WriteLine("--------------------");
  333. }
  334. }
  335. }