Skip to main content
Version: v3

HTTP Request signing

To ensure the integrity and authenticity of API requests, all requests must be signed. This process confirms that the API requests originate from a trusted source and have not been tampered with during transmission.

This guide explains how to sign HTTP requests according to the HTTP Signatures standard.

Certificate

The certificate used for signing requests is provided by Invers B.V. during the onboarding process. Only the public certificate is registered with Invers to validate signatures.

Required Headers

To sign a request, the following headers are required:

HeaderTypeDescription
ApiKeyStringAPI key issued by Invers B.V. during onboarding.
x-request-idGuidA unique GUID for each request.
dateStringThe current date in HTTP Date format (RFC 2616).
digestStringBase64 encoded hash of the request body.
SignatureStringContains the signed string with details of the signature method and key.

ApiKey

The ApiKey is issued by Invers B.V. during onboarding.

Example:

ApiKey: cEZrSmVPLTN1XzVDM09nVDhEanlZaUJwYzRXTldpVUc=

X-Request-ID

The x-request-id must be a unique GUID for each request.

Example:

X-Request-ID: f1b8d9bd-0118-47ff-bdb7-5e2956ad0e9f

Date

The date header should contain the current date in HTTP Date format (RFC 2616).

DateTime.Now.ToUniversalTime().ToString("r");

Example:

Date: Wed, 25 Sep 2019 07:45:19 GMT

Digest

The digest header ensures the integrity of the request body. It is generated by hashing the request body using SHA-256 or SHA-512 and then encoding the result in Base64.

  • If the body is empty, hash an empty string.
  • The output is Base64 (RFC 4648) encoded.

Example:

Digest: sha-512=z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXcg/SpIdNs6c5H0NE8XYXysP+DGNKHfuwvY7kxvUdBeoGlODJ6+SfaPg==

Signature

The Signature header contains the signed string and additional information. The signature is created using RSA-SHA512.

Example:

Signature: keyId="cEZrSmVPLTN1XzVDM09nVDhEanlZaUJwYzRXTldpVUc=",algorithm="rsa-sha512",headers="date digest x-request-id",signature="lvJxQyr9JTBZGj5zIss4lPRDntClh9wdYRdcq1MQYd0sdav/ccPR3tyEWklpgGc9vLNLETLUnAXl4LtmSEW6Zu4ZHxlJ82Y7hzzjDYDnyj1OSZa97ArlY9N5aLKKG1rICPTeWPN4hxID/taThTh8Ab2TCCNrpYRiIYTkxHWvjrQF8HPerbFalqjLn1WfNyhCIGkO6u6I2H9hOsLaFJG3k+Ui5i3IxmaT1yLSWYgHxo32xRHaGr6KqrspkbQmoCVbI78SkCkajOuBhVUXqAw213GuOxjLaOFFnoLAo3cfrMxvPtL/2JMpTjYUPdTZJ3EsuXXnvx7bwmrvooJtuNRgFw=="

Generating a Digest

The digest is a Base64 (RFC 4648) encoded hash of the request body: Base64(SHA512(body))

  • If the request body is empty, hash the empty string.
  • You can use either SHA-256 or SHA-512 as the hashing algorithm.
  • The output must be Base64 encoded and added to the digest header.

Examples:

Digest: sha-256=47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=
Digest: sha-512=z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXcg/SpIdNs6c5H0NE8XYXysP+DGNKHfuwvY7kxvUdBeoGlODJ6+SfaPg==
C# Example: Generating the Digest
private string CalculateDigest(byte[] body, HashAlgorithmName hashAlgorithm)
{
byte[] hash = null;
using (var algorithm = HashAlgorithm.Create(hashAlgorithm.Name))
{
hash = algorithm.ComputeHash(body);
}
return Convert.ToBase64String(hash);
}

Generating the Signing String

To generate the signing string, include the following headers in order:

  • date
  • digest
  • x-request-id
warning

