Contact us

BOOK A PRESENTATION

ASEE mToken

Solution concept

mToken is a comprehensive security solution powered by the ASEE Mobile Token SDK that provides comprehensive Two-Factor Authentication (2FA) and transaction signing capabilities. Designed to replace physical hardware tokens, it embeds directly into mobile applications to secure user identities and authorize financial transactions. The solution works alongside the ASEE Security Access Server (SxS) and Secure Mobile Applications Platform (SMAP) to ensure end-to-end security, managing the entire lifecycle of the software token from activation to recovery.

The following documentation is intended for security managers, project managers, business analysts, and developers and contains information about mToken functionalities, security features, and technical limitations.

How does mToken work?

mToken incorporates banking-grade security into a running application by utilizing an SDK that manages cryptographic operations and secure storage independently of the main business logic. The technology ensures that sensitive data, such as PINs, OTPs, and encryption keys, are never stored in plain text but are managed via secure classes and wiped immediately after use.

When a security event occurs, such as a login request or payment confirmation, mToken detects the requirement (via Push Notification or QR code) and calculates the necessary One Time Password (OTP) or Message Authentication Code (MAC) using the device's secure storage. By using the application to continuously monitor security parameters, such as PIN strength, biometric integrity, and inactivity time, transactions can be identified and authorized immediately without human intervention on the server side.

Supported platforms and languages

There are two versions of the Mobile Token SDK, built for Android and for iOS.

Android Mobile Token SDK is written in Java language but is fully compatible with other Java languages supported on Android, like Kotlin. This framework can be used for target devices from Android KitKat (API level 19) and higher.

iOS Mobile Token SDK is available in two builds, a build for Swift and a build for Objective-C. Both versions have all the capabilities in terms of runtime self-protection and utilize the iOS Keychain for secure storage. This framework can be used for target devices iOS 8.0 and higher.


Confirm identity for action execution with OTP

Actor: Customer, End User, SxS

Goal: Confirm that the end user is the one requesting the execution of the action

Preconditions:

  1. End user must have an enrolled token.

Steps:

  1. End user attempts to execute an action that can be considered risky
  2. Customer asks the user to confirm their identity using an OTP.
  3. End user opens an application that generates OTPs.
  4. End user types in their OTP and authorizes the execution of the action
  5. Customer validates the OTP with the SxS:
    • If OTP validation succeeds, the action can be executed
    • If OTP validation fails, the action is blocked

Result: The system ensures that only the authenticated end user can execute risky actions, enhancing security and accountability.


Confirm identity for action execution with dynamic linking

Actor: Customer, End User, SxS

Goal: Confirm that the end user is the one requesting the execution of the action.

Preconditions:

  1. End user must have an enrolled token.

Steps:

  1. End user attempts to execute an action that must be linked to the token.
  2. Customer asks the user to generate a MAC based on data that is shown to the user. The data has to be based upon a repeatable MAC input (Hash of a file, or a UUID linked to the file). This data is generated by the customer.
  3. End user opens an application that can calculate MACs. They enter the shown data.
  4. End user types in their MAC and authorizes the execution of the action
  5. Customer validates the MAC and MAC input data with the SxS:
    • If MAC validation succeeds, the action can be executed
    • If MAC validation fails, the action is blocked

Result: The system ensures that only the authenticated end user can execute risky actions, enhancing security and accountability. The action is now linked to the MAC generated. This means that with the same inputs, we can always get the same MAC.


Using SMS for confirming identity for action execution

Actor: Customer, End User, SxS

Goal: Confirm that the end user has control over the mobile phone number that is added to the Customer database.

Preconditions:

  1. End user must have an SMS token.

Steps:

  1. End user attempts to execute an action.
  2. Customer sends an SMS with OTP to the defined mobile phone number using SxS send SMS methods.
  3. End receives the SMS and sees the OTP.
  4. End user types in their OTP and authorizes the execution of the action
  5. Customer validates the OTP with the SxS:
    • If OTP validation succeeds, the action can be executed
    • If OTP validation fails, the action is blocked

Result: The system ensures that only the owner of the mobile phone number can execute the requested action.


Using PUSH notifications to give consent and dynamically link the action

Actor: Customer, End User, SxS

Goal: Confirm the identity of the user by leveraging application PUSH notifications.

Preconditions:

  1. End user must have an enrolled mToken
  2. End user application must be able to receive PUSH notifications.
  3. End user application must be connected to the internet.
  4. Customer backend must be able to handle callback methods.

