Skip to main content

Create a Authorized Signature Request

Issue a Signature Request

Create RSA Approval Key

This example shows how to create a signature request that requires approval based on the key policy rule ruleUse. Since the key is an SKA key (a key with a policy), the request isn't executed immediately and must be approved by the designated approver approverx.

POST /v1/sign

{
"signRequest": {
"payload": "QXBwcm92ZVNpZ25UYXNrUGF5bG9hZA==", # base64 encoded payload
"payloadType": "UNSPECIFIED",
"signKeyName": "TSB_TUTORIAL_1-RSA", # adjust the keyname to your previously created key defined as `label` in POST: /v1/key
"signatureAlgorithm": "SHA256_WITH_RSA"
}
}

Response: Status: 201

Interpreting the response

The response is not the actual signature, rather an uuid you will use in the final step, once the quorum is met and all approvals have been given. The uuid should be stored in the business app.

{
"signRequestId": "4e8731d8-0ae6-4444-8a8c-b73ab5f0ba18"
}

Fetch an approval task

To approve the original sign request, the approver has to fetch and solve a challenge first.

Fetch Approval Task

The script Sign Timestamp signs the current Timestamp of the system "timestamp": "2023-10-30T17:30:24+00:00", with the approvers private key and generates a request-body to be sent to TSB.

Run: ./sign_timestamp_rsa.sh approverx

The output of the script should be sent to the endpoint: /v1/filteredSignApprovalTask to fetch the challenge

Prove

In order to receive the challenge for a specific approver, one must prove that he possess the approver's private key. The prove is given by signing the current timestamp, doing this introduces a mitigation to prevent replay attacks.

POST /v1/filteredSignApprovalTask

{
"timestamp": "2023-10-30T17:30:24+00:00",
"timestampSignature": "VuZ0f/VEM2iq0zGCAVFTgWWD5zLJGCtUs/Eh3ecz4lYXSU42TwTWjwL6EQ4SHXf2gYZoci5q5nwswxkd0i4gvQ5fKd3lM8RzleDUziWqicrak65guIKynYuOvvYE29yqkwQ20N4FTKHAoseokIch8ByhxTeURFAinWHJZ9Rhf9ShojGn5f5/sP6G8C7WHMOaOB7f5e+FrjRfQs660rVaVjQU6XKmRrtKHsQQcMTz2Npm4/ikBolVSUXV4ZWUofA8ZR3+/aBsINw/CALnNIp+9mU6WEbneRz6nK1/LWV/VMT8A9J4gEo8GIGGSCFWlbq2P6DxTxLSHByEiNelYxOkqA==",
"approverCertificate": "MIIDUTCCAjmgAwIBAgIUVyyrH8t8ldAUzHaYAyavN7mK6lMwDQYJKoZIhvcNAQELBQAwODELMAkGA1UEBhMCQ0gxDTALBgNVBAoMBFRlc3QxGjAYBgNVBAMMEVNLQSBUZXN0IDIwMjMgUlNBMB4XDTIzMTAzMDE1MjIxMFoXDTI0MTAyOTE1MjIxMFowODELMAkGA1UEBhMCQ0gxDTALBgNVBAoMBFRlc3QxGjAYBgNVBAMMEVNLQSBUZXN0IDIwMjMgUlNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuUy1tRrrO5xf6576qAJlLHX3HLGP7AKLfHW0TRGXfLP+ngFiSF4qAQdeU7rDtoY0QbjPazqFr8E9wuvjZX4B8xDEPPlECEO+7ixmeb0CX1HtZrES4b9CJuYunBl/ENNujnXH0pE9yw5/SiIxujISyNZmorDIurMsi7JYreq3ZOj8IisMDHVNfJKPV4QMOWKGtUfj/s7EdQ9H6pEvZcmy/Z9PyYWSCDcID4lrMg/FfdZRwvp9OcouypKOoDKf0pK2K0eYZQtnLZzHA+KI3xTjrpRFHtfufnKd9hozndp3OkZv8ZJFfjJ55RXL1K/ZqHSNSsmOxcGzzfNwI0+S/BjYtQIDAQABo1MwUTAdBgNVHQ4EFgQU261gJf0Ta1kqLevzofEU/vqbY9MwHwYDVR0jBBgwFoAU261gJf0Ta1kqLevzofEU/vqbY9MwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAbjTisq3rwCcomv4BD2j0DFm+pS3uUDFgGkOci93XSq89rJaWw4mUcQDhdU8rXjm5hNT+XoPND80sv/LwnCVUAXmhGiwwjXNcIORje+5z/Wys+jmPfOrfrzOaoOQEFw5ZQY3SgSQaEN+pmQr4HhorGnlY8aWIQ5XEgx7scebRQI6xx8zeQID20IJTElHby5haCdtaAO9BR+E3U6NnPyr9gFDn0YAf/OfadpaI1beu5TBBj5k9e7+Yzidp+BboolWhvPLSoMlmrTlgwl6Tub/ZQdAelUD0sks5hqZbCjO1/FPIrDgRP57pUw3+EKbDwfpaIOdQGMjr4I/+nAPuWd5s1A==",
"timestampDigestAlgorithm": "SHA-256",
"detailLevel": "level1",
"paging": {
"pageNumber": 0,
"pageSize": 1,
"sortOrder": "CREATION_DATE_ASC"
}
}
Request Parameters
ParameterDescription
timestampThe ISO-8601 formatted timestamp that has been signed by the approval client.
timestampSignatureThe signature (base64 encoded) for the timestamp (ISO-8601) that was done using the key of the approver. Format of the signature is depending on the algorithm used and as returned when using a JDK's native Signature.sign() method.

