Integrate in Android

The MIRACL Trust Android SDK provides the following functionalities:

# System Requirements

  • Android API 21 or newer

# Installation

# Manual

Contact us at support@miracl.com to get the latest framework version and then import it in your application:

  1. Put the downloaded artifact in the libs folder under the project root folder

  2. Add the following line to the dependencies section in your module build.gradle

    Kotlin:

    dependencies {
        implementation(fileTree(mapOf("dir" to "libs", "include" to listOf(".jar", ".aar"))))
    }
    

    Groovy:

    dependencies{
        implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
    }
    

# Usage

It is a prerequisite to have an application in the MIRACL Trust platform. For a detailed guide on how to create one, see the Getting Started.

# Create Configuration object through its Builder

Kotlin:

val configuration =
    Configuration.Builder(YOUR_PROJECT_ID)
        // To set custom device name. Defaults to the model of the device.
        .deviceName(yourDeviceName)
        // To set custom [HttpRequestExecutor] implementation
        .httpRequestExecutor(yourHttpRequestExecutor)
        // To set custom [UserStorage] implementation
        .userStorage(yourUserStorage)
        // To set custom [Logger] implementation
        .logger(yourLogger)
        // To set specific [LoggingLevel] to be used by the default [Logger]
        .loggingLevel(Logger.LoggingLevel.yourSelectedType)
        .build()

Java:

Configuration configuration =
        new Configuration.Builder(YOUR_PROJECT_ID)
                // To set custom device name. Defaults to the model of the device.
                .deviceName(yourDeviceName)
                // To set custom [HttpRequestExecutor] implementation
                .httpRequestExecutor(yourHttpRequestExecutor)
                // To set custom [UserStorage] implementation
                .userStorage(yourUserStorage)
                // To set custom [Logger] implementation
                .logger(yourLogger)
                // To set specific [LoggingLevel] to be used by the default [Logger]
                .loggingLevel(Logger.LoggingLevel.yourSelectedType)
                .build();

# Initialize the SDK

Kotlin:

class YourApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        MIRACLTrust.configure(applicationContext, configuration)
    }
}

Java:

public class YourApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        MIRACLTrust.configure(getApplicationContext(), configuration);
    }
}

Call the configure method as early as possible in the application lifecycle and avoid using the getInstance() method before that; otherwise assertion will be triggered.

# Obtain instance of the SDK

Kotlin:

val miraclTrust = MIRACLTrust.getInstance()

Java:

MIRACLTrust miraclTrust = MIRACLTrust.getInstance();

# User ID Verification

To register a new User ID, you need to verify it. MIRACL Trust offers two options for that:

  • Custom User Verification.

  • Default verification - Confirm the User ID via email message.

    The default verification uses Android’s App Links to navigate back to the application from the email message.

    Start the verification by calling of the sendVerificationEmail method:

    Kotlin:

    miraclTrust.sendVerificationEmail(
        userId = USER_ID,
        resultHandler = ResultHandler { result ->
            when (result) {
                is MIRACLSuccess -> {
                    // Verification email is sent.
                }
                is MIRACLError -> {
                    val error = result.value
                    // Verification email is not sent due to an error.
                }
            }
        }
    )
    

    Java:

    miraclTrust.sendVerificationEmail(
        USER_ID,
        result -> {
            if (result instanceof MIRACLSuccess) {
                // Verification email is sent.
            } else {
                MIRACLError<VerificationResponse, VerificationException> error =
                        (MIRACLError<VerificationResponse, VerificationException>)
                                result;
                // Verification email is not sent due to an error.
            }
        }
    );
    

