Skip to main content

Account Message Signing

This is an advanced option that enables a method in the SDK to sign arbitrary messages, using HMAC with the SHA-256 algorithm. The HMAC key is account specific, so that the same key is used for all devices using the same account. Each Approov account uses a distinct signing key.

info

As well as account specific message signing, Approov also offers Installation Message Signing where requests are signed using an installation specific signing key. Both methods can be employed together, but we would advise the use of installation message signing before employing this account message signing option.

The feature ensures strict message integrity between the client app and the backend API, and is also an additional proof that the requests are truly emananting from an app that has passed the Approov attestation process. Message integrity is also assured by Managing Dynamic Pinning, which we strongly recommend that you implement (all of our frontend integration quickstarts do this). We provide account message signing as an advanced option for certain situations where an additional level of integrity assurance is required.

When account message signing is enabled the Approov account is assigned a random 512-bit secret that is used for the signing process. This secret key is only transmitted to the SDK if it passes attestation and is provided with a valid Approov token. If the attestation fails, and an incorrectly signed Approov token is sent, then an incorrect message signing secret is provided so that the app's message signatures will be incorrect.

Enabling Account Message Signing

Account message signing can be enabled on the account as follows:

approov secret -messageSigningKey change

An admin role and confirmation is required:

WARNING: changing the message signing key will have an immediate impact on your apps in production
ATTENTION: If you wish to continue then please type YES and return: YES
key ID: EXTnGx
encoding: base64
RVhUbkd4b01iQ1N3R3Y2cGM4dVdsTEU1UG14S3VOTVhkVDk1dWstb0xPVFZtSEZkdVRueW1lYmRUZWFmR1U3SQ==

All further Approov fetches will also transmit the signing secret to the SDK and the key ID for it will appear in the mskid claim in Approov tokens. The generated message signing secret is provided in base64 format. It can also be obtained in other formats.

The command can also be used to change the message signing secret to a new random value if required. Remember that the new secret must be made available to backend systems to do the signature verification.

Getting the Account Message Signing Key

The current account message siging key can be obtained as follows:

approov secret -messageSigningKey get-raw

An admin role is required and the output will be something like the following:

key ID: EXTnGx
encoding: raw
EXTnGxoMbCSwGv6pc8uWlLE5PmxKuNMXdT95uk-oLOTVmHFduTnymebdTeafGU7I

This example uses get-raw to get the raw secret value which is always 64 characters long. The generated secret only consists of printable characters, to support this.

Note that the key ID, which is included in the mskid claim of Approov tokens, is composed of the first few characters of the raw secret.

You can also obtain a base64 or base64url encoded form of the secret key with get-base64 or get-base64url.

Disabling Account Message Signing

Account message signing can be disabled on the account as follows:

approov secret -messageSigningKey clear

An admin role and confirmation is required:

WARNING: changing the message signing key will have an immediate impact on your apps in production
ATTENTION: If you wish to continue then please type YES and return: YES
message signing key cleared

Once disabled, the Approov cloud service will stop adding the mskid claim to new Approov tokens. Furthermore, once running apps receive their next token, the signing secret will be cleared and the message signing method in the SDK will no longer generate signatures.

tip

Prior to going into production you may wish to check the impact of clearing the message signing key, and that this continues to allow backend API operation as expected. This emulates the behavior expected should the Approov cloud system automatically transition to failover operation.

Implementing Account Message Signing

The Mobile App Quickstarts support account message signing as a configuration option. The configuration options also specify the set of headers that should be included in the signatures. All headers that are intended to reach the backend server and influence its behaviour should be included. The request HTTP verb, URL and body are always included.

When enabled, the quickstart integration concatenates the relevant parts of a request into a single string. This is then passed to the device signing method in the SDK to obtain the signature. This signature is then itself added to the request as an additional header. This is provided in addition to the Approov token header, which is included in the message integrity calculation. Moreover, you should always include the Approov token itself as part of the string submitted for signing as this prevents replay attacks (since the Approov token has a short expiration time).

Various of the Backend API Quickstarts also support account message signing checking. To do this they need to be provided with the secret account message signing key. The backend integration will first check the validity of the Approov token in the normal way. If the account message key ID mskid claim is present in the token (and matches the expected key ID) then it will also check the account message signing integrity. It is able to gather the components of the request and build the same single string as the client and verify the expected signature using the provided secret key. A failure indicates that the request has been tampered with in some way during transit or the originator of the message did not have access to private key corresponding to the public key provided.

It is not necessary to enforce signature checking on all API endpoints. You may wish to only apply it on particularly security sensitive ones. Of course, there must be consistency between the app and the backend API in these choices.