TIMESTAMP=$(date -u "+%Y-%m-%dT%H:%M:%S+00:00")
SIGNATURE=$(echo -n $TIMESTAMP | openssl dgst -sha256 -sign $PRIVATE_KEY_NAME | openssl enc -base64 | tr -d '\n')
approverCertificateCertificate of the approver in DER format (base64 encoded). Either the approverPublicKey or the approverCertificate has to be provided if the timestampSigningCertificate is not set.
timestampDigestAlgorithmThe message digest algorithm that was used for computing the timestamp signature. SHA-224, SHA-256, SHA-384, SHA-512, SHA3-224, SHA3-256, SHA3-384, SHA3-512
idIf specified filters for a specific task id.
requestIdIf specified filters for a specific request id by approver Public Key. Request ID is ignored if task ID is set.
detailLevelThe detail level of the response. level1, level2, level3, level4, level5
pageNumberThe number of the pages of results to be returned.
pageSizeThe number of results (approval tasks) to be returned per page
sortOrderSort order of the results. Note: initial value for LAST_FETCHED_DATE is the creation date of the task. LAST_FETCHED_DATE is updated every time a task is returned to the client using the appropriate REST service. CREATION_DATE_ASC, CREATION_DATE_DESC, LAST_FETCHED_DATE_ASC, LAST_FETCHED_DATE_DESC

Response: Status: 200, with detail-level: level1 contains a minimal challenge (approval task)

Body:

{
"tasks": [
{
"detailLevel": "level1",
"id": "6947856a-e3a1-44cf-bb99-bbd2995642ca", # the id of the challenge
"approvalToBeSigned": "4AAAADsABAABAAAAAhASAFRTQl9UVVRPUklBTF8xLVJTQQAAVBBAADwAAABXEBYAQXBwcm92ZVNpZ25UYXNrUGF5bG9hZAAABwEIANcU814AAAAAAhANAHRpbWVzdGFtcC1rZXkAAABWEFkAMFcwDAYIKoZIzj0EAwIFAANHADBEAiADPniQDGELMUTqJCJ17kW3bUInXIf8dy9mwsseJ7voJAIgK3Kh4JjkR+RDugYKlp4x3M6UQIXkyQ5OuavkL0V5b5sAAABXEBYAQXBwcm92ZVNpZ25UYXNrUGF5bG9hZAAA"
# the challenge payload (challenge to be signed)
}
]
}
Response Parameters
ParameterDescription
idThe id of the challenge
approvalToBeSignedThe challenge (payload) to be signed with the approvers private key

Send Approval

This step signs the challenge (approvalToBeSigned from the previous step) and herewith authorizes the signature-request.

Fetch Approval Task

The script Sign Approval Challenge signs the approvalToBeSigned from the previous step, with the approvers private key. Again use the following script to generate the next request body.