# Registration

  1. To register the mobile device, get an activation token using the getActivationToken method and the received verification URL:

    Kotlin:

    intent?.data?.let { verificationUri ->
        miraclTrust.getActivationToken(
            verificationUri,
            resultHandler = { result ->
                when (result) {
                    is MIRACLSuccess -> {
                        val userId = result.value.userId
                        val activationToken = result.value.activationToken
    
                        // Use the activation token and the User ID to register the user.
                    }
    
                    is MIRACLError -> {
                        val error = result.value
                        // Cannot obtain activation token due to an error.
                    }
                }
            }
        )
    }
    

    Java:

    Uri verificationUri = intent.getData();
    if (verificationUri != null) {
        miraclTrust.getActivationToken(verificationUri, result -> {
            if (result instanceof MIRACLSuccess) {
                ActivationTokenResponse response =
                        ((MIRACLSuccess<ActivationTokenResponse, ActivationTokenException>)
                                result).getValue();
    
                String userId = response.getUserId();
                String activationToken = response.getActivationToken();
    
                // Use the activation token and the User ID to register the user.
            } else {
                MIRACLError<ActivationTokenResponse,
                        ActivationTokenException> error =
                        (MIRACLError<ActivationTokenResponse, ActivationTokenException>)
                                result;
                // Cannot obtain activation token due to an error.
            }
        });
    }
    
  2. Pass the User ID (email or any string you use for identification), activation token (received from verification), PinProvider and ResultHandler implementations to the register function. When the registration is successful, a ResultHandler callback is returned, passing a MIRACLSuccess together with the registered user as its value. Otherwise, MIRACLError with corresponding message is passed in the callback.

    Kotlin:

    miraclTrust.register(
        userId = USER_ID,
        activationToken = activationToken,
        pinProvider = { pinConsumer ->
            // Ask the user to create a PIN code for their new User ID.
            // Then pass the PIN code to the PinConsumer.
            pinConsumer.consume(userPin)
        },
        resultHandler = { result ->
            when (result) {
                is MIRACLSuccess -> {
                    val user = result.value
                }
    
                is MIRACLError -> {
                    val error = result.value
                    // Cannot register user due to an error.
                }
            }
        }
    )
    

    Java:

    miraclTrust.register(
        USER_ID,
        activationToken,
        pinConsumer -> {
            // Ask the user to create a PIN code for their new User ID.
            // Then pass the PIN code to the PinConsumer.
            pinConsumer.consume(userPin);
        },
        result -> {
            if (result instanceof MIRACLSuccess) {
                User user = ((MIRACLSuccess<User, RegistrationException>) result).getValue();
            } else {
                MIRACLError<User, RegistrationException> error =
                        (MIRACLError<User, RegistrationException>) result;
                // Cannot register user due to an error.
            }
        }
    );
    

    If you call the register method with the same User ID more than once, the User ID will be overridden. Therefore, you can use it when you want to reset your authentication PIN code.

# Authentication

MIRACL Trust SDK offers two options:

# Authenticate users on the mobile application

The authenticate method generates a JWT authentication token for а registered user.

Use PinProvider the same way it is used during registration.

Kotlin:

miraclTrust.authenticate(
    user = user,
    pinProvider = pinProvider,
    resultHandler = ResultHandler { result ->
        when (result) {
            is MIRACLSuccess -> {
                // user is authenticated
                val jwt = result.value
            }
            is MIRACLError -> {
                // user is not authenticated
            }
        }
    }
)

Java:

miraclTrust.authenticate(
    user,
    pinProvider,
    result -> {
        if (result instanceof MIRACLSuccess) {
            // user is authenticated
            String jwt = ((MIRACLSuccess<String, AuthenticationException>) result).getValue();
        } else {
            // user is not authenticated
        }
    }
);

After the JWT authentication token is generated, it needs to be sent to the application server for verification. Then, the application server verifies the token signature using the MIRACL Trust JWKS endpoint and the audience claim, which in this case is the application Project ID.

# Authenticate users on another application

To authenticate a user on another application, there are three options:

  • Authenticate with AppLink

    Kotlin:

    intent.data?.let { appLink ->
        miraclTrust.authenticateWithAppLink(
            user = user,
            appLink = appLink,
            pinProvider = pinProvider,
            resultHandler = ResultHandler { result ->
                when (result) {
                    is MIRACLSuccess -> {
                        // user is authenticated
                    }
    
                    is MIRACLError -> {
                        // user is not authenticated
                    }
                }
            }
        )
    }
    

    Java:

    Uri appLink = getIntent().getData();
    if (appLink != null) {
        miraclTrust.authenticateWithAppLink(
            user,
            appLink,
            pinProvider,
            result -> {
                if (result instanceof MIRACLSuccess) {
                    // user is authenticated
                } else {
                    // user is not authenticated
                }
            }
        );
    }
    
  • Authenticate with QR code

    Kotlin:

    miraclTrust.authenticateWithQRCode(
        user = user,
        qrCode = qrCode,
        pinProvider = pinProvider,
        resultHandler = ResultHandler { result ->
            when (result) {
                is MIRACLSuccess -> {
                    // user is authenticated
                }
                is MIRACLError -> {
                    // user is not authenticated
                }
            }
        }
    )
    

    Java:

    miraclTrust.authenticateWithQRCode(
        user,
        qrCode,
        pinProvider,
        result -> {
            if (result instanceof MIRACLSuccess) {
                // user is authenticated
            } else {
                // user is not authenticated
            }
        }
    );
    
  • Authenticate with notification

    Kotlin:

    val payload = remoteMessage.data
    miraclTrust.authenticateWithNotificationPayload(
        payload = payload,
        pinProvider = pinProvider,
        resultHandler = ResultHandler { result ->
            when (result) {
                is MIRACLSuccess -> {
                    // user is authenticated
                }
                is MIRACLError -> {
                    // user is not authenticated
                }
            }
        }
    )
    

    Java:

    Map<String, String> payload = remoteMessage.getData();
    miraclTrust.authenticateWithNotificationPayload(
        payload,
        pinProvider,
        result -> {
            if (result instanceof MIRACLSuccess) {
                // user is authenticated
            } else {
                // user is not authenticated
            }
        }
    );
    

