- Home
- Forum
- ASP.NET MVC - EJ 2
- Embedded certificates in digitally signed PDFs
Embedded certificates in digitally signed PDFs
Dear tech people, good day!
Attachment: Signed_PDF_samples_732b0e5a.zip
I'm having an issue when signing PDF files with PdfCertificate and PdfSignature as follows:
1) When creating a PdfCertificate for signing with this constructor: PdfCertificate(Stream certificate, String password), the resulting PDF contains the complete certificate chain that is in the PFX used to build the Stream parameter (a sample PDF is attached, and a snapshot of what Adobe shows).
2) When creating a PdfCertificate for signing with this constructor: PdfCertificate(X509Certificate2 x509Certificate2), the resulting PDF contains only the signing certificate, and not the complete chain (a sample PDF is attached, and a snapshot of what Adobe shows).
The X509Certificate2 object passed to the constructor in example 2) was built like this:
var cert = new X509Certificate2(pathToPfxFile, passwordOfPfxFile)
The same PFX file was used in both cases, only that the first example passes a filestream of that file, and the second case passes an X509Certificate2 object built on it.
It's important to keep the complete certificate chain inside the PDF files. This is because when parsing the files, I extract the certificates to build a certificate chain and pass it to PdfLoadedSignatureField.ValidateSignature(rootCertificates X509Certificate2Collection).
I would gladly use only the first PdfCertificate example in our software, but since signing with smartcards is also a must, and that can be achieved only by passing an X509Certificate2 to PdfCertificate, I guess there must be something we can do in order to have the full chain embedded in the resulting PDF using the second method.
As a side note, this misbehavior happens with PFX files that were NOT imported previously in the Windows Certificates Store, otherwise the resulting PDF contains the full chain, I think because the signing process looks for the root cert there.
We cannot depend on the Windows Certificates Store to sign files because it's a server software, running under an IIS Application Pool account with low privileges.
I'm using ASP.NET MVC components, version 18.1.0.59.
Any suggestions are very welcome.
Thank you!
Alex
Attachment: Signed_PDF_samples_732b0e5a.zip
SIGN IN To post a reply.
4 Replies
1 reply marked as answer
CM
Chinnu Muniyappan
Syncfusion Team
June 26, 2020 11:51 AM UTC
Hi Alex,
Thank you for contacting Syncfusion support.
We are excluding the root certificate when signing a PDF document using the X509Certificate2 API, because of the root certificate fetched from the windows store in the viewer automatically (like Adobe Reader). This is our current behavior for signing store certificates. We can include the store certificate chain by using the following code.
First Approach:
Load the X509Certificate2 as exportable and sign with different digest algorithm like.
|
//Load existing PDF document
PdfLoadedDocument document = new PdfLoadedDocument("PDF_Succinctly.pdf");
//Get the existing page.
PdfLoadedPage page = document.Pages[0] as PdfLoadedPage;
//Load the certificate with exportable.
X509Certificate2 x509 = new X509Certificate2("certchain.pfx", "password@123", X509KeyStorageFlags.Exportable);
//Create PdfCertificate instance.
PdfCertificate certificate = new PdfCertificate(x509);
//Create the signature.
PdfSignature signature = new PdfSignature(document, page, certificate, "Signature1");
//Set the digest algorithm.
signature.Settings.DigestAlgorithm = DigestAlgorithm.SHA256;
//Save the PDF document
document.Save("Output.pdf");
//Close the document.
document.Close(true);
|
Second Approach:
Or else we can sign the store certificate using SignedCms externally like below.
|
//Load existing PDF document
PdfLoadedDocument document = new PdfLoadedDocument("PDF_Succinctly.pdf");
//Get the existing page.
PdfLoadedPage page = document.Pages[0] as PdfLoadedPage;
//Create the signature with empty certificate.
PdfSignature signature = new PdfSignature(document, page, null, "Signature1");
signature.Bounds = new RectangleF(0, 0, 100, 50);
//Initialize the ComputeHash event.
signature.ComputeHash += Signature_ComputeHash;
//Save the PDF document
document.Save("ExternalSignature.pdf");
//Close the document.
document.Close(true);
|
And the ComputeHash event add the below code.
|
private void Signature_ComputeHash(object sender, PdfSignatureEventArgs ars)
{
//Get the document bytes.
byte[] documentBytes = ars.Data;
SignedCms signedCms = new SignedCms(new ContentInfo(documentBytes), detached: true);
//Compute the signature using the specified digital ID file and the password.
X509Certificate2 certificate = new X509Certificate2("certchain.pfx", "password@123");
var cmsSigner = new CmsSigner(certificate);
cmsSigner.IncludeOption = X509IncludeOption.WholeChain;
//Set the digest algorithm SHA256
cmsSigner.DigestAlgorithm = new Oid("2.16.840.1.101.3.4.2.1");
signedCms.ComputeSignature(cmsSigner);
//Embed the encoded digital signature to the PDF document.
ars.SignedData = signedCms.Encode();
} |
For more details, refer the following KB article.
Please try the above in your side and let us know if you have any further assistance.
Regards,
Chinnu M
Marked as answer
AL
Alejandro
June 26, 2020 06:47 PM UTC
Hello Chinnu,
Thanks for your response. I understand the behavior you mention about excluding the root certificate when using X509Certificate2.
But what I don't understand is this:
How can other people validate PDFs signed this way, which don't include the root certificate?
In my case, I'm using external tools to parse the files (like BouncyCastle), which help me build X509Certificate2 objects from the signature certificates in the files.
Then I use .net's X509Chain to build a certificate chain with all that info, and -finally- I use them to pass it to PdfLoadedSignatureField.ValidateSignature
X509Chain complains if the chain cannot be built, and that's the case when the root certificate is missing.
I don't see how can I validate a PDF which does not containt the whole certificate chain embedded.
Am I missing something regarding validation?
Thank you
Alex
SL
Sowmiya Loganathan
Syncfusion Team
June 29, 2020 12:39 PM UTC
Hi Alejandro,
We have validated the reported issue and logged a bug report for this. We will update the patch for the reported issue on July 13, 2020.
Regards,
Sowmiya Loganathan
SL
Sowmiya Loganathan
Syncfusion Team
July 13, 2020 11:38 AM UTC
Hi Alejandro,
The reported issue has been fixed and the patch for this fix can be downloaded from the following location.
The reported issue has been fixed and the patch for this fix can be downloaded from the following location.
The status of this feedback can be tracked through the following feedback link,
Recommended approach - exe will perform automatic configuration
Please find the patch setup from below location:
http://syncfusion.com/Installs/support/patch/18.2.0.44/1177194/F155522/SyncfusionPatch_18.2.0.44_1177194_7132020061305583_F155522.exe
Advanced approach – use only if you have specific needs and can directly replace existing assemblies for your build environment
Please find the patch assemblies alone from below location:
http://syncfusion.com/Installs/support/patch/18.2.0.44/1177194/F155522/SyncfusionPatch_18.2.0.44_1177194_7132020061305583_F155522.zip
NuGet package: http://syncfusion.com/Installs/support/patch/18.2.0.44/1177194/F155522/SyncfusionNuget_18.2.0.44_1177194_7132020061305583_F155522.zip
Assembly Version: 18.2.0.44
Installation Directions :
This patch should replace the files “Syncfusion.Pdf.Base.dll” under the following folder.
$system drive:\ Files\Syncfusion\Essential Studio\18.2.0.44\precompiledassemblies\18.2.0.44\4.5.1
Eg : $system drive:\Program Files\Syncfusion\Essential Studio\9.3.0.61\precompiledassemblies\9.3.0.61\4.0
To automatically run the Assembly Manager, please check the Run assembly manager checkbox option while installing the patch. If this option is unchecked, the patch will replace the assemblies in precompiled assemblies’ folder only. Then, you will have to manually copy and paste them to the preferred location or you will have to run the Syncfusion Assembly Manager application (available from the Syncfusion Dashboard, installed as a shortcut in the Application menu) to re-install assemblies.
Note :
To change how you receive bug fixes, ask your license management portal admin to change your project’s patch delivery mode.
https://www.syncfusion.com/account/license
Disclaimer :
Please note that we have created this patch for version 18.2.0.44 specifically to resolve the following issue(s) reported in this/the incident(s). 155522
If you have received other patches for the same version for other products, please apply all patches in the order received.
This fix will be included in our Volume 2 SP1 release which will be available in end of August, 2020.
Regards,
Sowmiya Loganathan
SIGN IN To post a reply.
- 4 Replies
- 3 Participants
- Marked answer
-
AL Alejandro
- Jun 25, 2020 11:39 AM UTC
- Jul 13, 2020 11:38 AM UTC