DigitalSignature:: Signing:: DefaultHandler
This is the default signing handler which provides the ability to sign a document with the adbe.pkcs7.detached or ETSI.CAdES.detached algorithms. It is registered under the :default name.
The signing handler is used by default by all methods that need a signing handler. Therefore it is usually only necessary to provide the actual attribute values.
Note: Currently only RSA is supported, DSA and ECDSA are not. See the examples below for how to handle them using external signing.
CMS and PAdES
The handler supports the older standard of CMS signatures as well as the newer PAdES signatures specified in PDF 2.0. By default, CMS signatures are created but this can be changed by setting
signature_type to :pades.
When creating PAdES signatures the following two PAdES baseline signatures are supported: B-B and B-T. The difference between those two is that a timestamp handler was defined for B-T compatibility.
This handler provides two ways to create the CMS signed-data structure required by
By providing the signing certificate together with the signing key and the certificate chain,
HexaPDFitself does the signing internally. It is the preferred way if all the needed information is available.
By using an *external signing mechanism*, a callable object assigned to
external_signing. Here the actual signing happens “outside” of
HexaPDF, for example, in custom code or even asynchronously. This is needed in case the signing key is not directly available but only an interface to it (e.g. when dealing with a HSM).
Depending on whether
certificateis set the signing happens differently:
certificateis set, the CMS signed data object is created by
HexaPDF. The callable
external_signingobject is called with the used digest algorithm and the already digested data which needs to be signed (but not digested) and the signature returned.
If the signing process needs to be asynchronous, make sure to set the
signature_sizeappropriately, return an empty string during signing and later use Signatures.embed_signature to embed the actual signature.
Besides the required data, some optional attributes can also be specified:
Reason, location and contact information
Making the signature a certification signature by applying the DocMDP transform method and a DoCMDP permission
# Signing using certificate + key document.sign("output.pdf", certificate: my_cert, key: my_key, certificate_chain: my_chain) # Signing using an external mechanism without certificate set signing_proc = lambda do |io, byte_range| io.pos = byte_range data = io.read(byte_range) io.pos = byte_range data << io.read(byte_range) signing_service.pkcs7_sign(data).to_der end document.sign("output.pdf", signature_size: 10_000, external_signing: signing_proc) # Signing using external mechanism with certificate set signing_proc = lambda do |digest_method, hash| signing_service.sign_raw(digest_method, hash) end document.sign("output.pdf", certificate: my_cert, certificate_chain: my_chain, external_signing: signing_proc) # Signing with DSA or ECDSA certificate/keys signing_proc = lambda do |io, byte_range| io.pos = byte_range data = io.read(byte_range) io.pos = byte_range data << io.read(byte_range) OpenSSL::PKCS7.sign(certificate, key, data, certificate_chain, OpenSSL::PKCS7::DETACHED | OpenSSL::PKCS7::BINARY).to_der end document.sign("output.pdf", signature_size: 10_000, external_signing: signing_proc)
This class also serves as an example on how to create a custom handler: The public methods
sign are used by the digital signature algorithm. See their descriptions for details.
Once a custom signing handler has been created, it can be registered under the 'signature.signing_handler' configuration option for easy use. It has to take keyword arguments in its initialize method to be compatible with the Signatures#handler method.
The certificate chain that should be embedded in the PDF; usually contains all certificates up to the root certificate.
The contact information. If used, will be set on the signature dictionary.
The digest algorithm that should be used when creating the signature.
SignedDataCreator#digest_algorithm for the default value (if nothing is set) and for the allowed values.
The DocMDP permissions that should be set on the document.
A callable object for custom signing mechanisms.
The callable object has two different uses depending on whether
certificate is set:
The signing location. If used, will be set on the signature dictionary.
The reason for signing. If used, will be set on the signature dictionary.
The size of the serialized signature that should be reserved.
If this attribute is not set, an empty string will be signed using
sign to determine the signature size.
The size needs to be at least as big as the final signature, otherwise signing results in an error.
The type of signature to be written (i.e. the value of the /SubFilter key).
The value can either be :cms (the default; uses a detached CMS signature) or :pades (uses an ETSI CAdES compatible signature).
The timestamp handler that should be used for timestamping the signature.
If this attribute is set, a timestamp token is embedded into the CMS object.
Public Class Methods
Public Instance Methods
Sets the DocMDP permissions that should be applied to the document.
Valid values for
Don't set any DocMDP permissions (default).
No changes whatsoever are allowed.
Only filling in forms and signing are allowed.
Only filling in forms, signing and annotation creation/deletion/modification are allowed.
Finalizes the signature field as well as the signature dictionary before writing.
Returns the DER serialized CMS signed data object containing the signature for the given IO byte ranges.
byte_range argument is an array containing four numbers [offset1, length1, offset2, length2]. The offset numbers are byte positions in the
io argument and the to-be-signed data can be determined by reading length bytes at the offsets.