Steps:

  1. End user attempts to execute an action.
  2. Customer requests from the SxS to send a PUSH notification to the end user with a given MAC input data, and a callback location.
  3. End receives the PUSH request and authorizes the action.
  4. SxS receives the MAC and MAC input data from the mobile application.
  5. SxS validates the MAC using the MAC input data.
  6. SxS calls the callback location with a result. If the result was successful, an OTP is given as well
  7. Customer validates the OTP with the SxS to confirm the validation process.
    • If OTP validation succeeds, the action can be executed
    • If OTP validation fails, the action is blocked

Result: The system ensures that only the owner of the application can execute the requested action.


Activation of mToken

Actor: Customer, End User, SxS

Goal: Enroll the mToken on the customer application.

Preconditions:

  1. Customer must either have a mToken SDK integrated into their mobile application or have a mToken standalone application.

Steps:

  1. End user requests the activation codes for mToken
  2. Customer backend calls the SxS to assign a token to the user and generate activation codes
  3. The codes are sent via SMS and email to the customer.
  4. The customer enters the codes and the mToken is activated

Result: The mToken is active and enrolled.

Technologies used

Docker – SxS is deployed as Docker container

Postman – All methods that are used as a part of this chapter are prepared in the attached postman collection

SxS healthCheck

URL: {{base-url-sxsadminws}}/api/healthCheck

Response:

Response Code: 200

Body:

{

    "message": "Service is alive and well."

}


Create SxS user

Actor: Customer, SxS

Goal: Create a user on the SxS to which we will be able to add tokens.

Steps:

  1. User runs the Docker deploy CLI command. This command will download the preconfigured SxS.
  2. Run the healthCheck method to validate that the SxS is active and ready.
  3. Run the createUser method that was provided as part of the Postman collection.

Result: SxS is up and running, and a user was created

Summary

The purpose of this chapter is to explain the process of deploying SxS and the creation of the first end user on the SxS. SxS will come preloaded with mToken licenses, which will be used later in the process of activating mTokens. As a result of this chapter, you will have a fully deployed and operational SxS as well as a user that can be used later for authentication.

Methods

The following is a list of methods and CLI commands that will be used as part of this chapter.

Docker CLI

docker run –name sxs -p 442:442 -d sxs:latest

CreateSxSUser

URL: {{base-url-sxsadminws}}/UserAdministrationService

Body:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:impl="http://impl.user.webservice.sxsadmin.sxs.asseco.hr" xmlns:hsm="http://hsm.exposed.sxsadmin.sxs.asseco.hr/">

   <soapenv:Header/>

   <soapenv:Body>

      <impl:createOrUpdateSxsUser>

         <sxsUserWS>

            <address>Address</address>

            <email>test.user@gmail.com</email>

            <firstName>Test</firstName>

            <userId>test_user</userId>

            <lastName>User</lastName>

            <mobile>+385991234567</mobile>

         </sxsUserWS>

      </impl:createOrUpdateSxsUser>

   </soapenv:Body>

</soapenv:Envelope>

Response: This method has no return value

Process

The following steps need to be executed to be able to run the SxS and create a user that will be later used:

  • On a machine, run the docker run CLI command:

docker run –name sxs -p 442:442 -d sxs:latest

  • Once the execution is done, run the following methods from the Postman collection. Make sure that the URL environment variable targets your Docker instance:

a. SxSAdminWS-healthCheck

b. SxSWS-healthCheck

  • To create the user, run the following methods from the Postman collection

a. CreateSxSUser


mToken Biometrics

Actor: Customer, End User, Token SDK, Android OS, iOS

Goal: Enable biometric authentication (fingerprint, face) to allow the user to access the token without entering a PIN.

Preconditions:

  1. Token must be successfully activated (see previous chapter).
  2. Device must run Android 6.0 (Marshmallow) or higher.
  3. User must have biometrics enrolled on the device (e.g., at least one fingerprint registered).
  4. Biometric sensor must conform to Class 3 (formerly "Strong") classification for Face, or Class 2/3 for Fingerprint.

Steps:

  1. Application checks if the token supports biometrics and if the device has biometrics capability.
  2. User requests to enable biometrics (usually via a Switch in Settings).
  3. Application prompts the user for their current PIN (required to encrypt the biometric key).
  4. Application calls secureTokenWithBiometrics(...) on a background thread.
  5. User scans their biometric (fingerprint/face) when prompted by the system.
  6. SDK encrypts the PIN and stores it securely using the Android Keystore (TEE or StrongBox).

