Skip to content

Authorization

Heiti Tobi edited this page Apr 1, 2025 · 19 revisions

Introduction

Each e-service must be registered in the SiGa service. Each e-service is issued a unique service identifier (UUID) and a signing secret key.

All requests sent to SiGa service must be signed with a previously agreed signing secret key that is unique to given e-service. The signature is calculated as an HMAC value over the mandatory "X-Authorization-..." headers and the request body contents. For requests that do not contain a payload the body contents are considered as an empty byte array.

In addition to the request payload, the e-service provider must send the following mandatory HTTP headers with every request:

  • X-Authorization-Timestamp
  • X-Authorization-ServiceUUID
  • X-Authorization-Hmac-Algorithm (optional, defaults to "HmacSHA256")
  • X-Authorization-Signature

The signature must be calculated before any transformations or compression is applied to the request body.

Headers

Mandatory headers are same for all API requests. Content-Type may change in case of GET request.

Header Mandatory Default value Description
X-Authorization-Timestamp + - Unix time (Epoch time) of request generation from client side with precision of one second
X-Authorization-ServiceUUID + - Unique identifier of the relying party e-service. Used to determine client and e-service making the actual request.
X-Authorization-Signature + - Hex encoded value of HMAC hash of the canonicalized request data (authentication headers and body contents).
X-Authorization-Hmac-Algorithm - HmacSHA256 Algorithm used for Hmac calculation. Supported values: HmacSHA256, HmacSHA384, HmacSHA512, HmacSHA3-256, HmacSHA3-384, HmacSHA3-512
Content-Type for POST and PUT only - The Media type of the body of the request (used with POST and PUT requests). Only supported value is application/json; charset=UTF-8

Signature creation process

  1. Given the following example container creation request:
Request method:	POST
Request URI:	https://dsig-demo.eesti.ee:443/hashcodecontainers

{
    "dataFiles": [
        {
            "fileName": "test.txt",
            "fileHashSha512": "hQVz9wirVZNvP/q3HoaW8nu0FfvrGkZinhADKE4Y4j/dUuGfgONfR4VYdu0p/dj/yGH0qlE0FGsmUB2N3oLuhA==",
            "fileSize": 189,
            "fileHashSha256": "RnKZobNWVy8u92sDL4S2j1BUzMT5qTgt6hm90TfAGRo="
        }
    ]
}
  1. Prepare the current timestamp and ServiceUUID headers for the request:
X-Authorization-Timestamp=1580400796
X-Authorization-ServiceUUID=a7fd7728-a3ea-4975-bfab-f240a67e894f
  1. Prepare the request url and extract the context path with query parameters Note that the context path string should be extracted after URL Encoding rules are applied:
urlContextPath = "/hashcodecontainers"
  1. Extract HTTP method name in uppercase
requestMethod = "POST"
  1. Concatenate the values of X-Authorization-ServiceUUID header, X-Authorization-Timestamp header, requestMethod, urlContextPath and requestBody("UTF-8") with the delimiter ':'.
plaintext = "a7fd7728-a3ea-4975-bfab-f240a67e894f:1580400796:POST:/hashcodecontainers:{"dataFiles":[{"fileName":"test.txt","fileHashSha512":"hQVz9wirVZNvP/q3HoaW8nu0FfvrGkZinhADKE4Y4j/dUuGfgONfR4VYdu0p/dj/yGH0qlE0FGsmUB2N3oLuhA==","fileSize":189,"fileHashSha256":"RnKZobNWVy8u92sDL4S2j1BUzMT5qTgt6hm90TfAGRo="}]}"

In case of GET request the body part is left empty, but the delimiter ':' still needs to be added. Here is the example for getContainer request

plaintext = "a7fd7728-a3ea-4975-bfab-f240a67e894f:1584356816:GET:/hashcodecontainers/09595d18-c7b7-4a0d-833a-2b2fab106875:"
  1. With the signing secret key, calculcate the HmacSHA256 value for given plaintext
