MAC Token Based Authentication

While standard PowerAuth authentication codes are suitable for requests where a high degree of authenticity and integrity is required, for high-volume common access requests, the strong sequentiality caused by the use of a counter might be too restricting. Signed requests must be sent one by one, and a request needs to wait for the previous one to complete. This causes both data processing to be slow and the programming task related to request synchronization to be unnecessarily difficult.

This is why PowerAuth also supports simplified MAC Token-Based Authentication. As the name suggests, the authentication is achieved by computing a MAC (also called a “digest”) using a pre-shared token.

Security Considerations

There are a couple of very important things to keep in mind while using MAC Token-Based Authentication in your APIs:

  • Data Integrity - Since the resulting digest does not include any request data, it does not prevent data from being modified.
  • Single Factor - While the token has information about the factors used while the token was created, which is handy while distinguishing different grades of information (for example, some more sensitive info may require a token that was created using 2FA), the authentication as such uses only a single factor. It does not include PIN/password or biometric information at all.

As a result, you must use MAC Token-Based Authentication for read-only operations only. In other words, use the MAC Token-Based Authentication to access resources, not to create or modify them. We recommend using the 1FA PowerAuth authentication code for active operations that create or modify resources but do not require user’s interaction. This way, you avoid having repeated or inconsistent data while allowing access to information that needs to be frequently accessed.

Examples:

MAC Token-Based Authentication

Accessing simple information about the account, such as account name, balance of the account, and last three transactions, from Apple Watch.

PowerAuth 1FA Authentication Codes

Creating a quick, low-value payment from an iPhone app.

Creating a Token

In order to create a new token, the client application must call a PowerAuth Standard RESTful API endpoint /pa/v4/token/create.

This endpoint must be called with a standard PowerAuth authentication code. It can be any type of authentication code - 1FA or 2FA. The token then implicitly carries the information about the authentication code it was issued with. Using the PowerAuth authentication code assures the authenticity and integrity of the data sent during the request.

The endpoint then uses the same request and response encryption principles as described in a dedicated chapter for End-to-End Encryption.

Upon receiving and successfully validating a request authenticated using a PowerAuth authentication code, the server generates a new token for a given activation ID. Information about the used authentication code type and factors are stored with the token. Then, the server takes the token ID and secret and sends them in an encrypted response to the client.

The decrypted response data payload contains the following raw response format:

{
  "tokenId": "d6561669-34d6-4fee-8913-89477687a5cb",
  "tokenSecret": "VqAXEhziiT27lxoqREjtcQ=="
}

The tokenId value is in UUID level 4 format, and it uniquely identifies the token in the system and is sent with every request that requires MAC token-based authentication. The token_secret value is a random 16B value encoded as Base64. It is stored on the device and used as a secret key for computing the MAC later.

The client stores both token_id and token_secret in a suitable local storage (iOS Keychain, encrypted Shared Preferences).

Using the Tokens

When using MAC Token-Based Authentication, the authentication of the RESTful API calls is achieved by computing a token_digest value on the client side that can be later validated on the server side. The algorithms for calculation and verification of the digest are, in principle, the same.

The token_digest value is computed from the following input:

  • nonce – 16 bytes of random data
  • timestamp – Unix timestamp in milliseconds, converted to UTF-8 bytes from a string value
  • version – protocol version (for example "4.0")
  • token_secret – 16 random bytes associated with the token

The binary input for the MAC is constructed as:

nonce + "&" + timestamp + "&" + version

Protocol Version 4.0

For version 4.0, the digest is computed using KMAC256 with a custom string PA4DIGEST:

byte[] timestamp = String.valueOf(System.currentTimeMillis()).getBytes(StandardCharsets.UTF_8);
byte[] nonce = Generator.randomBytes(16);
byte[] version = "4.0".getBytes(StandardCharsets.UTF_8);
byte[] data = ByteUtils.concat(nonce, "&".getBytes(StandardCharsets.UTF_8), timestamp, "&".getBytes(StandardCharsets.UTF_8), version);
SecretKey key = convertBytesToSharedSecretKey(token_secret);
byte[] token_digest = Kmac.kmac256(key, data, "PA4DIGEST".getBytes(StandardCharsets.UTF_8));

In order to use the token authentication with the RESTful API call, you need to set the following HTTP header to the request:

X-PowerAuth-Token: PowerAuth token_id="${TOKEN_ID}"
    token_digest="${TOKEN_DIGEST}"
    nonce="${NONCE}"
    timestamp="${TIMESTAMP}"
    version="4.0"

Transport representation of the HTTP header properties is following:

  • token_id - Identifier of the token, as is - UUID level 4.
  • token_digest - Digest value computed using token_secret, nonce, timestamp, and version, Base64 encoded.
  • nonce - Random cryptographic nonce, 16B long, Base64 encoded.
  • timestamp - Current timestamp in a Unix timestamp format (in milliseconds, to achieve required time precision), represented as a string value.
  • version - Protocol version.

Token Removal

You can remove a token with a given ID anytime by sending a signed request to the PowerAuth Standard RESTful API endpoint /pa/v4/token/remove:

{
  "requestObject": {
    "tokenId": "d6561669-34d6-4fee-8913-89477687a5cb"
  }
}

You can use any authentication code type to authenticate the token removal request. All authentication code types are allowed because the tokens are mostly used for simplified access. Allowing the user to restrict the access again should be simple, as long as there is at least some authentication that would prevent removing token to the malicious party (causing DoS to the legitimate user).

If the authentication code validation is successful and after validating that the token is associated with the activation used for computing the authentication code, the token is removed on the server side. The response object only confirms the removal and the payload is typically ignored in the PowerAuth Mobile SDK:

{
  "requestObject": {
    "tokenId": "d6561669-34d6-4fee-8913-89477687a5cb"
  }
}
Last updated on Feb 04, 2026 (10:22) Edit on Github Send Feedback
Search

develop

PowerAuth Java Crypto