Ensure that all header names are in lowercase and separated by newline characters.
The date header must be formatted correctly.
In C#, use DateTime.Now.ToUniversalTime().ToString("r") to produce the required format.

Example:

date: Wed, 25 Sep 2019 07:45:19 GMT
digest: sha-512=z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXcg/SpIdNs6c5H0NE8XYXysP+DGNKHfuwvY7kxvUdBeoGlODJ6+SfaPg==
x-request-id: 23bfabd8-3ffa-4e41-a851-2395f15a889e

C# Example: Constructing a Signing String

private string CalculateSigningString(string requestDate, string requestDigest, string requestId)
{
var s = string.Format("date: {0}\ndigest: {1}\nx-request-id: {2}", requestDate, requestDigest, requestId);
return s;
}
tip

Use \n for a new line.

Generating the Signature

The signature is the signature string and signed using the certificate: Base64(RSA-SHA512(signing_string))

  1. Create the signing string using the required headers.
  2. Sign the string using your private key with the RSA-SHA512 algorithm.
  3. Encode the resulting signature in Base64 (RFC 4648).

Example:

lvJxQyr9JTBZGj5zIss4lPRDntClh9wdYRdcq1MQYd0sdav/ccPR3tyEWklpgGc9vLNLETLUnAXl4LtmSEW6Zu4ZHxlJ82Y7hzzjDYDnyj1OSZa97ArlY9N5aLKKG1rICPTeWPN4hxID/taThTh8Ab2TCCNrpYRiIYTkxHWvjrQF8HPerbFalqjLn1WfNyhCIGkO6u6I2H9hOsLaFJG3k+Ui5i3IxmaT1yLSWYgHxo32xRHaGr6KqrspkbQmoCVbI78SkCkajOuBhVUXqAw213GuOxjLaOFFnoLAo3cfrMxvPtL/2JMpTjYUPdTZJ3EsuXXnvx7bwmrvooJtuNRgFw==
C# Example: Generating a Signature
    private string CalculateSignature(string signingString)
{
if (_certificate != null)
{
byte[] bytesData = Encoding.ASCII.GetBytes(signingString);
byte[] bytesEncrypted = _certificate.GetRSAPrivateKey().SignData(bytesData, HashAlgorithmName.SHA512, RSASignaturePadding.Pkcs1);
return Convert.ToBase64String(bytesEncrypted);
}
else
{
_logger.LogError("No certificate loaded for calculating signature");
}

return String.Empty;
}

Constructing the Signature Header

The Signature header includes the following components:

  • keyId: The ApiKey.
  • algorithm - The value of the algorithm, which should be rsa-sha512.
  • headers - Lowercase list of the headers that have been used in the signature. The value shall be date digest x-request-id
  • signature - The generated signature.

Example:

keyId="cEZrSmVPLTN1XzVDM09nVDhEanlZaUJwYzRXTldpVUc=",algorithm="rsa-sha512",headers="date digest x-request-id",signature="lvJxQyr9JTBZGj5zIss4lPRDntClh9wdYRdcq1MQYd0sdav/ccPR3tyEWklpgGc9vLNLETLUnAXl4LtmSEW6Zu4ZHxlJ82Y7hzzjDYDnyj1OSZa97ArlY9N5aLKKG1rICPTeWPN4hxID/taThTh8Ab2TCCNrpYRiIYTkxHWvjrQF8HPerbFalqjLn1WfNyhCIGkO6u6I2H9hOsLaFJG3k+Ui5i3IxmaT1yLSWYgHxo32xRHaGr6KqrspkbQmoCVbI78SkCkajOuBhVUXqAw213GuOxjLaOFFnoLAo3cfrMxvPtL/2JMpTjYUPdTZJ3EsuXXnvx7bwmrvooJtuNRgFw=="
C# Example: Generating the Signature Header
private string GenerateSignatureHeader(string apiKey, string requestSignature)
{
return string.Format("keyId=\"{0}\",algorithm=\"rsa-sha512\",headers=\"date digest x-request-id\",signature=\"{1}\"", apiKey, requestSignature);
}