Result: The token is secured with biometrics. Future logins can be performed using loadTokenWithBiometrics, which decrypts the stored PIN upon successful biometric authentication.

Summary

The purpose of this chapter is to explain how to enhance user experience by implementing biometric login. Instead of typing a PIN for every transaction or login, the user can authenticate using the device's hardware sensors.

The Token SDK supports Android X Biometrics (recommended) and native Android Biometrics. When enabled, the SDK creates a secure cryptographic key protected by the hardware (Trusted Execution Environment or StrongBox). This key encrypts the user's PIN. When the user successfully authenticates via biometrics, the PIN is decrypted and used internally to load the token.

Methods

  • isBiometricsAvailable()
    • Checks if the device hardware supports biometrics and if the user has enrolled data (e.g., fingerprints).
  • getTokenBiometricState(String)
    • Returns the specific state of biometrics for a token (e.g., LOCKED, NOT_ENROLLED, SECURED).
  • secureTokenWithBiometrics(...)
    • Enables biometric security. Must be called on a background thread.
  • loadTokenWithBiometrics(...)
    • Unlocks/Loads the token using biometrics. Unlocks/Loads the token using biometrics. Must be called on a background thread.
  • removeTokenBiometricsSecurity(...)
    • Disables biometric login and reverts to PIN-only mode.
  • createBiometricsCancellationWrapper(...)
    • Creates a wrapper to handle the cancellation of the biometric prompt (e.g., if the user taps "Cancel").

Process

Integrating biometrics involves handling hardware availability, threading (as biometric operations are blocking), and callbacks for UI updates.

Check availability

Before showing a "Use Biometrics" switch in your UI, verify that the specific token and device are ready. Use getTokenBiometricState to handle specific edge cases (like the user having hardware but no fingerprints enrolled).

Configure Biometric Mechanism

The SDK supports multiple mechanisms. It is strongly recommended to use ANDROID_X_BIOMETRICS as it ensures backwards compatibility and consistent UI handling across Android versions.

Enable Biometrics

This operation requires the user's current PIN. Since this method blocks execution until the user scans their finger (or cancels), it must be run on a background thread. You must implement the IBiometricProgress interface to receive updates.

void secureTokenWithBiometrics(String tokenName, CharArrayExt pin, ServerInfo serverinfo) {
    // Biometric authentication mechanism stored in this class's field
    biometricAuthenticationMechanism = BiometricAuthenticationMechanism.BIOMETRIC_PROMPT_BIOMETRICS;

    // Biometrics cancellation wrapper stored in this class's field.
    biometricsCancellationWrapper = TokenFacade.createBiometricsCancellationWrapper(biometricAuthenticationMechanism);

    // NOTE: handling of disposable purposely left out. Disposable must be handled in order not to get garbage collected.
    Completable.fromAction(() -> {
        TokenFacade.getToken(tokenName)
            .secureTokenWithBiometrics(
                pin,
                serverinfo,
                biometricsCancellationWrapper,
                new IBiometricProgress() {
                    @Override
                    public void onFingerAuthenticated() {
                        // Dismiss UI element indicating that fingerprint scanning is in progress,
                        // and replace with loading indicator for example.
                    }

                    @Override
                    public void onAuthenticationFailed() {
                        // Display that an error has occurred during fingerprint scanning.
                    }
                },

BiometricPromptText.createWithRequiredFieldsOnly("Title", "Cancel"),
                false,
                BiometricSecuritySpecification.DEFAULT,
                biometricAuthenticationMechanism,
                null
            );
    })
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(
        this::processSecureTokenSuccess,
        this::processSecureTokenFailure
    );
}
private void processSecureTokenSuccess() {
    // Continue with business logic which must be done when token action related to biometrics is done.
    // This is the place do dismiss „Loading UI“ element which was shown in „onFingerprintAuthenticated“ callback.
}

Login with Biometrics

To use the token later, use loadTokenWithBiometrics. This replaces the standard loadToken method. Like the enabling process, this must be done on a background thread.

Handling Biometric invalidation

If you set invalidateOnFingerprintEnrollment = true during setup, and the user subsequently adds a new fingerprint to their Android settings, the token biometric link becomes invalid for security reasons.

  • Detection: getTokenBiometricState() returns TOKEN_BIOMETRICS_INVALIDATED_DUE_TO_NEW_FINGERPRINT.
  • Resolution: You must call removeTokenBiometricsSecurity(...) and then ask the user to re-enable biometrics (re-enter PIN) via secureTokenWithBiometrics(...).