Run: ./sign_rsa.sh approverx 6947856a-e3a1-44cf-bb99-bbd2995642ca 4AAAADsA....F5bG9hZAAA

The output of the script should be sent to the endpoint: /v1/approval to submit the approval.

POST /v1/approval

Example request-body, make sure you are replacing the id, approvalToBeSigned and the signature according to above scripts output.

{
"id": "6947856a-e3a1-44cf-bb99-bbd2995642ca",
"approvalToBeSigned": "4AAAADsABAABAAAAAhASAFRTQl9UVVRPUklBTF8xLVJTQQAAVBBAADwAAABXEBYAQXBwcm92ZVNpZ25UYXNrUGF5bG9hZAAABwEIANcU814AAAAAAhANAHRpbWVzdGFtcC1rZXkAAABWEFkAMFcwDAYIKoZIzj0EAwIFAANHADBEAiADPniQDGELMUTqJCJ17kW3bUInXIf8dy9mwsseJ7voJAIgK3Kh4JjkR+RDugYKlp4x3M6UQIXkyQ5OuavkL0V5b5sAAABXEBYAQXBwcm92ZVNpZ25UYXNrUGF5bG9hZAAA",
"signature": "Mn/DQgm2yQbmFgcsEB+v3ACJgIbVo6IFSa7bDfMXmQXJZU21lVE0Bv46dTN6D4oWU/LYTuUYcIXmmRMChVgvRQvF254CctvDww99/ZUB+RrJ5LKE4t4gbHMgORntY/u3lM1CtmD5LwxONcB+3FwIyiODGPiDtfabgAucoGQ1X3Gdvn6KuESfFxtQfr3yn/FcMHBCGZDPPCIDDRaql3u9rI81emhyh7Oi1iXEypHAi9jzAUWRjnFCFtbOOs5MERN+54HxZF8wfY58aZLlHPF0GIhpC9+92NS7GRe0oO+gwlYX43NvewHwitTUMBE0ctd5xoNDkhuu8zMPTJJwiHqbmA==",
"approvalDigestAlgorithm": "SHA-256",
"approverCertificate":"MIIDAjCCAeoCCQCcSLgNCjDsRzANBgkqhkiG9w0BAQsFADBDMQswCQYDVQQGEwJDSDEPMA0GA1UECAwGWnVyaWNoMQ8wDQYDVQQHDAZadXJpY2gxEjAQBgNVBAoMCVNlY3Vyb3N5czAeFw0yMDA1MTExNDI5MDdaFw0yMTA1MTExNDI5MDdaMEMxCzAJBgNVBAYTAkNIMQ8wDQYDVQQIDAZadXJpY2gxDzANBgNVBAcMBlp1cmljaDESMBAGA1UECgwJU2VjdXJvc3lzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArA0bxSqhL7xfvcHbKKa8wMTMsIeJfYRdIgPxp5cU9JcmV86kyfpyRcSNSi44LVeNmAi94F3OZrXXi6CZvWrFL+VcewUtUSu+kG5oLJ9T4O6R2I5GO2Ev1HJnK3WfHOsFKFxLGzmKyjEkSLGgopY+Nh74K8Q6yxsvQPETOs9TzQiUXFYlfEZnbjUWG4eAgW9WWEopmK/X295ToOuTHFzmzO00btkjAy6vwWOabCE4kaJg+bCNW1snZz84uonr60rB9H0Mj98RbTfbDyMh6cIkaj8WrXeaYh4fxQYXApYu3nzhe3Q1bNCzV5M68rCsgVrmWcK/xUhM9BK6QHSwS/l76wIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQBNmg+gx2mH+fkU/dtM+tDvMIj2SY4pNU8H144aRY9I5kARN7Uwp+zRfJC+rCxrrYxXmx/OD+mIrTAHxPd5WuUWgULB6DXPho5Tyl4Czt6qOuzl7Qp7n1G9R/evZCPyEHflcGVEko/uCL5N8Ch9YboW5QwTrdftnL+zLLC5nON7KUCqbtVrDSdeMKF+dHKTX4Z90gdbv1C8x1fMWrsaoNw194DNBZCTVe4Di69xz3lHNEWVZ460mqKg0n5010VfEQqA92ceNJhjl4hgNMH9+asdBVAWmt0gk4PJUbqtuOKGKyxqi2k9QX8N2tjlsuMJmwRIw2YsZN4EKqQZ+0NAn1N7"
}
Request Parameters
ParameterDescription
idId of the task for which the approval is being submitted.
approvalToBeSignedThe approval token (base64 encoded) as received from the previous request or constructed by the client using additional data received in the task
signatureThe signature of the approvalToBeSigned (base64 encoded)

