# HTTPS destination

Connecting an HTTPS destination enables you to forward IoT data from KPN Things to your server through an HTTPS connection.

## Connect an HTTPS destination

The following parameters are available to connect an HTTPS destination:

| Parameter               |     | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | Example value                                                                                                |
| ----------------------- | --- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| `name`                  | \*  | The name of the destination                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | *My Server*                                                                                                  |
| `description`           |     | Description of the destination                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | *Endpoint of my server*                                                                                      |
| `url`                   | \*  | <p>HTTPS URL of your destination. Should </p><p>start with https\://, no custom ports </p><p>are supported (only default 443), query </p><p>parameters are allowed</p>                                                                                                                                                                                                                                                                                                                                                                         | *<https://example.com/> thingsdata*                                                                          |
| `httpMethod`            | \*  | The HTTP method to use (GET or POST)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | *POST*                                                                                                       |
| `additional Headers`    |     | <p>Object of static key-value pairs.</p><p></p><p><strong>Caution! Do not put white space characters in your header name!</strong></p>                                                                                                                                                                                                                                                                                                                                                                                                         | <p><em>{</em></p><p>  <em>"header1":"value1",</em></p><p>  <em>"header2": "value2"</em></p><p><em>}</em></p> |
| `authentication method` |     | <ul><li>None - no authentication</li><li>Basic Authentication - Authentication via a user name and password</li><li>Bearer token - Authentication using a cryptic string as bearer token</li><li>X-API-key - Authentication using an API-key</li></ul>                                                                                                                                                                                                                                                                                         |                                                                                                              |
| `expected ResponseCode` |     | <p>The HTTP response code to be expected after the HTTPS request is done.<br><br><em>When a response code not equal to 2XX is returned, it is assumed that the delivery was not succesful. At most three delivery attempts are done with an increasing timeout before the data is discarded.</em></p>                                                                                                                                                                                                                                          | *200*                                                                                                        |
| `sharedSecret`          | \*† | <p>With the shared secret your destination can verify that Things has sent the data and not someone else, because with the shared secret a unique <a href="https://docs.kpnthings.com/kpn-things/building-blocks/destinations/https-destination#things-message-token">Things-Message-Token</a> is calculated for each message.</p><p>Shared secret should be at least 32 characters long and should contain at least: <br>- 1 uppercase character<br>- 1 lowercase character<br>- 1 number<br>- 1 special character (#?!@$%^&(){}:.,/+\*;)</p> | *Generate your own by hitting 32 random keys*                                                                |

*\*) required value*\
\&#xNAN;*†) secret value, can only be written*

## The request

* `{xx}` is a destination parameter
* `<xx>` is a variable filled by the system for each request

```http
{method} {url(path)} HTTP/1.1
Host: {url(domain)}
Things-Plug-UUID: <plugUUID>
Things-Message-Token: <token>
Content-type: application/json
{additional-headers}

<senML>
```

* `plugUUID` is the unique identifier of the destination connection that allows you to lookup the shared secret in your own database that should be used to check the Things-Message-Token
* `token` must be used to verify the authenticity of the request data. It is a SHA-256 hash calculated over the SenML body in the request and a shared secret unique for this destination. Since only KPN Things and you know this secret, the authenticity of the message is verified.
* `senML` is the device data

### Things-Message-Token

{% hint style="warning" %}
It is very important to implement the token check before accepting the sent data in your application.
{% endhint %}

The HTTPS request contains a `Things-Message-Token`header which allows you to verify the origin of the request. The token is a hash, calculated as following:

```
token = sha256({senMLBody}{sharedSecret})
```

Where `{senMLBody}` is the body of the request, and `sharedSecret` is the password set when adding the destination. The shared secret should at least be 30 characters long.

You must generate and fill in your own shared secret when adding the destination. Since the token is stored securely in our system, it is not possible to retrieve the shared secret from the destination configuration after creation. It is only possible to renew the secret.

### Request body

The body of the HTTPS request will contain the SenML object in JSON formatting. It will contain the device identifier and the measurement data. Learn more on the SenML object here:

