The PDFSigner class signs PDF documents digitally.
PDFSigner can sign PDF documents in accordance with a selection of PDF and PAdES signature standards.
Standards and technologies supported
PDFSigner can create PDF signatures that match the following baseline standards:
- Generic PDF signatures (ISO 32000)
- PAdES: all profiles are supported (BES, EPES, T, LTV, B-B, B-T, and others) (ETSI EN 319 142-1 and others)
- Signature and document timestamps using external TSAs.
- All industry-standard cryptographic algorithms (RSA, ECDSA, SHA256-512, and many others).
Configuring the signature spec
Configuring PDFSigner to produce signatures of the right type is one of the most important questions you need to address. Normally the service or software you will be communicating your PDF documents to will provide you with the list of requirements that your signatures should match.
Typically, those will dictate the following key aspects of the signatures:
- Level (BES, T, or LTV). This can be adjusted with the Level property (Note: when creating EPES signatures you need to provide the signature PolicyID and PolicyHash properties).
- Timestamp requirement: provide the address of your online TSA service via TimestampServer property.
- When creating LTV signatures, tune up validation parameters via RevocationCheck, OfflineMode, and IgnoreChainValidationErrors properties.
- To create a document timestamp, sign your document first, and then sign the result again with Level set to pslDocumentTimestamp and TimestampServer pointing to the TSA URL.
PDFSigner can use certificates residing on different media. Besides generic certificates stored in PFX or PEM files (A1), it can operate with non-exportable certificates residing on hardware media (A3) or in the cloud.
Non-exportable certificates can be accessed transparently via a Windows CSP or a PKCS#11 driver, if supplied by the certificate issuer. Proprietary interfaces can be plugged in with the external signing feature (see below).
You can use CertificateManager and CertificateStorage components to load the signing certificate. Assign the certificate to SigningCertificate property, and optionally provide the remainder of its chain via SigningChain property.
Note: If signing with a non-exportable key (such as residing on a hardware device or in the cloud), please make sure you keep the original CertificateStorage object open until the signing is completed. This is because the storage component provides a 'bridge' to the private key. If the storage is closed prematurely, this bridge is destroyed, and the private key can't be used.
You don't need to provide a signing certificate or chain when creating document timestamp signatures, since this type of signatures is done with a TSA's certificate.
PDFSigner provides means to customize the look of the signature widget to be shown on the document page. Create your very own signatures in the form of your company's logo, a handwritten signature, or a wet seal.
Alternatively, you can choose not to associate any widget with your signature by setting Invisible to true.
Signing the document
Now that you have set up all signature, certificate, and widget properties, it is time to sign. You can provide the input document in one of the following forms: as a file (assign the path to InputFile property), as a stream (assign to InputStream property), or as a byte array (assign to InputBytes). Similarly, the output can be collected in one of the same forms, either by passing the destination path or stream via OutputFile and OutputStream respectively, or by reading the resulting document bytes from the OutputBytes property after the signing.
Having set up the input and output, call the component's Sign method. This will initiate the signing process. Depending on the settings, the signing may be as straightforward as calculating the document hash and signing it with the private key (e.g. in PAdES-BES signing variant), or it may involve advanced chain validation routines (PAdES-LTV). During the latter the component may contact a number of external revocation information sources (CRL and OCSP servers) to establish the validity of the signing certificate.
If a TSA server was provided via the TimestampServer property, the component will contact it too to timestamp the new signature.
During the signing PDFSigner may fire events to let your code know of certain conditions. If the input document is encrypted but no decryption parameters were found in Password and DecryptionCertificate properties, the component would fire DecryptionInfoNeeded event to tell your code that it needs decryption information to be able to continue with the signing. It may fire TLSCertValidate if one of the HTTP endpoints involved during the operation (which may be a CRL, OCSP, or TSA service) works over TLS and needs its certificate to be validated.
External signing and DCAuth
PDFSigner, like many other components offered by the product, supports two methods of signing with external keys. These methods are fully independent of each other: you can choose the one that suits your usage scenario best.
Synchronous method: ExternalSign
This is a simpler method that basically lets you infiltrate into the heart of the signing routine by taking care of the hash signing operation. The component does the rest of the job (hash calculation, preparation of signature objects, CRL/OCSP retrieval).
To initiate this method, call SignExternal instead of Sign. When the hash is ready, it will be passed back to your code with ExternalSign event. Your event handler needs to sign the hash with the private key and return the created signature back to the component - which will embed it into the document.
You don't need your signing certificate to contain an associated private key when using this method. The certificate itself (its public copy) may be needed though, as it is often included in the hash calculation.
This method is synchronous, meaning SignExternal provides you the results immediately upon its completion.
Asynchronous method: DCAuth
DCAuth is a SecureBlackbox know-how technology. This protocol was designed to allow sharing of private keys across environments, allowing the signer and the private key to reside on different systems. It works in the following way:
- The signing party - such as PDFSigner - initiates the operation using SignAsyncBegin call. This produces two outcomes: a pre-signed document (a document with a blank signature placeholder), and a request state (an object containing a hash that needs to be signed). At this point the PDFSigner instance can be released, and the process itself terminated (which may be useful when run as part of a web page).
- The request state is passed to the private key holder party. The private key holder passes the request state to a DCAuth object, which parses the request state, extracts the hash, and signs it. The output of DCAuth processing is another object, response state, which contains the signature. The private key holder then sends the response state back to the signing party.
- The signing party re-creates the controls, and passes the response state, together with the pre-signed version of the document, to the signer's SignAsyncEnd method. SignAsyncEnd extracts the signature from the response state and incorporates it into the pre-signed document.
This method is asynchronous in that sense that, from the signing party's viewpoint, it splits the signing operation into the pre-signing and completion stages which can be performed independently from each other and in different execution contexts. This makes this method particularly helpful for use in web pages and other scenarios where the signing key is not available in real time.
Fine-grained chain validation setup
Chain validation is a sophisticated, multi-faceted procedure that involves a lot of variables. Depending on the configuration of your operating environment, the specifics of the PKI framework being used, and the validation policy you need to follow, you may want to tune up your chain validation parameters so they fit them best. Below is given a summary of such parameters.
- RevocationCheck property lets you choose between and/or prioritize revocation origins. OCSP sources are often preferred to CRL because of their real-time capability and the smaller size of validation tokens they produce.
- OfflineMode is a master switch that stops class from looking for any validation tokens online. If this property is switched on, the component will only use KnownCertificates, TrustedCertificates, KnownCRLs, and KnownOCSPs collections to look for the missing validation material.
- IgnoreChainValidationErrors makes the component ignore any major validation issues it encounters (such us an untrusted chain or missing CRL). This option is handy for debugging and for creating signatures in the environments where the signing certificate is not trusted.
- KnownCertificates, KnownCRLs, and KnownOCSPs let you provide your own validation material. This may be useful when working in OfflineMode, where the signer has no access to the validation sources, or where the validation material has already been collected.
- TrustedCertificates lets you provide a list of trust anchors, either as a complement to the system's or as an alternative for it.
- BlockedCertificates lets you provide a list of blocked/distrusted certificates. Any CA certificate contained in it will be deemed untrusted/invalid.
The following parameters are not directly related to chain validation, but may have an implicit effect on it.
- Proxy, SocketSettings, and TLSSettings let you tune up the connectivity and TLS options in accordance with local preferences.
- TLSClientChain lets you provide the client certificate and its chain for TLS client authentication.
- Subscribe to TLSCertValidate to validate any TLS certificates of the services involved in chain validation.
The results of the chain validation procedure, upon its completion, are published in the following properties:
- ChainValidationResult contains the primary result of the chain validation routine: valid, valid but untrusted, invalid, or undefined.
- ChainValidationDetails provides the details of the factors that contributed to the chain validation result, such as an outdated certificate, a missing CRL, or a missing CA certificate.
- ValidationLog contains the detailed chain validation log. The log can often be very helpful in nailing down various validation issues.
The following is the full list of the properties of the class with short descriptions. Click on the links for further details.
|BlockedCertificates||The certificates that must be rejected as trust anchors.|
|ClaimedSigningTime||The signing time from the signer's computer.|
|DecryptionCertificate||A decryption certificate.|
|DecryptionCertificates||A collection of decryption certificates.|
|EmptyFieldIndex||Specifies the index of the empty signature field to sign.|
|Encrypted||Indicates if the PDF document is encrypted.|
|EncryptionAlgorithm||The symmetric algorithm used to encrypt the document.|
|EncryptionType||The document encryption type.|
|ExternalCrypto||Provides access to external signing and DC parameters.|
|FieldIndex||Specifies the index of the signature field to update.|
|IgnoreChainValidationErrors||Makes the class tolerant to chain validation errors.|
|InputBytes||Use this property to pass the input to class in the byte array form.|
|InputFile||The PDF file to be signed or updated.|
|InputStream||A stream containing the PDF document to be signed or updated.|
|KnownCertificates||Additional certificates for chain validation.|
|KnownCRLs||Additional CRLs for chain validation.|
|KnownOCSPs||Additional OCSP responses for chain validation.|
|MetadataEncrypted||Indicates if the document metadata is encrypted.|
|OfflineMode||Switches the class to the offline mode.|
|OutputBytes||Use this property to read the output the class object has produced.|
|OutputFile||The file to save the signed or updated document to.|
|OutputStream||The stream to write the signed document to.|
|Password||The decryption password.|
|Permissions||Contains the document permissions associated with the encryption.|
|Profile||Specifies a pre-defined profile to apply when creating the signature.|
|Proxy||The proxy server settings.|
|RevocationCheck||Specifies the kind(s) of revocation check to perform.|
|Signature||Provides access to signature properties.|
|SigningCertificate||The certificate to be used for signing.|
|SigningChain||The signing certificate chain.|
|SocketSettings||Manages network connection settings.|
|TimestampServer||The address of the timestamping server.|
|TLSClientChain||The TLS client certificate chain.|
|TLSServerChain||The TLS server's certificate chain.|
|TLSSettings||Manages TLS layer settings.|
|TrustedCertificates||A list of trusted certificates for chain validation.|
|ValidationLog||Contains the complete log of the certificate validation routine.|
The following is the full list of the methods of the class with short descriptions. Click on the links for further details.
|Config||Sets or retrieves a configuration setting.|
|ExtractAsyncData||Extracts user data from the DC signing service response.|
|Sign||Signs a PDF document.|
|SignAsyncBegin||Initiates the asynchronous signing operation.|
|SignAsyncEnd||Completes the asynchronous signing operation.|
|SignExternal||Signs the document using an external signing facility.|
|Update||Updates a signature.|
The following is the full list of the events fired by the class with short descriptions. Click on the links for further details.
|DecryptionInfoNeeded||Requests decryption information during decryption, signing, or validation.|
|Error||Information about errors during signing/validation.|
|ExternalDecrypt||Handles remote or external decryption.|
|ExternalSign||Handles remote or external signing initiated by the SignExternal method or other source.|
|Notification||This event notifies the application about an underlying control flow event.|
|RecipientFound||Provides recipient certificate details to the application.|
|TLSCertValidate||This event is fired upon receipt of the TLS server's certificate, allowing the user to control its acceptance.|
The following is a list of configuration settings for the class with short descriptions. Click on the links for further details.
|AssemblyOptions||Specifies the assembly options.|
|AutoCollectRevocationInfo||Whether revocation info should be collected automatically.|
|AutoRotateSignature||Specifies whether to auto-rotate signature widget.|
|BackgroundPosition||Specifies the background position.|
|CollectRevInfoForTimestamps||Whether revocation info for timestamps should be collected automatically.|
|CustomTextCount||The number of custom text block on the signature widget.|
|CustomTextFontResourceName[Index]||The font resource name to use for the custom text block.|
|CustomTextFontSizeX[Index]||The horizontal font size scale.|
|CustomTextFontSizeY[Index]||The vertical font size scale.|
|CustomTextText[Index]||A text to show on a custom signature widget text block.|
|CustomTextX[Index]||The horizontal offset of the text block.|
|CustomTextY[Index]||The vertical offset of the text block.|
|DeepValidation||Whether a complete validation should be performed.|
|EmptyFullFieldName||Specifies the full name of the empty signature field to sign.|
|EmptySignatureFieldAddRevInfo[Index]||Specifies if revocation checking should be performed.|
|EmptySignatureFieldAlternateName[Index]||Contains an alternate field name.|
|EmptySignatureFieldCount||The number of empty signature form fields.|
|EmptySignatureFieldFlags[Index]||The field flags of the signature form field.|
|EmptySignatureFieldHeight[Index]||The Height of the empty signature form field.|
|EmptySignatureFieldInvisible[Index]||The visibility status of the field.|
|EmptySignatureFieldLegalAttestations[Index]||Specifies the legal attestations that are associated with the signature.|
|EmptySignatureFieldMappingName[Index]||The mapping name to be used when exporting form field data from the document.|
|EmptySignatureFieldName[Index]||Textual field name.|
|EmptySignatureFieldOffsetX[Index]||The field's offset from the left page border.|
|EmptySignatureFieldOffsetY[Index]||The field's offset from the bottom page border.|
|EmptySignatureFieldPage[Index]||The index of the form field's page in the document.|
|EmptySignatureFieldRequiredAllowedChanges[Index]||Specifies the changes allowed by the signature.|
|EmptySignatureFieldRequiredConstraints[Index]||Specifies the required Seed Value Dictionary (SVD) constraints.|
|EmptySignatureFieldRequiredDigestAlgorithms[Index]||Specifies the required digest algorithms.|
|EmptySignatureFieldRequiredFilter[Index]||Specifies the required filter.|
|EmptySignatureFieldRequiredLockAction[Index]||Indicates which set of fields shall be locked.|
|EmptySignatureFieldRequiredLockFields[Index]||Indicates the fields that shall be locked on signing.|
|EmptySignatureFieldRequiredReasons[Index]||Specifies the required reasons.|
|EmptySignatureFieldRequiredSubfilters[Index]||Specifies the required subfilters.|
|EmptySignatureFieldTimestampRequired[Index]||Specifies if the signature should be time-stamped.|
|EmptySignatureFieldTSPURL[Index]||URL for a TSP server.|
|EmptySignatureFieldWidth[Index]||The Width of the empty signature form field.|
|EncryptionHandlerName||Specifies the custom security handler PDF-name.|
|ExtensionIdentifierMode||Specifies the extension identifier mode.|
|ExtraSpace||Allows the allocation of extra zero character space in the document behind the signature.|
|ForceCompleteChainValidation||Whether to check issuer (CA) certificates when signing certificate is invalid.|
|ForceCompleteChainValidationForTrusted||Whether to continue with the full validation up to the root CA certificate for mid-level trust anchors.|
|GracePeriod||Specifies a grace period to apply during revocation information checks.|
|HardenedKeyGeneration||Specifies if hardened Key generation should be used.|
|IgnoreOCSPNoCheckExtension||Whether OCSP NoCheck extension should be ignored.|
|IgnoreSystemTrust||Whether trusted Windows Certificate Stores should be treated as trusted.|
|IgnoreTimestampFailure||Whether to ignore time-stamping failure during signing.|
|ImplicitlyTrustSelfSignedCertificates||Whether to trust self-signed certificates.|
|IncludeKnownRevocationInfoToSignature||Whether to include custom revocation info to the signature.|
|IncludeRevocationInfoToAdbeAttribute||Whether to save revocation info in PDF-compliant form.|
|LastSignatureWidget||Specifies that it is the last signature widget to be added.|
|PAdESOptions||Specifies the PAdES options.|
|PageInfoCount||The number of pages.|
|PageInfoCropBoxEmpty[Index]||Check if the page's crop box is empty or not.|
|PageInfoCropLLX[Index]||Defines the X coordinate of the lower left corner of the crop box.|
|PageInfoCropLLY[Index]||Defines the Y coordinate of the lower left corner of the crop box.|
|PageInfoCropURX[Index]||Defines the X coordinate of the upper right corner of the crop box.|
|PageInfoCropURY[Index]||Defines the Y coordinate of the upper right corner of the crop box.|
|PageInfoHeight[Index]||The Height of the page.|
|PageInfoMediaLLX[Index]||Defines the X coordinate of the lower left corner of the media box.|
|PageInfoMediaLLY[Index]||Defines the Y coordinate of the lower left corner of the media box.|
|PageInfoMediaURX[Index]||Defines the X coordinate of the upper right corner of the media box.|
|PageInfoMediaURY[Index]||Defines the Y coordinate of the upper right corner of the media box.|
|PageInfoRotate[Index]||The Rotate value of the page.|
|PageInfoUserUnit[Index]||Defines the size of default user space units.|
|PageInfoWidth[Index]||The Width of the page.|
|PolicyExplicitText||The explicit text of the user notice.|
|PolicyUNNumbers||The noticeNumbers part of the NoticeReference PAdES-EPES attribute.|
|PolicyUNOrganization||The organization part of the NoticeReference qualifier.|
|PolicyURI||The URI of the signature policy.|
|PositionAnchor||Specifies the signature widget position anchor.|
|PredefinedSignatureSize||User-defined size of the signature.|
|PromoteLongOCSPResponses||Whether long OCSP responses are requested.|
|RC4KeyBits||Specifies the number of key bits used for RC4 algorithm.|
|SchemeParams||The algorithm scheme parameters to employ.|
|SignatureCount||The number of signatures.|
|SignatureHeight[Index]||The Height of the signature widget.|
|SignatureInvisible[Index]||The visibility status of the signature.|
|SignatureName[Index]||Textual signature name.|
|SignatureOffsetX[Index]||The siganture widget's offset from the left page border.|
|SignatureOffsetY[Index]||The signature widget's offset from the bottom page border.|
|SignatureOptions||Specifies the signature options.|
|SignaturePage[Index]||The index of the signature widget's page in the document.|
|SignatureSizeEstimationStrategy||Which mechanism to use to estimate the size of a PAdES signature.|
|SignatureWidth[Index]||The Width of the signature widget.|
|TempPath||Location where the temporary files are stored.|
|TextObjEncoding||The encoding to apply to string objects stored with the signature.|
|TLSChainValidationDetails||Contains the advanced details of the TLS server certificate validation.|
|TLSChainValidationResult||Contains the result of the TLS server certificate validation.|
|TLSClientAuthRequested||Indicates whether the TLS server requests client authentication.|
|TLSValidationLog||Contains the log of the TLS server certificate validation.|
|TolerateMinorChainIssues||Whether to tolerate minor chain issues.|
|TspHashAlgorithm||Sets a specific hash algorithm for use with the timestamping service.|
|TspReqPolicy||Sets a request policy ID to include in the timestamping request.|
|UpdateKind||Adjusts the scope of modifications that are made to the signature with the Update method.|
|UseLegacyVisualStyle||Specifies whether to use legacy signature visual style.|
|UseMicrosoftCTL||Enables or disables automatic use of Microsoft online certificate trust list.|
|UsePSS||Whether to use RSASSA-PSS algorithm.|
|UseSystemCertificates||Enables or disables the use of the system certificates.|
|UseValidationCache||Enables or disable the use of the product-wide certificate chain validation cache.|
|CheckKeyIntegrityBeforeUse||Enables or disable private key integrity check before use.|
|CookieCaching||Specifies whether a cookie cache should be used for HTTP(S) transports.|
|Cookies||Gets or sets local cookies for the class (supported for HTTPClient, RESTClient and SOAPClient only).|
|DefDeriveKeyIterations||Specifies the default key derivation algorithm iteration count.|
|EnableClientSideSSLFFDHE||Enables or disables finite field DHE key exchange support in TLS clients.|
|GlobalCookies||Gets or sets global cookies for all the HTTP transports.|
|HttpUserAgent||Specifies the user agent name to be used by all HTTP clients.|
|LogDestination||Specifies the debug log destination.|
|LogDetails||Specifies the debug log details to dump.|
|LogFile||Specifies the debug log filename.|
|LogFilters||Specifies the debug log filters.|
|LogFlushMode||Specifies the log flush mode.|
|LogLevel||Specifies the debug log level.|
|LogMaxEventCount||Specifies the maximum number of events to cache before further action is taken.|
|LogRotationMode||Specifies the log rotation mode.|
|MaxASN1BufferLength||Specifies the maximal allowed length for ASN.1 primitive tag data.|
|MaxASN1TreeDepth||Specifies the maximal depth for processed ASN.1 trees.|
|OCSPHashAlgorithm||Specifies the hash algorithm to be used to identify certificates in OCSP requests.|
|UseOwnDNSResolver||Specifies whether the client classes should use own DNS resolver.|
|UseSharedSystemStorages||Specifies whether the validation engine should use a global per-process copy of the system certificate stores.|
|UseSystemOAEPAndPSS||Enforces or disables the use of system-driven RSA OAEP and PSS computations.|
|UseSystemRandom||Enables or disables the use of the OS PRNG.|