Token activation

Actor: Customer, End User, SxS

Goal: Activate the mobile token so it can be used for authentication operations.

Preconditions:

  1. Customer mobile application must have the Token SDK integrated.
  2. Activation codes (16-digit string) must be generated and distributed to the end user.
  3. Token name (unique identifier) must be defined by the developer.

Steps:

  1. End user receives the activation codes (first 8 digits = clientID; second 8 digits = activationCode).
  2. Customer backend calls SxS to generate and distribute activation codes to the user.
  3. The end user enters the activation codes and defines a PIN.
  4. The application invokes the SDK method activateAndLoad(...) with:
    • tokenName (unique identifier)
    • clientID (first 8 digits)
    • activationCode (second 8 digits)
    • optionally userId, if SxS is configured to validate it
  5. The SDK validates the activation codes. If incorrect codes are entered three times (or the SxS-configured limit), the token cannot be activated anymore even with correct codes.
  6. If successful, the token is activated, securely stored on disk/KeyChain, and remains available for retrieval via getToken(tokenName).

Result: The token is successfully activated, securely stored, and in the loaded state. A token with the same tokenName cannot be activated again unless the existing token is deleted using deleteTokenFromStorage().

Summary

The purpose of this chapter is to explain the integration steps required to activate a mobile token on the end user's device. While the previous chapter dealt with the server-side user creation, this chapter focuses on binding the mobile application instance to that user securely.

Token activation is the process where the application exchanges the activation codes (obtained from the SxS via the backend) and a user-defined PIN for a secure, encrypted token stored on the device. As a result of this chapter, the mobile application will hold an active token capable of generating OTPs, signatures, and performing authentication.

Methods

The following is a list of SDK methods and API endpoints that will be used as part of this chapter.

SDK

mtmRedistributeToken

URL: http://host:port/SxSAdminWS/services/MobileTokenManagementService

SxS

mtmRedistributeToken

URL: http://host:port/SxSAdminWS/services/MobileTokenManagementService

Body:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:impl="http://impl.mtm.webservice.sxsadmin.sxs.asseco.hr" xmlns:hsm="http://hsm.exposed.sxsadmin.sxs.asseco.hr/">

   <soapenv:Header/>

   <soapenv:Body>

      <impl:mtmRedistributeTokenRequest>

         <sxsUserWS>

            <userId>new_user</userId>

         </sxsUserWS>

         <tokenProfileId>1393</tokenProfileId>

  <serviceIds>6</serviceIds>     

      </impl:mtmRedistributeTokenRequest>

   </soapenv:Body> </soapenv

Response: This method returns the tokenSN of the enrolled mobile token.

mtmRenewActivationCode

URL: http://host:port/SxSAdminWS/services/MobileTokenManagementService

Body:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:impl="http://impl.mtm.webservice.sxsadmin.sxs.asseco.hr">
   <soapenv:Header/>
   <soapenv:Body>
      <impl:mtmRenewActivationCodeRequest>
         <tokensn>2000038252</tokensn>
         <generateNew>true</generateNew>
      </impl:mtmRenewActivationCodeRequest>
   </soapenv:Body>
</soapenv:Envelope>


mtmGetActivationCode

Body:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:impl="http://impl.mtm.webservice.sxsadmin.sxs.asseco.hr">
   <soapenv:Header/>
   <soapenv:Body>
      <impl:mtmGetActivationCodeRequest>
         <tokensn>2000038252</tokensn>
         
<formatId>1</formatId>
      </impl:mtmGetActivationCodeRequest>
   </soapenv:Body>
</soapenv:Envelope> 

Response: This method has returned the Activation code.

Process:

SDK initialization

Before attempting the activation, the Token SDK must be initialized. This should ideally happen in the onCreate() method of your Application class to ensure it's ready before any UI is shown.

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        // 
            // Handle initialization error
        }
    }
}

Obtain activation codes

Before the mobile application can activate a token, the Customer Backend must provision the token on the SxS and retrieve the credentials. This is a three-step process performed via the MobileTokenManagementService SOAP API:

  1. Enroll the Token (mtmRedistributeToken): Call this method with the target userId and tokenProfileId. The response will contain the Token Serial Number (tokensn), which is required for the subsequent steps.
  2. Generate Code (mtmRenewActivationCode): Call this method using the tokensn obtained in step 1 with the flag generateNew set to true. This triggers the generation of a fresh code on the server.
  3. Fetch Code (mtmGetActivationCode): Call this method using the tokensn to retrieve the actual activation string. Set formatId to 1 to get the full 16-digit code.