{% content-ref url="../data-processing/thingsml-and-senml/senml" %}
[senml](https://docs.kpnthings.com/kpn-things/building-blocks/data-processing/thingsml-and-senml/senml)
{% endcontent-ref %}

## TLS/SSL Requirements

KPN Things does not facilitate unsafe connections. For the definition of a safe connection we follow the [KPN Security Policy](https://ciso-ksp.kpnnet.org/). There are three aspects you need to take into account when configuring TLS/SSL on the endpoint where you want to deliver your IoT Data.

### Trusted certificate

We do not support self-signed certificates. Your HTTPS certificate should be signed by a root certificate authority (CA) that is trusted by the default Java trust store. You can use the [SSL Server Test from Qualys](https://www.ssllabs.com/ssltest/index.html) to check if your certificate is trusted by the Java trust store:

<figure><img src="https://1453626848-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl6RrePMSAjRvOgcHjMBZ%2Fuploads%2FIEfUWFRPiV0CEgEqVfI0%2Fimage.png?alt=media&#x26;token=a9c684c0-4d20-48f1-8337-b5e6f8457a96" alt=""><figcaption><p>The result of the SSL Server Test indicating the certificate is trusted by Java</p></figcaption></figure>

### Up to date TLS version

Your server should use TLSv1.2 or higher. Older protocols are not supported because they are not considered safe.&#x20;

### Safe cipher suite

Your server should support at least one of the cipher suites stated below. The cipher suites in this table are considered safe.

| Standard code | Standard + SSLLabs cipher suite name                     |
| ------------- | -------------------------------------------------------- |
| 0x16B9        | TLS\_CECPQ1\_RSA\_WITH\_AES\_256\_GCM\_SHA384            |
| 0x16B7        | TLS\_CECPQ1\_RSA\_WITH\_CHACHA20\_POLY1305\_SHA256       |
| 0x67          | TLS\_DHE\_RSA\_WITH\_AES\_128\_CBC\_SHA256               |
| 0x6b          | TLS\_DHE\_RSA\_WITH\_AES\_256\_CBC\_SHA256               |
| 0xc09e        | TLS\_DHE\_RSA\_WITH\_AES\_128\_CCM                       |
| 0xc09f        | TLS\_DHE\_RSA\_WITH\_AES\_256\_CCM                       |
| 0xc0a2        | TLS\_DHE\_RSA\_WITH\_AES\_128\_CCM\_8                    |
| 0xc0a3        | TLS\_DHE\_RSA\_WITH\_AES\_256\_CCM\_8                    |
| 0x9e          | TLS\_DHE\_RSA\_WITH\_AES\_128\_GCM\_SHA256               |
| 0x9f          | TLS\_DHE\_RSA\_WITH\_AES\_256\_GCM\_SHA384               |
| 0xbe          | TLS\_DHE\_RSA\_WITH\_CAMELLIA\_128\_CBC\_SHA256          |
| 0xc4          | TLS\_DHE\_RSA\_WITH\_CAMELLIA\_256\_CBC\_SHA256          |
| 0xccaa        | OLD\_TLS\_DHE\_RSA\_WITH\_CHACHA20\_POLY1305\_SHA256     |
| 0xc027        | TLS\_ECDHE\_RSA\_WITH\_AES\_128\_CBC\_SHA256             |
| 0xc028        | TLS\_ECDHE\_RSA\_WITH\_AES\_256\_CBC\_SHA384             |
| 0xc02f        | TLS\_ECDHE\_RSA\_WITH\_AES\_128\_GCM\_SHA256             |
| 0xc030        | TLS\_ECDHE\_RSA\_WITH\_AES\_256\_GCM\_SHA384             |
| 0xc076        | TLS\_ECDHE\_RSA\_WITH\_CAMELLIA\_128\_CBC\_SHA256        |
| 0xc077        | TLS\_ECDHE\_RSA\_WITH\_CAMELLIA\_256\_CBC\_SHA384        |
| 0xcc13        | OLD\_TLS\_ECDHE\_RSA\_WITH\_CHACHA20\_POLY1305\_SHA256   |
| 0xcca8        | TLS\_ECDHE\_RSA\_WITH\_CHACHA20\_POLY1305\_SHA256        |
| 0x16BA        | TLS\_CECPQ1\_ECDSA\_WITH\_AES\_256\_GCM\_SHA384          |
| 0x16B8        | TLS\_CECPQ1\_ECDSA\_WITH\_CHACHA20\_POLY1305\_SHA256     |
| 0xc023        | TLS\_ECDHE\_ECDSA\_WITH\_AES\_128\_CBC\_SHA256           |
| 0xc024        | TLS\_ECDHE\_ECDSA\_WITH\_AES\_256\_CBC\_SHA384           |
| 0xc0ac        | TLS\_ECDHE\_ECDSA\_WITH\_AES\_128\_CCM                   |
| 0xc0ad        | TLS\_ECDHE\_ECDSA\_WITH\_AES\_256\_CCM                   |
| 0xc0ae        | TLS\_ECDHE\_ECDSA\_WITH\_AES\_128\_CCM\_8                |
| 0xc0af        | TLS\_ECDHE\_ECDSA\_WITH\_AES\_256\_CCM\_8                |
| 0xc02b        | TLS\_ECDHE\_ECDSA\_WITH\_AES\_128\_GCM\_SHA256           |
| 0xc02c        | TLS\_ECDHE\_ECDSA\_WITH\_AES\_256\_GCM\_SHA384           |
| 0xc072        | TLS\_ECDHE\_ECDSA\_WITH\_CAMELLIA\_128\_CBC\_SHA256      |
| 0xc073        | TLS\_ECDHE\_ECDSA\_WITH\_CAMELLIA\_256\_CBC\_SHA384      |
| 0xcc14        | OLD\_TLS\_ECDHE\_ECDSA\_WITH\_CHACHA20\_POLY1305\_SHA256 |
| 0xcca9        | TLS\_ECDHE\_ECDSA\_WITH\_CHACHA20\_POLY1305\_SHA256      |
| 0xC086        | TLS\_ECDHE\_ECDSA\_WITH\_CAMELLIA\_128\_GCM\_SHA256      |
| 0xC087        | TLS\_ECDHE\_ECDSA\_WITH\_CAMELLIA\_256\_GCM\_SHA384      |
| 0xC07C        | TLS\_DHE\_RSA\_WITH\_CAMELLIA\_128\_GCM\_SHA256          |
| 0xC07D        | TLS\_DHE\_RSA\_WITH\_CAMELLIA\_256\_GCM\_SHA384          |
| 0xC08A        | TLS\_ECDHE\_RSA\_WITH\_CAMELLIA\_128\_GCM\_SHA256        |
| 0xC08B        | TLS\_ECDHE\_RSA\_WITH\_CAMELLIA\_256\_GCM\_SHA384        |

## Example HTTPS request

| Variable            | Value                                                                                                                                 |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `url`               | <https://www.example.com/thingsdata>                                                                                                  |
| `httpMethod`        | POST                                                                                                                                  |
| `additionalHeaders` | <p>{</p><p>  "Test-header": "Hello world"</p><p>}</p>                                                                                 |
| `sharedSecret`      | <p>C03fajLBWj$nbvOnQlV9N49zVFEobV# <br><em><strong>This is an example value! Don't use it for your own destination!</strong></em></p> |

| Properties | Value                                |
| ---------- | ------------------------------------ |
| `plugUUID` | fbc063cb-4dd4-41b3-917a-e2d1ea907f75 |

{% code title="exampleHTTPS" %}

```http
POST /thingsdata HTTP/1.1
Host: www.example.com
Things-Plug-UUID: fbc063cb-4dd4-41b3-917a-e2d1ea907f75
Things-Message-Token: a7939780a487b036d5f41edf29ee3e087b14c121302e321326865255de8ea9c9
Content-type: application/json
Content-length: 106
Test-header: Hello world

[{"bn":"urn:dev:DEVEUI:0000000000000000:","bt":1.58565075E9},{"n":"temperature","v":21.22,"u":"Celsius"}]
```

{% endcode %}

## Setup test endpoint

If you do not have an HTTPS endpoint in your back pocket, you could use services like webhook.site to setup your first endpoint to receive your IoT data.

{% embed url="<https://webhook.site>" %}

When you open the webhook.site website you will get a unique URL that you can use as endpoint for your HTTPS destination:

<figure><img src="https://1453626848-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl6RrePMSAjRvOgcHjMBZ%2Fuploads%2F8q4EurkdLVi5G9oip8ww%2Fimage.png?alt=media&#x26;token=87e8ff24-c067-4af7-a21d-9a25cb768eb3" alt=""><figcaption><p>Use the red bordered value as URL for your HTTPS destination</p></figcaption></figure>
