Signature Library User Manual
Signature Library User Manual
Introduction
The main function of .NET Digital Signature Library is to digitally sign files in PDF, CAdES
or PKCS#7 cryptographic standard (.P7S or .P7M files) using X.509 certificates stored on
PFX files, smart cards, USB tokens, HSM’s stored on Microsoft Certificate Store.
The positioning of the PDF signature appearance is configurable, plus on which pages of the
document it should appear (first page, last page or all pages).
Also, using .NET Digital Signature Library can digitally sign Office 2007, 2010, 2013, XPS
and XML documents using X.509 certificates. Using this library you can quickly digitally
sign .docx, .xlsx, .pptx, .xps and .xml files using a simple SDK.
.NET Digital Signature Library can be used to create X.509 certificates in PFX format. Using
this library you can quickly create PFX digital certificates and custom certificates with different
Key usage or Enhanced key usage.
Links
Every effort has been made to make this manual as complete and accurate as possible, but
no warranty or fitness is implied. The information provided is on an “as is” basis. The author
shall have neither liability nor responsibility to any person or entity with respect to any loss or
damages arising from the information contained in this manual.
Trademarks
Note:
SignLib.dll requires at least .NET Framework 3.5.
The certificates stored on Microsoft Store are available by opening Internet Explorer – Tools
menu – Internet Options – Content tab – Certificates button (see below).
Also, the Microsoft Certificate store can be accessed using the command: Start – Run –
certmgr.msc.
For digital signatures the certificates stored on Personal tab are used. These certificates have
a public and a private key.
The digital signature is created by using the private key of the certificate. The private key can
be stored on the file system (imported PFX files), on a cryptographic smart card (like Aladdin
eToken or SafeNet iKey) or on a HSM (Hardware Security Module).
Another way to store a digital certificate is a PFX (or P12) file. This file contain the public and
the private key of the certificate. This file is protected by a password in order to keep safe the
key pair.
Note that a PFX/P12 file can be imported on Microsoft Store (just open the PFX/P12 file and
follow the wizard).
Every certificate must have a Subject. The Subject can contains Unicode characters like ä,æ,
£, Ñ.
Every certificate has a validity period. A certificate becomes invalid after it expires.
Observation: On the demo version of the library, the certificate validity cannot exceed
30 days (this is the single limitation of the library on the demo version).
using SignLib.Certificates;
using SignLib.Certificates;
using SignLib.Pdf;
ps.SignaturePosition = SignaturePosition.TopRight;
When the dest.pdf is opened in Adobe Reader, a signature rectangle appear on the top right
corner.
When the signature rectangle is clicked, the digital signature information appears.
using SignLib.Certificates;
using SignLib.Pdf;
ps.SignaturePosition = SignaturePosition.TopRight;
When the application is launched, the user must select the digital certificate from all
certificates available in Personal tab.
If the desired certificate has in the Subject field the value E = [email protected], you can use
the following code to automatically use the certificate for the signing operation.
using SignLib.Certificates;
using SignLib.Pdf;
//Load the certificate from Microsoft Certificate Store without user intervention
ps.DigitalSignatureCertificate = DigitalCertificate.LoadCertificate(false,
DigitalCertificateSearchCriteria.EmailE, "[email protected]");
Note that there are a lot of criteria to automatically select your certificate (Common Name,
Serial Number, Thumbprint, etc.).
In case the digital signature must be made without user intervention and the certificate is
stored on a smart card or USB token, the PIN dialog might be automatically bypassed for
some models.
Attention: This feature will NOT work for all available smart card/USB tokens because of the
drivers or other security measures. Use this property carefully.
using SignLib.Certificates;
using SignLib.Pdf;
oad the certificate from Microsoft Certificate Store without user intervention
ps.DigitalSignatureCertificate = DigitalCertificate.LoadCertificate(false,
DigitalCertificateSearchCriteria.EmailE, "[email protected]");
If the signing certificate (or the Root CA that issued the signing certificate) is not included in
Adobe Store, the digital signature is considered "not trusted" when a user open a document
with Adobe Reader (see example).
This behavior has nothing to do with the signing engine but with the Adobe
certification validation procedure.
To trust a signature the user must add the signing certificate on the Adobe Certificate Store
because only a few Root CA's are considered trusted by default by Adobe certificate
validation engine (See this article: http://www.adobe.com/security/partners_cds.html)
To validate the signing certificate in Adobe use the methods described on this document:
http://www.signfiles.com/manuals/ValidatingDigitalSignaturesInAdobe.pdf
Valid signature
using SignLib.Certificates;
using SignLib.Pdf;
DocumentPageSize property is useful when you want to place a custom digital signature
rectangle on the PDF document.
Observation: Some digital signature properties (like “Signed by” in Adobe) will not appear
with your custom value because of Adobe policy. If Time stamping is used, the signing date
(SignatureDate property) is taken from the time stamping response.
Signed by, Reason, Location, Date and Signer's contact properties in other PDF reader
Example: put the digital signature rectangle on the last page of the document on top middle
position:
ps.SignaturePage = ps.DocumentProperties.NumberOfPages;
ps.SignaturePosition = SignaturePosition.TopMiddle;
Example: put the digital signature on a custom position (top right corner) on the first page of
the document:
ps.SignaturePage = 1;
//get the pdf page size
System.Drawing.Point page = ps.DocumentProperties.DocumentPageSize(1);
The signature text can be set using SignatureText propery like below:
ps.SignatureText =
"Signed by:" + ps.DigitalSignatureCertificate.GetNameInfo(X509NameType.SimpleName,
false) + "\n Date:" + DateTime.Now.ToString("yyyy.MM.dd HH:mm") + "\n" +
"Reason:" + ps.SigningReason;
ps.TextDirection = TextDirection.RightToLeft;
The font size is calculated based on the signature rectangle size in order to fit on the
signature rectangle (it not have a fixed size). To set the font size you can use FontSize
propery like below:
ps.FontFile = "c:\\windows\\fonts\\arial.ttf";
ps.FontSize = 10;
//invisible signature
ps.VisibleSignature = false;
By default, the hash algorithm used to create the digital signatures is SHA-1. In order to use
SHA-256 or SHA-512 hashing algorithm, check the property HashAlgorithm.
Attention: SHA-256, SHA-384 and SHA-512 hash algorithms are not supported by Windows
XP. Note that some smart cards and USB tokens not support SHA-256, SHA-384 and SHA-
512 hash algorithms.
In order to be compatible with all Adobe Reader versions and with third party PDF readers,
the default signature standard is PKCS#7 – Detached.
Some countries require the new PDF signature standard named CAdES (PAdES).
In order to use this new standard, use the code below (note that the signature must be SHA-
256).
ps.DigitalSignatureCertificate =
DigitalCertificate.LoadCertificate("d:\\cert.pfx", "123456");
ps.HashAlgorithm = SignLib.HashAlgorithm.SHA256;
ps.SignatureStandard = SignLib.SignatureStandard.Cades;
Attention: The old versions of Adobe Reader and some versions of digital signature
verification software will not recognize this format.
To add time stamping information to the PDF digital signature you will need access to a RFC
3161 time stamping server.
A fully functional version of our TSA Authority is available for testing purposes at this link:
http://ca.signfiles.com/TSAServer.aspx (no credentials are needed).
Use the code below to digitally sign and timestamp your PDF file:
using SignLib.Certificates;
using SignLib.Pdf;
ps.TimeStamping.AuthenticationCertificate =
DigitalCertificate.LoadCertificate("d:\\time_stamping_certificate", "123456");
To include (or exclude) a Nonce on the time stamping request use the following code. The
default value of the UseNonce propery is true.:
ps.TimeStamping.UseNonce = true;
Some TSA servers require to set a Policy OID on the TSA requests. To set a TSA policy OID
on the time stamping requests use the code below. By default, no TSA OID is included on the
TSA request.
ps.TimeStamping.PolicyOid = new
System.Security.Cryptography.Oid("1.3.7.2.9.1.829.3");
Hash Algorithms
By default, the hash algorithm used to generate the Time Stamp Request is SHA-1.
In order to use SHA-256 or SHA-512 hashing algorithm, check the property
TimeStamping.HashAlgorithm.
ps.TimeStamping.HashAlgorithm = SignLib.HashAlgorithm.SHA256;
Attention: SHA-256, SHA-384 and SHA-512 hashing algorithms are not supported by
Windows XP. Note that some smart cards and USB tokens not support SHA-256, SHA-384
and SHA-512 hashing algorithms.
If the time stamping certificate (or the Root CA that issued the time stamping certificate) is not
included in Adobe Store, the time stamping response could not be verified when a user open
a document with Adobe Reader (see example).
This behavior has nothing to do with the signing engine but with the Adobe
certification validation procedure.
To validate the signing certificate in Adobe use the methods described on this document:
http://www.signfiles.com/manuals/ValidatingDigitalSignaturesInAdobe.pdf.
In order to have a LTV signature, be sure that the certificate have a CRL and the revocation
info is included on the signature. Including a timestamp is also recommended.
If the revocation information will not be available online, the digital signature cannot be
verified as Long Term Validation signature by the Adobe Reader engine.
Attention: In some cases, the CRL file is very large (1 to 3 MB) so the signed PDF file size
will increase with at least the size of the CRL file.
You can apply a certifying signature only if the PDF doesn’t already contain any other
signatures. Certifying signatures can be visible or invisible. A blue ribbon icon in the
Signatures panel indicates a valid certifying signature (see example).
More information about the certification process you can find here.
using SignLib.Certificates;
using SignLib.Pdf;
Certified signature
SignLib library can save PDF file in PDF/A-1b - Level B compliance in Part 1 standard.
Observation: In order to save a PDF/A-1b file all fonts used on the PDF document must be
embedded (including the font used on the digital signature rectangle).
using SignLib.Certificates;
using SignLib.Pdf;
ps.SignaturePage = 1;
ps.SignaturePosition = SignaturePosition.TopLeft;
ps.SignatureAppearsOnAllPages = true;
ps.AppendSignature = false;
In some cases, the size of the document is an critical factor so the size of the signed file can
be reduced by setting a lower value of the signature block size.
Observation: This value is approximative and cannot be set on the signed document to an
exact value so the final size of the signed file is not equal with the original file size +
SignatureByteBlockSize.
To set a custom space for the signature block size (this is an invisible property and will not
appear on autocomplete) use the following code:
ps.SignatureByteBlockSize = 8192;
ps.OldStyleAdobeSignature = true;
Signature valid
s.PadesLtvLevel = PadesLtvLevel.IncludeCrlAndOcsp;
//very large CRL will also be added
ps.MaxCrlSize = 2048 * 1024; //2 MB
ps.SignatureStandard = SignLib.SignatureStandard.Cades;
Attention: In some cases, the CRL file is very large (1 to 3 MB) so the signed PDF file size
will increase with at least the size of the CRL file.
Password Security
In order to encrypt the PDF document, the AppendSignature propery must be set to false.
Also, the encryption algorithm must be specified using EncryptionAlgorithm property.
OwnerPassword property is used to set the password that protects the PDF document for
printing or content copying.
To digitally sign and encrypt a PDF document using a password, use the following code:
To digitally sign and protect the document with an opened password use the code below
instead of the commented line:
//PDFSign.Encryption.OwnerPassword = "123456";
ps.Encryption.UserPassword = "123456";
When the document is opened in PDF reader, the passwor must be entered.
To encrypt a signed message using a digital certificate use the code below:
If you want to encrypt the PDF file using a .CER file (public key), use the code below instead
of the commented lines:
//ps.Encryption.EncryptionCertificate = DigitalCertificate.LoadCertificate(false,
string.Empty, "Select Certificate", "Select the certificate for encryption");
ps.Encryption.EncryptionCertificate = new
System.Security.Cryptography.X509Certificates.X509Certificate2(File.ReadAllBytes("
d:\\encryption_certificate.cer"));
Observation: A file encrypted with the public key can be opened only by the corresponding
private key of that certificate. If you want to encrypt a file for a person, you will need the public
key of the certificate issued for that person. If the file is encrypted with your certificate only
you can open that file. If the private key of the encryption certificate is not present a warning
message will be displayed like below:
ps.DigitalSignatureCertificate =
DigitalCertificate.LoadCertificate("d:\\cert.pfx", "123456");
//put the signature to all pages
ps.SignatureAppearsOnAllPages = true;
//set the signature position
ps.SignaturePosition = SignaturePosition.TopLeft;
//digitally sign and save the PDF file
File.WriteAllBytes("d:\\dest.pdf", ps.ApplyDigitalSignature());
Set a Custom Signature Rectangle and Sign Using a Smart Card Certificate
using SignLib.Certificates;
using SignLib.Pdf;
Digitally Sign a PDF Located on the Web Only if it is not Already Signed
using SignLib.Certificates;
using SignLib.Pdf;
//create the digital certificate used to digitally sign the PDF document
X509CertificateGenerator cert = new X509CertificateGenerator("serial number");
cert.Extensions.AddEnhancedKeyUsage(CertificateEnhancedKeyUsage.DocumentSigning);
cert.Extensions.AddEnhancedKeyUsage(CertificateEnhancedKeyUsage.SecureEmail);
ps.LoadPdfDocument("c:\\source.pdf");
ps.DigitalSignatureCertificate =
DigitalCertificate.LoadCertificate("d:\\cert.pfx", "123456");
ps.SignaturePage = 1;
ps.SignaturePosition = SignaturePosition.BottomLeft;
File.WriteAllBytes("c:\\dest.pdf", ps.ApplyDigitalSignature());
Add an Image on the Signature Rectangle and Save the File as PDF/A
using SignLib.Certificates;
using SignLib.Pdf;
ps.LoadPdfDocument("d:\\source.pdf");
ps.DigitalSignatureCertificate =
DigitalCertificate.LoadCertificate("d:\\cert.pfx", "123456");
ps.SignaturePage = ps.DocumentProperties.NumberOfPages;
ps.SignaturePosition = SignaturePosition.BottomLeft;
File.WriteAllBytes("d:\\dest.pdf", ps.ApplyDigitalSignature());
ps.LoadPdfDocument("d:\\source.pdf");
ps.DigitalSignatureCertificate =
DigitalCertificate.LoadCertificate("d:\\cert.pfx", "123456");
File.WriteAllBytes("d:\\dest.pdf", ps.ApplyDigitalSignature());
ps.LoadPdfDocument("d:\\source.pdf");
ps.DigitalSignatureCertificate =
DigitalCertificate.LoadCertificate("d:\\cert.pfx", "123456");
File.WriteAllBytes("d:\\dest.pdf", ps.ApplyDigitalSignature());
ps.LoadPdfDocument("d:\\source.pdf");
ps.DigitalSignatureCertificate =
DigitalCertificate.LoadCertificate("d:\\cert.pfx", "123456");
File.WriteAllBytes("d:\\dest.pdf", ps.ApplyDigitalSignature());
using SignLib.Certificates;
using SignLib.Pdf;
ps.DigitalSignatureCertificate =
DigitalCertificate.LoadCertificate("d:\\cert.pfx", "123456");
System.IO.DirectoryInfo di;
System.IO.FileInfo[] rgFiles;
using SignLib.Certificates;
using SignLib.Pdf;
ps.LoadPdfDocument(Server.MapPath("source.pdf"));
System.IO.File.WriteAllBytes(Server.MapPath("dest.pdf"),
ps.ApplyDigitalSignature());
}
ps.SignaturePosition = SignaturePosition.TopLeft;
ps.SignaturePage = 1;
System.IO.DirectoryInfo di;
System.IO.FileInfo[] rgFiles;
//digitally sign an existing signature field (the name of the field must be known)
File.WriteAllBytes(signedDocument, ps.ApplyDigitalSignature("Signature1"));
To verify the digital signatures added to PDF document, use the following code:
using SignLib.Certificates;
using SignLib.Pdf;
ExtractCertificateInformation(csi.SignatureCertificate);
Console.WriteLine(Environment.NewLine);
} //foreach
} //method
using SignLib.Pdf;
sourceFiles.Add(File.ReadAllBytes("d:\\1.pdf"));
sourceFiles.Add(File.ReadAllBytes("d:\\2.pdf"));
sourceFiles.Add(File.ReadAllBytes("d:\\3.pdf"));
sourceFiles.Add(File.ReadAllBytes("d:\\4.pdf"));
File.WriteAllBytes("d:\\merge.pdf", PdfMerge.MergePdfFiles(sourceFiles));
/***************************
Insert images on PDF document
***************************/
PdfInsertImage.LoadPdfDocument("c:\\source.pdf");
//adds an image on a specific rectangle location on the page 1. The image will be
placed over the PDF content of the page.
PdfInsertImage.AddImage(File.ReadAllBytes("c:\\watermark.png"), new
System.Drawing.Rectangle(10, 10, 100, 100), 1, ImagePosition.ImageOverContent);
//adds an image that will cover all the page 2. The image will be placed under the
PDF content (backgorund) of the page.
PdfInsertImage.AddImage(File.ReadAllBytes("c:\\watermark.png"), 2,
ImagePosition.ImageUnderContent);
//adds an image that will start on a specific starting position on the page 3. The
image will not be resized. The image will be placed over the PDF content of the
page.
PdfInsertImage.AddImage(File.ReadAllBytes("c:\\watermark.png"), new
System.Drawing.Point(200, 200), 3, ImagePosition.ImageOverContent);
//adds an image on all document pages under the text in the middle.
PdfInsertImage.AddImage(File.ReadAllBytes("c\\watermark.png"), new
System.Drawing.Rectangle(PdfInsertImage.DocumentProperties.DocumentPageSize(3).X /
2, PdfInsertImage.DocumentProperties.DocumentPageSize(3).Y / 2, 100, 100), 0,
ImagePosition.ImageUnderContent);
/***************************
Insert texts on PDF document
*****************************/
//The smart card PIN dialog can be bypassed for some smart cards/USB Tokens.
//ATTENTION: This feature will NOT work for all available smart card/USB Tokens
becauase of the drivers or other security measures.
//Use this property carefully.
//DigitalCertificate.SmartCardPin = "123456";
cs.SignatureStandard = SignLib.SignatureStandard.Cades;
using SignLib.Certificates;
using SignLib.Cades;
//The smart card PIN dialog can be bypassed for some smart cards/USB Tokens.
//ATTENTION: This feature will NOT work for all available smart card/USB Tokens
becauase of the drivers or other security measures.
//Use this property carefully.
//DigitalCertificate.SmartCardPin = "123456";
cs.SignatureStandard = SignLib.SignatureStandard.Pkcs7;
using SignLib.Certificates;
using SignLib.Cades;
ExtractCertificateInformation(csi.SignatureCertificate);
if (csi.SignatureIsTimestamped == true)
{
Console.WriteLine("Hash Algorithm: " +
csi.TimestampInfo.HashAlgorithm.FriendlyName);
Console.WriteLine("Is TimestampAltered: " +
csi.TimestampInfo.IsTimestampAltered.ToString());
Console.WriteLine("TimestampSerial Number: " + csi.TimestampInfo.SerialNumber);
Console.WriteLine("TSA Certificate: " + csi.TimestampInfo.TsaCertificate.Subject);
}
Console.WriteLine(Environment.NewLine);
}
using SignLib;
using SignLib.Certificates;
cs.DigitalSignatureCertificate =
DigitalCertificate.LoadCertificate(Environment.CurrentDirectory + "\\cert.pfx",
"123456");
cs.IncludeKeyInfo = true;
cs.IncludeSignatureCertificate = true;
cs.DigitalSignatureCertificate =
DigitalCertificate.LoadCertificate(Environment.CurrentDirectory + "\\cert.pfx",
"123456");
A digital certificate can be validated against three criteria: Local time, CRL (Certificate
Revocation List) and OCSP (Online Certificate Status Protocol).
Every certificate is valid for a limited period. If a certificate is expired, it should not be used to
perform digital signatures.
For some reasons, a digital certificate could be revoked before expiration date (e.g. a person
leaves the company, the person lost the smart card, forgot the PIN, etc.).
When a certificate is revoked, the certificate serial number is added on the CRL. To verify if a
certificate is revoked, the CRL must be downloaded and check if the certificate serial number
appears on the CRL.
In some cases, the CRL is very large (more than 1MB). On this case, the OCSP protocol
verifies only a specific serial number instead downloading the entire CRL file.
if (certificate == null)
throw new Exception("No certificate was found or selected.");
Certificate Subject
Every certificate must have a Subject. There are two methods to set the certificate subject.
If the subject contains comma characters (“,” e.g. My Company, Subsidiary 1), the first
method must be used. The Subject can contains Unicode characters like ä,æ, £, Ñ.
1. Manually set every SubjectType of the certificate using the following code:
using SignLib.Certificates;
Certificate Subject
using SignLib.Certificates;
Observation: On the demo version of the library, the certificate validity cannot exceed 30
days.
To set the key size and the signature algorithm of the certificate, use the following code:
using SignLib.Certificates;
The default value of KeySize property is KeySize.KeySize1024Bit and should be enough for
common certificates. For the Root certificates a 2048 key can be used.
Observation: The certificate will requires more time to be generated if a larger key size is
used.
The serial number can be lately used to identify a certificate but, according to X.509 standard,
the certificate serial number appears on the digital certificate in hexadecimal notation. To set
the serial number in hexadecimal format, use the code below:
When the certificate is imported to Microsoft Store, it will appear on the certificate list. If more
certificates has the same subject, in order to identify a specific certificate, FriendlyName
property can be set.
A CA, user, computer, network device, or service can have more than one certificate. The Key
Usage extension defines the security services for which a certificate can be used. The options
can be used in any combination and can include the following:
DataEncipherment - The public key can be used to directly encrypt data, rather than
exchanging a symmetric key for data encryption.
DigitalSignature - The certificate use the public key for verifying digital signatures that have
purposes other than non-repudiation, certificate signature, and CRL signature.
KeyEncipherment - The certificate use the public key for key transport.
NonRepudiation - The certificate use the public key for verifying a signature on CRLs.
CRLSigning - The certificate use the public key for verifying a signature on certificates.
CertificateSigning - The certificate use the public key for key agreement.
KeyAgreement - The certificate public key may be used only for enciphering data while
performing key agreement.
EncipherOnly - The certificate public key may be used only for enciphering data while
performing key agreement.
DecipherOnly - The certificate public key may be used only for enciphering data while
performing key agreement.
For a simple certificate, the most used Key Usages are: DigitalSignature, NonRepudiation,
KeyEncipherment and DataEncipherment.
For a Root Certificate (CA certificate), the most used Key Usages are: CertificateSigning and
CRLSigning.
cert.Extensions.AddKeyUsage(CertificateKeyUsage.DigitalSignature);
cert.Extensions.AddKeyUsage(CertificateKeyUsage.NonRepudiation);
cert.Extensions.AddKeyUsage(CertificateKeyUsage.KeyEncipherment);
cert.Extensions.AddKeyUsage(CertificateKeyUsage.DataEncipherment);
This extension indicates how a certificate’s public key can be used. The Enhanced Key Usage
extension provides additional information beyond the general purposes defined in the Key
Usage extension. For example, OIDs exist for Client Authentication (1.3.6.1.5.5.7.3.2), Server
Authentication (1.3.6.1.5.5.7.3.1), and Secure E-mail (1.3.6.1.5.5.7.3.4).
The library supports a lot of well known Enhanced Key Usages but also support to specify a
custom Enhanced Key Usage extension.
TimeStamping - The certificate can be used for signing public key infrastructure timestamps
according to RFC 3161.
To add Enhanced Key Usage to a digital certificate, use the following code:
cert.Extensions.AddEnhancedKeyUsage(CertificateEnhancedKeyUsage.SmartcardLogon);
cert.Extensions.AddEnhancedKeyUsage(CertificateEnhancedKeyUsage.TimeStamping);
cert.Extensions.AddEnhancedKeyUsage(CertificateEnhancedKeyUsage.SecureEmail);
cert.Extensions.AddEnhancedKeyUsage(new
System.Security.Cryptography.Oid("1.2.3.4.5.6.7.8.9.10.11"));
In some scenarios, Key Usage or Enhanced Key Usage must be set as Critical extension.
By default, these properties are considered non-critical but the behavior can be changed as
below:
cert.Extensions.AddEnhancedKeyUsage(CertificateEnhancedKeyUsage.TimeStamping);
cert.Extensions.AddEnhancedKeyUsage(CertificateEnhancedKeyUsage.SecureEmail);
cert.Extensions.AddEnhancedKeyUsage(new
System.Security.Cryptography.Oid("1.2.3.4.5.6.7.8.9.10.11"));
using SignLib.Certificates;
cert.Extensions.AddKeyUsage(CertificateKeyUsage.DigitalSignature);
cert.Extensions.AddKeyUsage(CertificateKeyUsage.NonRepudiation);
cert.Extensions.AddEnhancedKeyUsage(CertificateEnhancedKeyUsage.DocumentSigning);
cert.Extensions.AddEnhancedKeyUsage(CertificateEnhancedKeyUsage.SecureEmail);
A self-signed certificate
using SignLib.Certificates;
Note that creating a Root certificate is very similar with creating a self signed certificate. The
only main difference is on the second parameter of GenerateCertificate() method that must be
set to true.
Also, some Key Usage extension is automatically added for a Root Certificate as below:
To issue a digital certificate signed by a Root Certificate, use the code below:
using SignLib.Certificates;
File.WriteAllBytes("c:\\user.pfx", cert.GenerateCertificate("123456"));
The certificates stored on Microsoft Store are available by opening Internet Explorer – Tools
menu – Internet Options – Content tab – Certificates button (see below) or by entering
certmgr.msc command on Run window.
For digital signatures, the certificates stored on Personal tab are used. These certificates
have a public and a private key.
The Root Certificates are stored on Trusted Root Certification Authorities tab.
The digital signature is created by using the private key of the certificate. The private key can
be stored on the file system (imported PFX files), on a cryptographic smart card (like Aladdin
eToken or SafeNet iKey) or on a HSM (Hardware Security Module).
For encryption, only the public key of the certificate is necessary (certificates stored on
Personal or Other People tabs).
Another way to store a digital certificate is a PFX (or P12) file. This file contain the public and
the private key of the certificate. This file is protected by a password in order to keep safe the
key pair.
The PFX file can be imported on Microsoft Store (just open the PFX file and follow the
wizard).
Trusting Certificates
When a user certificate is issued by a Root Certificate, in order to trust the user certificate, the
Root Certificate must be imported on Microsoft Store – Trusted Root Certification Authorities.
When the PFX user certificate is imported on Microsoft Store, the Root Certificate can be also
imported as follow:
At this step, the Root Certificate is imported and every certificate issued by this Root is
Anyway, if a document or email message is digitally signed by the client certificate and the
document/email is opened on other computer, the digital signature might be considered
untrusted because the Root certificate is not imported on that computer so the Root
Certificate must be manually imported on every client machine that will be related with
this certificate.
Because the Root Certificate is not included by default in Microsoft Store – Trusted Root
Certification Authorities, the Root Certificate that issues the User Certificate must be imported
on that store when the PFX certificate is imported.
More advanced options to manually install certificates on the client machines are available by
using Certmgr.exe (Certificate Manager Tool).
using System.Security.Cryptography.X509Certificates;
try
{
var cert = new X509Certificate2(File.ReadAllBytes("c:\\root.cer"));
//use dirrectly the PFX
//var cert = new X509Certificate2("c:\\root.pfx", "Root_password");
store.Add(cert);
}
finally
{
store.Close();
}
Digital certificates can be used for digitally sign PDF, Office, XPS documents or email
messages.
The time digital signature certificate profile will look like this:
- It is recommended to be issued by a Root Certificate (not self signed certificate).
- Use RSA1024 key size (or RSA 2048 for more security).
- Key Usage: Digital Signature.
- Extended Key Usage - add ONLY Time Stamping extension (OID: 1.3.6.1.5.5.7.3.8) marked
as critical.
- Expiration date: 1 year or more.
In order to create a certificate for digital signature, use the code below:
File.WriteAllBytes("C:\\root.pfx", root.GenerateCertificate("Root_password",
true));
File.WriteAllBytes("c:\\userCertificate.pfx",
cert.GenerateCertificate("user_password"));
After the certificate is created and imported, it can be used for digital signature.