signingSecret = "746573745365637265744b6579303031"
authSignature = HmacSHA256(plaintext, signigSecret)
X-Authorization-Signature=7301b3b88995b410bed0016b9a5bb3d177d32ac2bb2e91fabb80c084180eb42d
  1. Add the signature value to the request header X-Authorization-Signature to construct the final request
Request method:	POST
Request URI:	https://dsig-demo.eesti.ee:443/hashcodecontainers
Headers:	X-Authorization-Signature=7301b3b88995b410bed0016b9a5bb3d177d32ac2bb2e91fabb80c084180eb42d
		X-Authorization-Timestamp=1580400796
		X-Authorization-ServiceUUID=a7fd7728-a3ea-4975-bfab-f240a67e894f
		X-Authorization-Hmac-Algorithm=HmacSHA256
		Content-Type=application/json; charset=UTF-8

Body:
{
    "dataFiles": [
        {
            "fileName": "test.txt",
            "fileHashSha512": "hQVz9wirVZNvP/q3HoaW8nu0FfvrGkZinhADKE4Y4j/dUuGfgONfR4VYdu0p/dj/yGH0qlE0FGsmUB2N3oLuhA==",
            "fileSize": 189,
            "fileHashSha256": "RnKZobNWVy8u92sDL4S2j1BUzMT5qTgt6hm90TfAGRo="
        }
    ]
}

Url encoding rules

  • Do not URL encode any of the unreserved characters that RFC 3986 defines. These unreserved characters are A-Z, a-z, 0-9, hyphen ( - ), underscore ( _ ), period ( . ), and tilde ( ~ ).
  • Percent encode extended UTF-8 characters in the form %XY%ZA.
  • Percent encode the space character as %20 (and not +, as common encoding schemes do).
  • Percent encode all other characters with %XY, where X and Y are hex characters 0-9 and uppercase A-F.

Generating a Signing Secret (for Digital Signature Gateway Service providers)

Overview

This chapter details the steps to generate a cryptographically secure signing secret and encrypt it before storing it in the database. This is crucial for maintaining secure communication with your e-service.

Generating signing secret

The signing secret should be generated using a cryptographically secure random number generator. The example below uses Unix utilities:

$ head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32 ; echo ''
# Example output:
# FduSA0DZvlb23WfbSC2t8KAEU8100p1X

Encrypting signing secret

Before inserting the signing secret into SiGa database, it must be encrypted. SiGa security configuration parameters and example values can be found here.

Using Jasypt 1.9.3 with OpenJDK 17

  1. Setup
  2. Configuration
    • Algorithm: Should match the siga.security.jasypt.encryption-algo property in application.properties (e.g., PBEWITHSHA-256AND256BITAES-CBC-BC).
    • Password: Should match the siga.security.jasypt.encryption-key property in application.properties (e.g., encryptorKey).
  3. Encryption Command
jasypt-1.9.3$ bin/encrypt.sh providerClassName="org.bouncycastle.jce.provider.BouncyCastleProvider" algorithm="PBEWITHSHA-256AND256BITAES-CBC-BC" input="FduSA0DZvlb23WfbSC2t8KAEU8100p1X" password="encryptorKey"
# Example output:
# ----ENVIRONMENT-----------------
# Runtime: Eclipse Adoptium OpenJDK 64-Bit Server VM 17.0.11+9
# ----ARGUMENTS-------------------
# input: FduSA0DZvlb23WfbSC2t8KAEU8100p1X
# providerClassName: org.bouncycastle.jce.provider.BouncyCastleProvider
# password: encryptorKey
# algorithm: PBEWITHSHA-256AND256BITAES-CBC-BC
# ----OUTPUT----------------------
# jjvJ29sY5AwEOsXvB6n4PIhGvwj67RZBkNmqbjveN4Qy5MjSjswmB0wiaDBr2gOzLrTZFQBp7m4tdkiJkJrS6Q==