> ## Documentation Index
> Fetch the complete documentation index at: https://boxo.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Request Signaturing

## Usage in Endpoints

### Validate Requests

* ["Get access\_token"](/host-apps/BoxoConnect#get-access-token) to Hostapp backend
* ["Create Order Payment"](/host-apps/BoxoPayments#1-create-order-payment-endpoint) to Hostapp backend
* ["Get Order Payment Status"](/host-apps/BoxoPayments#2-get-order-payment-status-endpoint) to Hostapp backend

### Signing Requests

["Complete Order Payment"](/host-apps/BoxoPayments#3-webhook-complete-order-payment) Webhook to Boxo Platform

## Settings Options

### Algorithms

Choose from three types of algorithms for signing requests and validating them:

* RSA2
* HMAC
* ECDSA

### Hash Function Used in Signature

Select the hash function used for the signature:

* MD5
* SHA-1
* SHA-224
* SHA-256
* SHA-384
* SHA-512

### Api Client ID

“Api client ID” is an identifier for a Hostapp’s API

### Key Format for RSA or ECDSA

For RSA2 and ECDSA, choose between:

* PEM
* DER

### Boxo public key

“Boxo public key” is used for validating request data on a Hostapp’s side.

### Hostapp public key

“Hostapp public key” is used for validating request data from a Hostapp. This key belongs to the private key on a Hostapp’s side.

### HMAC Secret

“HMAC Secret” is used in HMAC algorithm only.

### Headers Map

“Headers map” is a JSON field used to set up custom headers in case a Hostapp wants to utilize their own request signaturing. These fields should be mapped:

* signature
* timestamp
* nonce
* identity
* client\_id
* merchant\_id

### Default

```json theme={"system"}
{
  "nonce": "X-Nonce",
  "identity": "X-Identity",
  "client_id": "X-Client-Id",
  "signature": "X-Signature",
  "timestamp": "X-Timestamp",
  "merchant_id": "X-Merchant-Id"
}
```

### Signature Payload Template

“Signature payload template” is a string template field used to set up a custom payload format in case a Hostapp wants to utilize their own request signaturing. These fields should be mapped in the template:

* `{timestamp}`
* `{nonce}`
* `{identity}`
* `{client_id}`
* `{merchant_id}`
* `{request_method} - Example: “POST”, "GET"`
* `{url}`
* `{payload} - this is “Request data/body”`

### Signature Template

“Signature template” is a string template field used to set up a custom signature header format in case a Hostapp wants to utilize their own request signaturing. These fields should be mapped in the template:

* `{signature}`

### Timespec

**Timespec** is a field used when generating the current timestamp, defining the level of time precision. Examples include **seconds** or **milliseconds**, depending on the required accuracy for the timestamp in the request signing process.

### Identity

**Identity** is an optional static string that can be included in the signature payload and passed through headers to verify data integrity. If used, make sure to add it to the **Headers map** and include it in the **Signature payload template** as `{identity}` to ensure it's correctly incorporated into the request signing process.

### Nonce

A **Nonce** is an optional random string that can be included in the signature payload and passed through headers to verify data integrity. Its length is defined in the **Nonce length** parameter and can be enabled via the **Use nonce** option. If the nonce is used, make sure to include it in the **Headers map** and the **Signature payload template** as `{nonce}` to ensure it's properly accounted for in the request signing process.

### Encoding

* **Request data encoding for payload**: This field defines how the request data is encoded before it is formatted into the payload. It can either be encoded to **base64** or left as **plain text**.
* **Signature payload encoding**: This field specifies how the payload should be encoded before the signing process. The options are **base64** or **plain text**.
* **Signature encoding**: This field determines how the signature is encoded after the signing process. It can be encoded to **base64** or **hex** format.

### Request Data/Body

* **Use request data with spaces**: This option determines whether spaces are included in the request data when formatting the payload.
  * If **false**, the payload will be formatted without spaces: `{"a":"b"}`.
  * If **true**, the payload will include spaces: `{"a": "b"}`.

* **Sort request data keys**: This option specifies whether the keys in the request data should be sorted alphabetically when formatting the payload.
  * If **true**, the payload will have keys sorted: `{"a": "2", "b": "1"}`.
  * If **false**, the keys will remain in their original order: `{"b": "1", "a": "2"}`.

### Merchant ID

Merchant ID is an optional identifier unique to a Partnership. It is used to identify a miniapp in a Hostapp’s system. Don’t forget to add it in “Headers map” and to “Signature payload template” as {merchant_id} if used. Merchant ID can be also specified in a Partnership settings.

## Hostapp to provide

Please provide the following information to Boxo, after setup Boxo will provide you with a public key to verify the signature:

### Hostapp's settings

Here is a structured breakdown of the parameters used in the request signing process:

* **Algorithm (choice)**: The cryptographic algorithm used for signing:
  * Options: RSA2, HMAC, ECDSA

* **Hash function (choice)**: The hash function applied to the request:
  * Options: MD5, SHA-1, SHA-224, SHA-256, SHA-384, SHA-512

* **Key Format (choice)** (optional): The format for the private/public key pair:
  * Options: PEM, DER (Applicable only for RSA2 and ECDSA)

* **Hostapp public key (string)**: The public key of the host app in PKCS1 format, used by Boxo to verify the signature.

* **HMAC Secret (string)** (optional): A secret key used for HMAC algorithm only.

* **Headers map (JSON)** (optional): A JSON field used to configure custom headers if the host app wants to implement its own request signing.

* **Signature payload template (string)** (optional): A string template for setting up a custom payload format if the host app is using custom request signing.

* **Signature template (string)** (optional): A string template for setting up a custom signature header format if the host app is using custom request signing.

* **Timespec (string)**: Defines the time precision when generating the current timestamp.
  * Example values: seconds, milliseconds

* **Identity (string)** (optional): An identifier for the host app, used for recognition.

* **Nonce length (integer)** (optional): Defines the length of the nonce string.

* **Use nonce (boolean)** (optional): A boolean value indicating whether to use a nonce string.

* **Request data encoding for payload (choice)**: The encoding method for the request payload.
  * Options: base64, plain text

* **Signature payload encoding (choice)**: The encoding for the signature payload.
  * Options: base64, plain text

* **Signature encoding (choice)**: The encoding for the signature.
  * Options: base64, hex

* **Use request data with spaces (boolean)** (optional): Indicates whether spaces should be used in request data.

* **Sort request data keys (boolean)** (optional): Indicates whether the keys in the request data should be sorted.

* **Public Key (string)**: The public key in PKCS1 format for the Boxo Platform to verify the signature.

* **Client ID (string)**: A unique identifier for the host app for verification.

* **Merchant ID (string)** (optional): A unique identifier for the merchant associated with the host app.

This detailed structure ensures that both the host app and the Boxo platform can securely exchange data using request signing.

## Code examples

* Hash function - SHA-256
* Key Format - PEM
* Headers map - `{"signature": "X-Signature", "timestamp": "X-Timestamp", "client_id": "X-Client-Id"}`
* Signature payload template - `{timestamp}{client_id}{request_method}{url}{payload}`
* Signature template - `{signature}`
* Timespec - seconds
* Use nonce - false
* Request data encoding for payload - plain text
* Signature payload encoding - plain text
* Signature encoding - base64
* Use request data with spaces - false
* Sort request data keys - false

### RSA2

```py theme={"system"}
def sign_request(
    url, request_method, request_data, client_id, timestamp, 
):
    import rsa

    payload = self._payload_template.format(
        request_method=request_method,
        url=url,
        client_id=client_id,
        timestamp=timestamp,
        payload=request_data,
    )

    signature = rsa.sign(
        payload.encode("utf-8"),
        rsa.PrivateKey.load_pkcs1(self._private_key),
        hash_method,
    )

    return base64.b64encode(signature).decode()
```

```py theme={"system"}
def verify_signature(
    signature, url, request_method, request_data, client_id, timestamp,
):
    import rsa
    from rsa.pkcs1 import VerificationError

    payload = self._payload_template.format(
        request_method=request_method,
        url=url,
        client_id=client_id,
        timestamp=timestamp,
        payload=request_data,
    )

    signature = base64.b64decode(signature)
    try:
        rsa.verify(
            payload.encode("utf-8"),
            signature,
            rsa.PublicKey.load_pkcs1_openssl_pem(self._public_key),
        )
        return True
    except VerificationError:
        return False
```

### HMAC

```py theme={"system"}
def sign_request(
    url, request_method,  request_data, timestamp
):
    import hmac
    import hashlib

    keyEncoded = secret_key.encode()
    hash_method = hashlib.sha256

    payload = self._payload_template.format(
        request_method=request_method,
        url=url,
        client_id=self._client_id,
        timestamp=timestamp,
        payload=request_data,
    )
    h = hmac.new(keyEncoded, payload.encode(), hash_method)

    generated_signature = base64.b64encode(h.digest()).decode("utf-8")

    return generated_signature
```

```py theme={"system"}
def verify_signature(
    signature, url, request_method, request_data, client_id, secret_key, timestamp
):
    import hmac
    import hashlib
    import base64


    payload = self._payload_template.format(
        request_method=request_method,
        url=url,
        client_id=client_id,
        timestamp=timestamp,
        payload=request_data,
    )

    keyEncoded = self._secret_key.encode()
    hash_method = hashlib.sha256
    h = hmac.new(keyEncoded, payload.encode(), hash_method)

    generated_signature = base64.b64encode(h.digest()).decode("utf-8")

    return hmac.compare_digest(signature, generated_signature)
```

### ECDSA

```py theme={"system"}
def sign_request(
    url, request_method, request_data, client_id, timestamp, 
):
    import hashlib
    from ecdsa import SigningKey
    from ecdsa.util import sigencode_der

    payload = self._payload_template.format(
        request_method=request_method,
        url=url,
        client_id=client_id,
        timestamp=timestamp,
        payload=request_data,
    )

    sign_key = SigningKey.from_pem(self._private_key)
    signature = sign_key.sign(
        payload.encode(),
        hashfunc=hashlib.sha256,
        sigencode=sigencode_der,
    )

    return base64.b64encode(signature).decode()
```

```py theme={"system"}
def verify_signature(
    signature, url, request_method, request_data, timestamp, client_id
):  
    import hashlib
    from ecdsa import VerifyingKey
    from ecdsa.util import sigdecode_der

    payload = self._payload_template.format(
        request_method=request_method,
        url=url,
        client_id=client_id,
        timestamp=timestamp,
        payload=request_data,
    )

    verifying_key = VerifyingKey.from_pem(self._public_key)
    return verifying_key.verify(
        base64.b64decode(signature),
        payload.encode(),
        hashfunc=hashlib.sha256,
        sigdecode=sigdecode_der,
    )
```