For more information about authenticating users on custom applications, see Cross-Device Authentication.

# Signing

DVS stands for Designated Verifier Signature, which is a protocol for cryptographic signing of documents. For more information, see Designated Verifier Signature. In the context of this SDK, we refer to it as ‘Signing’.

To sign a document, use the sign method as follows:

Kotlin:

miraclTrust.sign(
    hashedMessage,
    timestamp,
    user,
    pinProvider
) { result ->
    when (result) {
        is MIRACLSuccess -> {
            val signature = result.value
        }
        is MIRACLError -> {
            val error = result.value
            // Cannot sign the message/document due to an error.
        }
    }
}

Java:

miraclTrust.sign(
        hashedMessage,
        timestamp,
        user,
        pinProvider,
        result -> {
            if (result instanceof MIRACLSuccess) {
               Signature signature =
                       ((MIRACLSuccess<Signature, SigningException>) result).getValue();
            } else {
                MIRACLError<Signature, SigningException> error =
                        (MIRACLError<Signature, SigningException>) result;
                // Cannot sign the message/document due to an error.
            }
        }
);

The signature needs to be verified. This is done when the signature is sent to the application server, which then makes an HTTP call to the POST /dvs/verify endpoint. If the MIRACL Trust platform returns status code 200, the certificate entry in the response body indicates that signing is successful.

# QuickCode

QuickCode is a way to register another device without going through the verification process.

# Generate QuickCode

Kotlin:

miraclTrust.generateQuickCode(
    user,
    pinProvider
) { result ->
    when (result) {
        is MIRACLSuccess -> {
            val quickCode = result.value
        }
        is MIRACLError -> {
            val error = result.value
            // handle error
        }
    }
}

Java:

miraclTrust.generateQuickCode(
    user,
    pinProvider,
    result -> {
        if (result instanceof MIRACLSuccess) {
            QuickCode quickCode =
                    ((MIRACLSuccess<QuickCode, AuthenticationException>) result).getValue();
        } else {
            MIRACLError<QuickCode, AuthenticationException> error =
                    (MIRACLError<QuickCode, AuthenticationException>) result;
            // handle error
        }
    }
);

# Dependencies

MIRACL Trust SDK Android depends on:

  1. GSON
  2. Kotlin Coroutines
  3. Room Persistence Library
  4. SQLCipher

# FAQ

  1. How to provide PIN code?

    For security reasons, the PIN code is sent to the SDK at the last possible moment. A PinConsumeris responsible for that and when the SDK calls it, the currently executed operation is blocked until a PIN code is provided. Therefore, this is a good place to display some user interface for entering the PIN code. Implement PinProvider and use it to obtain a PIN. Then pass the PIN to the PinConsumer.

    Kotlin:

    val pinProvider =
        PinProvider { pinConsumer ->
            val pin = /* user pin */
            pinConsumer.consume(pin)
        }
    

    Java:

    PinProvider pinProvider =
        pinConsumer -> {
            String pin = /* user pin */
            pinConsumer.consume(pin);
        };
    
  2. What is Project ID?

    Project ID is a common identifier of applications in the MIRACL Trust platform that share a single owner.

    You can find the Project ID value in the MIRACL Trust Portal:

    1. Go to trust.miracl.cloud.
    2. Log in or create a new User ID.
    3. Select your project.
    4. In the CONFIGURATION section, go to General.
    5. Copy the Project ID value.

# Documentation