SIGNATURE=$(echo -n $APPROVAL_TO_BE_SIGNED | openssl enc -base64 -d -A | openssl dgst -sha256 -sign rsa-private-key.pem | openssl enc -base64 | tr -d '\n')
approvalDigestAlgorithmThe digest algorithm used for signing the approvalToBeSigned. The signature algorithm is given by the approver's private key. SHA-224, SHA-256, SHA-384, SHA-512, SHA3-224, SHA3-256, SHA3-384, SHA3-512
approverPublicKeyIf approver is public key based: The public key of the approver in the same format as provided during key creation (base64 encoded)
approverCertificateIf approver is certificate based: The certificate of the approver in the same format as provided during key creation (base64 encoded)

Response Status: 200

Get the approved signature

Fetch Approval Task

Replace the {id} with the id returned in the first request, e.g. 4e8731d8-0ae6-4444-8a8c-b73ab5f0ba18

GET: /v1/request/{id}

Response Status: 200

{
"id": "4e8731d8-0ae6-4444-8a8c-b73ab5f0ba18",
"status": "EXECUTED",
"executionTime": "2020-06-24T08:54:47Z",
"approvedBy": [
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArA0bxSqhL7xfvcHbKKa8wMTMsIeJfYRdIgPxp5cU9JcmV86kyfpyRcSNSi44LVeNmAi94F3OZrXXi6CZvWrFL+VcewUtUSu+kG5oLJ9T4O6R2I5GO2Ev1HJnK3WfHOsFKFxLGzmKyjEkSLGgopY+Nh74K8Q6yxsvQPETOs9TzQiUXFYlfEZnbjUWG4eAgW9WWEopmK/X295ToOuTHFzmzO00btkjAy6vwWOabCE4kaJg+bCNW1snZz84uonr60rB9H0Mj98RbTfbDyMh6cIkaj8WrXeaYh4fxQYXApYu3nzhe3Q1bNCzV5M68rCsgVrmWcK/xUhM9BK6QHSwS/l76wIDAQAB"
],
"notYetApprovedBy": [],
"rejectedBy": [],
"result": "H3bq8PdgSiAlhB0kt1RSD6a3JYXZoj/dz3Nb/MHlgISnmh6x3TPtnV+9mUnw8PV2Ss1pq8txdMOBg9SF8uaKyUvFtLl/QFHIgllm/Q/uvrjaM205Cdz1uaSLePXaNXeC012l1sqlhnyqGKxKTKejMngzNHAnOpwU7kGCEpKPFWL5ltaBRYd3Q/I/F9IufAsKHj+3ky/p6tYN5VPhJSKiSE2YuVyOzGPHY40ipVo/7deBtUUjZmaZAgVQNC1mC79LOhIHLj8Ce4i41CbFZA+ZSMe+nx5bP/7uPA+kbGAjvNS3KLOFeZJ2OJCkTuThsXVh7rTp9tVqYqHU1LZm8f9bYA=="
}

If the quorum has been filled the request status is EXECUTED and the result contains the actual signature

Response Parameters
ParameterDescription
idId of the task for which the approval is being submitted.
statusThe current status of the request. PENDING, APPROVED, EXECUTED, FAILED, EXPIRED, REJECTED, CANCELLED
executionTimeDate and time when the request is sent to the hsm in ISO-8601 format.
approvedByPublic keys of approvers that have approved the request.
notYetApprovedByPublic keys of approvers that have not yet approved the request but still could approve.
rejectedByPublic keys from approvers that have rejected to approve the request (i.e. they deleted the task related to this request.
resultThe result of the request after the request was executed on the hsm. In case of a sign request this field contains the signature. In case of a decrypt request it contains the decrypted payload. Otherwise this field is empty.

What's next?