Hash Signing API
Unlike other APIs provided by Signature Service, the hash signing APIs do not handle document files directly. Instead, they generate a standard CMS signature container based on the provided document digest.
This approach offers maximum confidentiality and flexibility for systems implementing a digital signature workflow as the document is not transiting through the remote signing service; however, it requires additional effort during the integration process to ensure accurate signature management and seamless functionality.
Digital signature in a PDF
Integrating the signing service to digitally sign PDF files requires careful preparation due to the specific characteristics of the PDF format. A common mistake is using the digest of the entire raw document as the digest to be signed, which results in invalid signatures.
The correct implementation involves preparing the signature dictionary with optional signature appearance settings and relevant metadata, such as the signing time, reason, and location. The signature dictionary also includes the /ByteRange attribute, which defines the portions of the document that must be signed. This range specifically excludes the /Contents attribute, which will later store the actual signature.
The digest of the data to be signed, as defined by the /ByteRange attribute, is then computed and sent to the Signature Service remote signing service using the APIs described in this document.
Once the signature is obtained, it must be embedded back into the document by placing it within the /Contents attribute of the signature dictionary.
For a comprehensive guide on integrating digital signatures into PDF files, refer to Adobe’s official documentation: Digital Signatures in a PDF.
Extending to PAdES Baseline-LT
For enhanced long-term validation, the final step is to extend the PAdES signature to Baseline LT by embedding all necessary revocation materials, such as OCSP responses and CRL data for all certificates, into the document. While optional in some cases, this step is highly recommended as it ensures lifetime offline validation of the signatures.
APIs Endpoints
Requesting a signature
The digest(s) to be signed are provided in the /signDoc API with the signing service profile and other meta data that might be required by the requested service.
If the chosen signing service supports batch signing (signing multiple digests at once), multiple digests can be provided in the hashes array, and the ids array must be provided with associated ids for each hash in the array.
signDoc API request body
{
"documentDigests": { <1>
"hashAlgorithmOID": "2.16.840.1.101.3.4.2.1", <2>
"hashes": [
"n4bQgYhMfWWaL+qgxVrQFaO/TxsrC4Is0V1sFbDwCgg=" <3>
],
"ids": [] <4>,
"titles": [] <5>
},
"signingServiceProfile": "signing-profile-identifier", <6>
"lang": "en", <7>
"metadata": { <8>
"key": "value"
},
"signatureClientConfiguration": {}, <9>
"userID": "testUser" <10>
}- Document digest(s) to be signed. Cannot be set in conjunction with the `documents' attribute.
- Hashing algorithm OID used to compute the document hash(es). Currently only SHA-256 is supported.
- Base64-encoded document(s) hash(es), to be signed. If more than one digest is provided, the signing service must support batch signing.
- Optional ids, only required if multiple document digests are available.
- Optional titles, required only for specific signing service profiles.
- The signing service profile identifier. Must be enabled for the current organisation.
- The preferred language of the SCS responses, specified according to RFC5646
- Collection of generic metadata required by the targeted
signingServiceProfile, see example section for additional details - Optional signature client configuration, may be required depending the
signingServiceProfile, see example section for additional details - The identifier of to the user signing the request
The API returns a JSON object represented as below.
For signing services that do not require user authentication (e.g Electronic Seal), the status of the response is directly SUCCESS and the signature(s) is provided in the signature or signatures attributes without the need of a further call to the back-end.
A status with value PENDING means that the signature request requires a user authentication. The authenticationUrl must be provided to the end user to initiate the authentication process.
signDoc response body
{
"status": "PENDING", <1>
"responseID": "WyJjZDdmNzQxYi1hZTVkLTQzNDEtOTBlMy1iYjQ4YzJk", <2>
"authenticationUrl": "https://sign.swisssign.com/websic/...", <3>
"signature": null, <4>
"signatures": null, <5>
"error": null, <6>
"errorMessage": null <7>
}- Status of the signature request. Can be
PENDING,SUCCESS,CANCEL,TIMEOUT,ERROR - Response identifier to be used as 'requestID' when requesting signature status, when status is 'PENDING'.
- Authentication URL to display to end-user, when step-up authentication is required to sign
- Signature value, when a single signature has been requested
- Signature values, when multiple signatures have been requested
- Error code, in case the 'status' component is set to 'ERROR'
- End-user error message, in case the 'status' component is set to 'ERROR'
Please refer to the examples section for detailed example of signature requests for our different signing services.
Polling signature status
In the case of asynchronous processing awaiting user authentication, the status of the signature request can be retrieved using the /signPolling API with the following request body :
signPolling request body
{
"requestID": "responseID" <1>
}- Value of the
responseIDattribute received in response of thesignDocAPI
The response body is the identical to the signDoc API.
Once a status different than PENDING is returned to the Relying-Party system, the request is permanently removed from our system and the request's status can't be retrieved anymore.
Callbacks are not supported for hash signing signature requests.
Examples
Electronic Seal
The example below demonstrates how to use the SCS APIs with an electronic seal, for Simple Electronic Signature or Document certification purpose.
cURL example for electronic seal signing service
curl --location \
--request POST 'https://mtl.sandbox.pre.swissid.ch/rss/admin/admin/api/v3/organizations/\{organizationId}/signatures/signDoc' \
--header 'Content-Type: application/json' \
--user 'username:password' --cert-type P12 --cert client-cert.p12:password \
--data-raw '{
"documentDigests": {
"hashAlgorithmOID": "2.16.840.1.101.3.4.2.1"
"hashes" : [
"n4bQgYhMfWWaL+qgxVrQFaO/TxsrC4Is0V1sFbDwCgg="
]
},
"signingServiceProfile": "scs-demo-seal",
"userID": "myUserId"
}'- The
signingServiceProfilehas to be changed in production environment with the identifier of your own electronic seal. - Using this signing service, the userID is only used in signature logs. As we do not offer per-user pricing model for this service, this parameter can be omitted if you do not need to differentiate user from our usage APIs.
Electronic Seal (batch signing)
cURL example for electronic seal signing service (batch signing)
curl --location \
--request POST 'https://mtl.sandbox.pre.swissid.ch/rss/admin/admin/api/v3/organizations/\{organizationId}/signatures/signDoc' \
--header 'Content-Type: application/json' \
--user 'username:password' --cert-type P12 --cert client-cert.p12:password \
--data-raw '{
"documentDigests": {
"hashAlgorithmOID": "2.16.840.1.101.3.4.2.1"
"hashes" : [
"n4bQgYhMfWWaL+qgxVrQFaO/TxsrC4Is0V1sFbDwCgg=",
"KpdRbDVLaISM29j1SiJqClWyHtE44getbFy7nACqWuo="
],
"ids" : [
"digest1",
"digest2"
},
"signingServiceProfile": "scs-demo-seal",
"userID": "myUserId"
}'- For batch signing, the
idsis required and shall define unique identifiers of thehashes, in the same order. - The
signingServiceProfilehas to be changed in production environment with the identifier of your own electronic seal. - Using this signing service, the userID is only used in signature logs. As we do not offer per-user pricing model for this service, this parameter can be omitted if you do not need to differentiate user from our usage APIs.
Qualified Electronic Signature
The example below demonstrates how to use the SCS APIs for Qualified Electronic Signature (QES).
cURL example for qualified electronic signature use-case
curl --location \
--request POST 'https://mtl.sandbox.pre.swissid.ch/rss/admin/admin/api/v3/organizations/\{organizationId}/signatures/signDoc' \
--header 'Content-Type: application/json' \
--user 'username:password' --cert-type P12 --cert client-cert.p12:password \
--data-raw '{
"documentDigests": {
"hashAlgorithmOID": "2.16.840.1.101.3.4.2.1",
"hashes" : [
"n4bQgYhMfWWaL+qgxVrQFaO/TxsrC4Is0V1sFbDwCgg="
],
"titles": [
"Document to be signed"
]
},
"signingServiceProfile": "scs-swisssign-qes-zertes",
"lang": "de",
"metadata": {
"issuer": "SCA On Premise"
},
"signatureClientConfiguration": {
"loginHint": "user@company.com"
},
"userID": "rss_sub"
}'- The
userIDshall match therss_subattribute which is the unique identifier of the SwissID user that can be retrieved through the SwissID Introspection Endpoint. - The
loginHintis mandatory and shall match the email address of the SwissID account (emailclaim). - The
titlesis mandatory and shall represent the document(s) being signed by the user.titlesmust contain as much elements ashashes. - The
issueris mandatory and shall represent the entity submitting the signature request. - The
langselects the language of the authentication page for the user. - Issuer metadata will used by the authentication app to identify the signature request.
The authenticationUrl received in the response body shall be provided to the (link, iFrame, etc.) as it will guide the user into the confirmation of the signature using the SwissSign Wallet application.