Result: The backend receives a 16-digit string. This must be split and provided to the user:

  • Digits 1–8: ClientID
  • Digits 9–16: ActivationCode

Check for existing token

Before calling the activation method, it is best practice to check if a token with the desired name already exists to avoid exceptions.

String tokenName = "MyMobileToken"; // Unique identifier defined by developer
try {
    if (TokenFacade.hasToken(tokenName)) {
        // Token already exists. 
        // Logic to delete the old token or skip activation.
    }
} catch (TokenException e) {
    // Handle check error
}

Activate the Token

Once the user inputs the codes and defines a PIN, call the activateAndLoad method. Note that sensitive data uses CharArrayExt instead of standard Strings for security reasons.

// Prepare input data
String tokenName = "MyMobileToken";
CharArrayExt clientId = new CharArrayExt("12345678"); // First 8 digits
CharArrayExt actCode = new CharArrayExt("87654321");  // Second 8 digits
CharArrayExt pin = new CharArrayExt("1234");          // User defined PIN
CharArrayExt licenseKey = new CharArrayExt("YOUR_LICENSE_KEY"); 
ServerInfo serverInfo = new ServerInfo();             // Configure server connection details

try {
    // Perform Activation
    TokenFacade token = TokenFacade.activateAndLoad(
        tokenName,
        clientId,
        actCode,
        licenseKey,
        pin,
        serverInfo
    );
    
    // Result: Token is now active, loaded, and ready for use
    
} catch (TokenException e) {
    // Handle activation failure
    // e.g., Invalid codes, network error, or activation limit reached
    int errorCode = e.getErrorCode();
}

Note: If the activation fails 3 times (default SxS configuration) due to incorrect codes, the activation string becomes invalid and a new one must be generated via the backend.


OTP Validation

Actor: Customer, End User, SxS

Goal: Verify the validity of a generated OTP

Preconditions:

  1. Token must be in the loaded state (unlocked with PIN).
  2. Device must have network access to reach the SxS.

Steps:

  1. The end user triggers an action (e.g., Login) on the mobile app.
  2. The mobile SDK generates an OTP using the OTP_APP slot.
  3. The mobile app sends this OTP (and username/tokenSN) to the Customer Backend.
  4. The Customer Backend invokes the validateOtp SOAP method on the SxS.
  5. The SxS checks the OTP against its internal records.
  6. The SxS returns a success response (TokenSN/UserID) or an exception (Wrong OTP).

Result: The user is either authenticated (success) or rejected (failure/lockout).

Summary

The purpose of this chapter is to explain the server-side validation of the OTP. After the mobile application generates an OTP locally, it must be verified by the central authentication server (SxS) to ensure it matches the expected value. This process confirms the user's identity and that they are in possession of the specific mobile device.

Methods

validateOtp

URL: http://host:port/SxSWS/SxS5Authentication

Body:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:aut= "http://authentication.ws.sxs.logos.hr">
   <soapenv:Header/>
   <soapenv:Body>
      <aut:validateOtpRequest>
         <otp>740627</otp>

         <TokenSN>2000038252</TokenSN>
   	   <applicationProfileName>OTP_APP</applicationProfileName>

   <!--<UserID>test</UserID>-->
      </aut:validateOtpRequest>
   </soapenv:Body>
</soapenv:Envelope>

Response: If OTP is correct, only tokenSN (and userID) are returned, otherwise, an error will be returned (with code and message).

Process

The validation process begins when the mobile application sends the locally calculated OTP and the user's identifier (Token Serial Number or UserID) to the Customer Backend. Upon receiving these details, the backend must construct a SOAP request to the SxS5Authentication web service, specifically invoking the validateOtp method. It is critical to include the Organization ID in the HTTP headers and ensure the applicationProfileName parameter is set to "OTP_APP".

Once the request is sent, the backend must parse the SOAP response from the SxS to determine the outcome. In a successful scenario, the SxS returns the tokenSN and userId without errors, indicating the OTP is valid. However, if the validation fails (e.g., due to an incorrect OTP or a locked token), the response will contain an exception object detailing the specific exceptionCode and exceptionMessage. The backend should use this information to approve the user's login or return an appropriate error message to the client.

CyberSecurityhub

chevron-down linkedin facebook pinterest youtube rss twitter instagram facebook-blank rss-blank linkedin-blank pinterest youtube twitter instagram