Android 3DS SDK

Introduction

This document serves as a guide for the integrator of Ravelin’s Android 3DS SDK, providing details on how the SDK should be configured and integrated into an Android application or library.

System Requirements and Delivery

Ravelin’s Android 3DS SDK supports a minimum Android version Android 5 (API Level 21).

Developed as a standard Android Library, Ravelin provides a single AAR artifact along with the Maven POM file that lists dependencies.

We also include:

  • SDK API Javadoc
  • License file
  • Integration Guide document

Versioning

The Android 3DS SDK follows semantic versioning - The version can be described as PROTOCOL.MAJOR.MINOR.PATCH, where:

  • PROTOCOL - major protocol version, i.e. 2
  • MAJOR - new features
  • MINOR - improvements
  • PATCH - bug / security fix

Supporting documentation

The following documents should be used in conjunction with this guide:


Integration

This section provides technical details on how to integrate the Android 3DS SDK into your application.

Gradle Setup

The first step is to declare the SDK as a dependency in your project using Gradle. You can include it using Maven or by referencing it as a local artefact.

Via Maven Repository

You can publish the .aar and .pom files to a private Maven repository, and then declare the dependency by editing build.gradle:

dependencies {
  implementation 'com.netcetera.android-3dssdk:3ds-sdk:2.0.0'
}

Via Local Artefact

You can include the .aar artefact as a local library, however all the SDK’s dependencies will need to be added manually:

  1. Add the provided .aar artefact to the libs/ directory of your project.

  2. Add the SDK dependency in the build.gradle file

dependencies {
  implementation files('libs/filename.aar')
}
  1. Add the external dependencies

Building the 3DS SDK into another Android Library

The SDK can be bundled into another Android Library with the purpose of delivering an integration as a single artefact to a client. Because the Gradle plugin doesn’t officially support bundling an Android Library with another yet, and there are no reliable third-party plugins, you’ll have to do this manually:

  1. Extract the SDK by renaming the .aar file to a .zip file.

  2. Move the resulting classes.jar into the libs folder of the other Android Library, and ensure they’re included as dependencies:

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

Note: The classes.jar contains some additional binaries other than “.class” and will only be packaged correctly in the other library when using Android Gradle Plugin 3.5.0 or greater.

  1. Move the contents of the jni folder into the library’s src/main/jniLibs. Not all .so files have to be included, just the ones that the library wants to support - for example, mips and armeabi might not be required as their market share is very low. The final result should look like this:
.
└── main
   └── jniLibs
      ├── arm64-v8a
      │   └── <contents from the `jni/arm64v8a`>
      ├── armeabi
      │   └── <contents from the `jni/armeabi`>
      ├── armeabi-v7a
      │   └── <contents from the `jni/armeabi-v7a`>
      ├── mips
      │   └── <contents from the `jni/mips`>
      ├── x86
      │   └── <contents from the `jni/x86`>
      └── x86_64
          └── <contents from the `jni/x84_64`>
  1. Add the DS logos from the res folder into the library’s drawable resources. The final structure should look like this:
.
└─ main
   └── res
       ├── drawable
       │   ├── ds_logo_amex.xml
       │   ├── ds_logo_mastercard.xml
       │   ├── ds_logo_visa.xml
       │   └── <Other Drawable resources>
       └── values
           └── values.xml

Note: You cannot change the file names here otherwise the SDK won’t be able to reference them.

  1. Add the external dependencies

License Setup

Using ConfigParameters

One of the ways to set up your license is by using ConfigParameters.addParam(...) with the following arguments:

group: null
paramName: "license-key"
paramValue: Content of license file

Example:

ConfigParameters.addParam(null, "license-key", "eyJhbGciOiJ...");

Using ConfigurationBuilder

You can also use the ConfigurationBuilder by calling the ConfigurationBuilder.license(...) function with the content of the license file

Example:

ConfigurationBuilder().license("eyJhbGciOiJ...").build();

Android Studio Javadoc Setup

To set up Javadoc, you’ll need the 3ds-sdk-javadoc.jar file in the delivered package:

  1. Open the “External Libraries” view in Android Studio
  2. Locate the 3DS SDK Library
  3. Right click and open “Library Properties…”
  4. Using the + button, add the delivered Javadoc.

Dependencies

The following table contains all the third-party libraries used in the Android 3DS SDK.

The libraries that are marked as embedded are bundled into the SDK codebase, and you won’t need to add them as dependencies. Conversely, you’ll need to add the others as dependencies, unless marked as optional.

Name Website Embedded? License
Apache Commons https://www.apache.org/ Yes Apache 2.0
jose.4.j https://bitbucket.org/b_c/jose4j/ Yes Apache 2.0
OkHttp https://github.com/square/okhttp/ Yes Apache 2.0
Bouncy Castle https://www.bouncycastle.org/ No MIT
Simple Logging Facade for Java (slf4j) https://www.slf4j.org/ No MIT
Google Play Services Base (Optional) https://maven.google.com/web/index.html?#com.google.android.gms:play-services-base No Android Software Development Kit License

Code Optimisations and Obfuscation

The SDK’s bytecode cannot be modified in any way so that it works as intended, therefore, you should exclude the com.netcetera.threeds.sdk package from any optimisation or obfuscation process. You will also need to add configuration for any non-embedded dependencies you’ve added from the dependencies table.


SDK Configuration

This section describes the configuration options available on the Android 3DS SDK, and how to configure it.

Directory Server Configuration

When a transaction is initiated, the SDK will try to obtain information about the Directory Server that will participate in the message flow. This is so that the correct DS Public Key can be used for data encryption, and the correct DS logo is shown.

Scheme and Directory Server information is configured through ConfigParameters or ConfigurationBuilder in Initialisation. The following parameters are available for configuration:

  1. Schemes: Which schemes can be used.
  2. DS IDs: Directory Server IDs that belong to a certain scheme.
  3. Scheme’s Public Key: Public keys for each scheme that will be used to encrypt device data.
  4. Scheme’s Root Public Key: Public keys for each scheme that will be used for ACS Certificate Chain verification.
  5. Scheme Logo Resource ID: Drawable Resource ID for each scheme that will be used as logo.
  6. Scheme Dark Logo Resource ID: Drawable Resource ID for each scheme that will be used as dark-mode logo.

Some of these values can be omitted. Please check Pre-Configured Directory Servers for a list of pre-configured values that will be used in case no configuration is given.

Note: If public keys are provided, they can be either EC or RSA in PEM format. If certificates are provided, they need to be in the X.509 standard in either PEM or DER format.

Using ConfigParameters

To configure the various parameters, you can use the ConfigParameters.addParam(...) function. This function takes a group, paramName and paramValue as arguments. These arguments vary based on what you want to configure for. Below you can find the expectations for argument values for each configurable parameter:

Configuring Schemes’ Directory Servers

group: null
paramName: "schema_names"
paramValue: Comma-separated schemes list.

Example:

configParameters.addParam(null, "schema_names", "mastercard, visa");

Configuring Directory Server IDs

group: "schema_ds_ids"
paramName: Scheme name.
paramValue: Comma-separated list of Directory Server IDs.

Example:

configParameters.addParam("schema_ds_ids", "mastercard", "A000000004");
configParameters.addParam("schema_ds_ids", "visa", "A000000003");

The 3DS Requestor App uses the Cardholder Account Number (and optionally other cardholder information) to identify the DS ID. A DS ID is the Scheme’s Card RID (Registered application provider identifier). The identifier, usually 5 bytes in length, is issued by the ISO/IEC 7816-5 registration authority and is used to address an application in the card.

For example, an RID could be: A000000003. Please refer to the configuration for more RID values.

Configuring Scheme Public Key and Root Public Key

group: "schema_public_key" for Public Key; "schema_root_public_key" for Root Public Key
paramName: Scheme name.
paramValue: ASN.1 encoding of the public key / certificate in Base64.

Public Key Example:

configParameters.addParam("schema_public_key", "mastercard", loadPublicKey("certificates/mastercard_rsa.cer"));
configParameters.addParam("schema_public_key", "visa", loadPublicKey("certificates/visa_ec.cer"));

Root Public Key Example:

configParameters.addParam("schema_root_public_key", "mastercard", loadPublicKey("certificates/root_mastercard_rsa.cer"));
configParameters.addParam("schema_root_public_key", "visa", loadPublicKey("certificates/root_visa_ec.cer"));

On this example, loadPublicKey(...) is the function that loads ASN.1 encoding of the public key in Base64 encoded format from a certificate file.

Configuring Scheme Logos

A scheme can have two logos configured - a standard and a dark-mode logo. The standard logo is mandatory, so it must be present either in the pre-configured data, or configured by you. The dark-mode logo is optional. If the 3DS SDK needs to use a dark-mode logo that is missing, it will fallback to the standard logo displayed over a white background.

group: "schema_logo" for standard logo; "schema_logo_dark" for dark-mode logo
paramName: Scheme name
paramValue: String value of Drawable Resource ID

Examples:

// Schema with both logos
configParameters.addParam("schema_logo", "mastercard", Integer.toString(R.drawable.schema_logo_mastercard));
configParameters.addParam("schema_logo_dark", "mastercard", Integer.toString(R.drawable.schema_logo_mastercard_dark));

// Schema without dark logo
configParameters.addParam("schema_logo", "visa", Integer.toString(R.drawable.schema_logo_visa));

Using ConfigurationBuilder

The ConfigurationBuilder is an all-in-one API provided by the SDK to allow easier configuration. To configure a scheme, you can use the ConfigurationBuilder.configureScheme(...) function. This function takes a SchemeConfiguration object as an argument.

You can obtain the SchemeConfiguration object by calling SchemeConfiguration.newSchemeConfiguration(...) with the following arguments:

schemeName: Scheme name
schemeIds: List containing Directory Server IDs
schemeLogo: String value of Drawable Resource ID for standard scheme logo
schemeLogoDark: String value of Drawable Resource ID for dark-mode scheme logo
encryptionPublicKey: ASN.1 encoding of public key
rootPublicKey: ASN.1 encoding of public root key
certificatePath: Path to base64-encoded DER/PEM file in the "assets" directory

Example:

ConfigurationBuilder()
    .configureScheme(
        SchemeConfiguration.newSchemeConfiguration("diners")
        .ids(Collections.singletonList("A000000152"))
        .logo(Integer.toString(R.drawable.ds_logo_diners))
        .logoDark(Integer.toString(R.drawable.ds_logo_diners_dark))
        .encryptionPublicKeyFromAssetCertificate(assetManager, "example-diners-sign-certeq-rsa.crt")
        .rootPublicKeyFromAssetCertificate(assetManager, "example-diners-sign-certeq-rsa.crt")
        .build()
    )
    .build();

This class also includes the option to modify a pre-configured scheme. To do this, you must use the functions available in SchemeConfiguration for this purpose, like mastercardSchemeConfiguration(), or visaSchemeConfiguration(). The pattern they follow is SchemeConfiguration.{SchemeName}SchemeConfiguration() where {SchemeName} is the name of a pre-configured scheme.

Example:

ConfigurationBuilder()
    //Mastercard configuration
    .configureScheme(
        SchemeConfiguration.mastercardSchemeConfiguration()
            .encryptionPublicKeyFromAssetCertificate(assetManager, "example-mc-sign-certeq-rsa.crt")
            .build()
    )
    //Visa configuration
    .configureScheme(
        SchemeConfiguration.visaSchemeConfiguration()
            .encryptionPublicKeyFromAssetCertificate(assetManager, "example-visa-sign-certeq-rsa.crt")
            .rootPublicKeyFromAssetCertificate(assetManager, "example-visa-sign-certeq-rsa.crt")
            .build()
    )
    .build();

Pre-Configured Directory Servers

The Android 3DS SDK comes bundled with configuration for the following Directory Servers:

SDK Configured Scheme RIDs DS Public Key DS Root Public Key DS Logo DS Dark Logo
Mastercard A000000004 3ds2.directory.mastercard.com - Expiry: 19.11.2021 PRD MasterCard Identity Check Root CA - Expiry: 15.07.2030 R.drawable.ds_logo_mastercard R.drawable.ds_logo_mastercard_dark
Visa A000000003 3ds2.rsa.encryption.visa.com - Expiry: 22.06.2022 Visa eCommerce Root - Expiry: 24.07.2022 R.drawable.ds_logo_visa R.drawable.ds_logo_visa
Amex A000000025 sdk.safekey.encryptkey.com - Expiry: 03.12.2021 American Express Private Certification Authority - Expiry: 11.08.2029 R.drawable.ds_logo_amex R.drawable.ds_logo_amex_dark
Diners A000000152 Discover SDK Key ProtectBuy Root - Expiry: 03.02.2027 R.drawable.ds_logo_diners R.drawable.ds_logo_diners
JCB A000000065 ds2apr.jcb-tds.com - Expiry: 14.01.2028 JCB DS Root CA EMV 3-D Secure - Expiry: 09.01.2036 R.drawable.ds_logo_jcb R.drawable.ds_logo_jcb
MIR - - - R.drawable.ds_logo_mir R.drawable.ds_logo_mir
Union A000000333 银联国际有限公司 - Expiry: 02.08.2022 CFCA ACS CA - Expiry: 28.09.2035 R.drawable.ds_logo_union R.drawable.ds_logo_union

The binding between the configuration and the above values is done through the Directory Server RID, and custom configuration has precedence over these pre-configured values.

The pre-configured DS Public Key and DS Root Public Key serve for convenience. You have to verify their compatibility with the Directory Server. The integrators are encouraged to complete the configuration.

Directory Server RID Values

The Android 3DS SDK has a utility API, DsRidValues, that contains the Directory Server RIDs for the Pre-Configured Schemes.

Restricted Device Info Parameters Configuration

Device Info parameters can be set as restricted, which will in turn make the SDK not collect them.

This is achievable through two main ways: Through ConfigParameters, or ConfigurationBuilder. A list of device info parameters and their corresponding IDs can be found in the official 3DS SDK Device Info documentation.

InvalidInputException is thrown if a passed ID doesn’t correspond to any predefined device info parameter.

Using ConfigParameters

By using ConfigParameters.addParam(...), with the following arguments:

group: null
paramName: "restricted_device_info_parameters"
paramValue: Comma-separated list of device info parameter IDs.

Example:

configParameters.addParam(null, "restricted_device_info_parameters", "A001,A016,C005");

Using ConfigurationBuilder

By using ConfigurationBuilder.restrictedParameters(...), with the following arguments:

restrictedParameters: List containing device info parameter IDs.

Example:

ConfigurationBuilder().restrictedParameters(Arrays.asList("A001","A016","C005")).build();

UI Customisation

The Android 3DS SDK supports customization of UI elements that are being shown by itself. For configuration, the UiCustomization object is used.

For more detailed information, refer to Section 4.5 in the 3DS SDK Specification.

System-wide dark mode (available in Android 10) is supported by the SDK, with additional UI Customisation parameters. By default, dark mode is disabled. To enable, see UICustomization.

Example:

UiCustomization uiCustomization = new UiCustomization();
uiCustomization.supportDarkMode(true) // Challenge UI should change based on whether system wide dark mode is active.

ButtonCustomization buttonCustomization = new ButtonCustomization();
buttonCustomization.setBackgroundColor("#000000"); // Setting light mode background color.
buttonCustomization.setDarkBackgroundColor("#FFFFFF"); // Setting dark mode background color.

Logging Configuration

The Android 3DS SDK uses SLF4J for logging purposes. By default, it logs messages on WARN and ERROR levels. This can be configured by using any logging implementation on top of SLF4J.

Permissions

Permission Mandatory Description
android.permission.INTERNET Yes Required for communication with the ACS in Challenge Flow. Must be permitted before Starting of Challenge Flow.
android.permission.ACCESS_COARSE_LOCATION No Required for collecting the device coarse location that will be provided as device info parameter. Should be permitted before Initialisation.
android.permission.ACCESS_FINE_LOCATION No Required for collecting the device fine location that will be provided as device info parameter. Should be permitted before Initialisation.
android.permission.ACCESS_NETWORK_STATE No Required for collecting device’s IP Address that will be provided as device info parameter. Should be permitted before Initialisation.
android.permission.BLUETOOTH No Required for collecting bluetooth hardware info that will be provided as device info parameter. Should be permitted before Initialisation.
android.permission.READ_PHONE_STATE No Required for collecting Telephony information that will be provided as device info parameters. Should be permitted before Initialisation.
android.permission.SEND_SMS No Required for collecting Telephony information that will be provided as device info parameters. Should be permitted before Initialisation.
android.permission.ACCESS_WIFI_STATE No Required for collecting WiFi and Network related information that will be provided as device info parameters. Should be permitted before Initialisation.

SDK API

The SDK API complies with the API defined by the EMVCo 3DS SDK Specification. This section describes how the SDK can be used to perform 3DS Authentication of payment / non-payment transactions.

Instantiation

An instance of the SDK ThreeDS2Service can be acquired by calling ThreeDS2ServiceInstance.get().

This implementation holds a single instance of ThreeDS2Service and every call of .get() will return the same instance.

ThreeDS2Service threeDS2Service = ThreeDS2ServiceInstance.get();

UI Customisation

The EMV 3DS 2.0 protocol defines an API for Challenge Flow UI Customisation. This includes text colour, fonts, background colour, etc. A list of all available methods can be found in Section 4.5 of the 3DS SDK Specification.

The Android 3DS SDK adds support for system-wide dark-mode available from Android 10. The requestor application can enable this feature by calling supportDarkMode(true) in the UICusomization class.

When enabled, the SDK will follow the current Android System theme (as set in the system settings).

To accommodate for the additional styling needs of dark-mode, the SDK extends the EMVCo protocol with additional methods, listed below:

Class Method Description
UiCustomization supportDarkMode(boolean supported) Enables / Disables dark-mode support.
Customization setDarkTextColor(String hexColorCode) Sets the dark-mode text colour.
ButtonCustomization setDarkBackgroundColor(String hexColorCode) Sets the dark-mode background colour.
ToolbarCustomization setDarkBackgroundColor(String hexColorCode) Sets the dark-mode background colour.
LabelCustomization setHeadingDarkTextColor(String hexColorCode) Sets the dark-mode heading text colour.
TextBoxCustomization setDarkBorderColor(String hexColorCode) Sets the dark-mode border colour.

Initialisation

In order to use the SDK, it needs to be initialised with ThreeDS2Service.initialize(...).

try {
  Context context = ...;
  ConfigParameters configParameters = ...;
  String locale = ...;
  UiCustomization uiCustomization = ...;
  threeDS2Service.initialize(context, configParameters, locale, uiCustomization);
} catch (InvalidInputException | SDKRuntimeException e) {
  // ...
} catch (SDKAlreadyInitializedException e) {
  // no-op, already initialized
}
Function Argument Description
context Instance of Android application context.
configParameters Instance of ConfigParameters created during SDK Configuration.
locale String that represents the locale for the application’s user interface.
uiCustomization Instance of UICustomization created during SDK Configuration.

During initialization, security checks are performed and device information collected. These parameters will be part of Authentication and will be provided to the ACS via 3DS Server for risk analysis. For more details, refer to Security Features.

For information on what device data is collected, please refer to EMVCo 3DS SDK Device Info Specification and EMVCo 3DS SDK Device Info Specification Version 1.1.

Warnings

After security checks are performed, the SDK provides the outcome as list of Warning objects. To obtain the result of these checks, call ThreeDS2Service.getWarnings().

try {
  List<Warning> warnings = threeDS2Service.getWarnings();
  // Handle warnings
} catch (SDKNotInitializedException e) {
  // ...
}

Each Warning object has a Severity property with value LOW, MEDIUM or HIGH. It’s up to the integrator to decide what to do with this information. The resulting warnings are also provided as part of Device Info in the Authentication process. For more details, please refer to Security Warnings.

Processing Screen

To indicate that a transaction is ongoing, a processing screen (supplied by the SDK) shall be shown by the requestor application. To get an instance of this processing screen, use Transaction.getProgressView(...). This method must be called from the main thread, otherwise SDKRuntimeException will be thrown.

Processing Screen Use Cases / Requirements for Requestor Application

  • (Required) While the 3DS Authentication Request is ongoing, the processing screen shall be shown for a minimum of 2 seconds by the requestor application, regardless of authentication response time or result.
  • (Recommended) SDK Requirement: If a Challenge flow is required after the Authentication Request, do not call ProgressView.hideProgress() before calling Transaction.doChallenge(...), as this will lead to a screen flicker since the SDK uses the same processing screen for starting the challenge flow. The processing screen is shown by the SDK until the first challenge screen appears. Furthermore, assuming no exception was thrown by Transaction.doChallenge(...), the SDK will hide the processing screen once the challenge is finished (when any ChallengeStatusReceiver methods are called).

Note: Calling any method on the ProgressView object will have no effect once a successful Transaction.doChallenge(...) method call has occurred. In this case, the SDK takes control and handles the state of the processing screen.

Authentication

The 3DS Authentication flow starts with the Authentication Request that is sent to the 3DS Server, where an AReq is created, forwarded to the relevant DS and further forwarded to the relevant ACS. The ACS then evaluates the data in the AReq and responds with an ARes back to the DS, which comes back to the 3DS Requestor Environment via the 3DS Server.

The SDK generates authentication parameters that should be used to build the Authentication Request. All these parameters should be sent to the 3DS Server. These are made available in the Transaction object.

To obtain an instance of Transaction, ThreeDS2Service.createTransaction(...) function can be called:

try {
  String directoryServerID = ...
  String messageVersion = "2.1.0";
  Transaction transaction = threeDS2Service.createTransaction(directoryServerID, messageVersion)
} catch(SDKNotInitializedException | InvalidInputException | SDKRuntimeException e) {
  // ...
}
Function Argument Description
directoryServerID The Directory Server ID that will be used. Make sure configuration for this DS already exists in DS Configuration.
messageVersion 3DS Protocol Version that shall be used. If this value is null, the highest version supported will be used.

After the Transaction object has been created, AuthenticationRequestParameters can be obtained by calling Transaction.getAuthenticationRequestParameters().

try {
  AuthenticationRequestParameters authenticationRequestParameters = transaction.getAuthenticationRequestParameters();
  // Send request with AuthenticationRequestParameters to the 3DS Server
} catch (SDKRuntimeException e) {
  // ...
}

All available AuthenticationRequestParameters are defined in Chapter 4.12 in the EMVCo 3DS SDK Specification.

Challenge Flow

If the ACS assesses a transaction as high-risk, it forces the Challenge flow onto it. In case of Challenge, the 3DS Requestor calls Transaction.doChallenge(...) and the SDK takes over the Challenge process. This method must be called on the main thread and before Activity.onSaveInstanceState(...), otherwise SDKRuntimeException is thrown:

try {
  Activity activity = ... // getActivity();
  ChallengeParameters challengeParameters = ... // createChallengeParameters(authenticationResponse);
  ChallengeStatusReceiver challengeStatusReceiver = this;
  int timeOut = 5;
  transaction.doChallenge(activity, challengeParameters, challengeStatusReceiver, timeOut);
} catch (InvalidInputException e) {
  // ...
}
Function Argument Description
activity The Activity that is in the application foreground.
challengeParameters Instance of ChallengeParameters, created with values from the Authentication Response.
challengeStatusReceiver Callback object that implements ChallengeStatusReceiver. This is where the application will be notified about the Challenge Result.
timeOut Timeout interval (in minutes) within which the challenge process must be completed. The minimum value is defined to be 5 minutes.

Once a Challenge has been started, any calls to Transaction.doChallenge(...) or Transaction.close() will result in an SDKRuntimeException, however the Challenge flow will not be interrupted. When the Challenge result comes through the ChallengeStatusReceiver, Transaction.doChallenge(...) and Transaction.close() can be called again.

For security purposes, the Activity that hosts the Challenge UI will have screenshots disabled (setting FLAG_SECURE to the Window).

Requestor App URL

Starting with version 2.2.0 of 3DS, the application integrating the 3DS SDK can be called from another authentication application during an Out-of-Bounds challenge flow to indicate completed OOB authentication. To use this feature, the requestor application should define its app URL and provide it to the SDK.

This is done by calling the ChallengeParameters.setThreeDSRequestorAppURL(String threeDSRequestorAppURL) method. The inclusion of this value in ChallengeParameters is optional. This value will be ignored if provided for an irrelevant version of 3DS (like 2.1.0).

In order for the SDK to catch the call from the authentication application and act accordingly, the requestor application needs to update the current Intent of the Activity that is used to start the Challenge. This can be achieved by overriding the Activity.onNewIntent(...) function and setting the current intent to the newly received one:

@Override
protected void onNewIntent(Intent intent) {
  super.onNewIntent(intent);
  setIntent(intent);
}

Challenge Flow Results

After invoking Transaction.doChallenge(...), the Challenge Flow starts and the SDK takes control of the UI. This means that the Activity provided via the doChallenge function should not be finished or replaced by other Activity. The requestor receives control back when any of the callback methods from ChallengeStatusReceiver are invoked:

class MyChallengeManager implements ChallengeStatusReceiver {

  public void completed(CompletionEvent completionEvent) {
    // Handle successfully or unsuccessful completion of challenge flow
  }

  public void cancelled() {
    // Handle challenge cancelled by the user
  }

  public void timedout() {
    // Handle challenge timeout
  }

  public void protocolError(ProtocolErrorEvent protocolErrorEvent) {
    // Handle protocol error that has been send by the ACS
  }

  public void runtimeError(RuntimeErrorEvent runtimeErrorEvent) {
    // Handle error that has occurred in the SDK at runtime
  }
}

When any of these are invoked, the Challenge is considered as finished. As a result, the SDK dismisses the Challenge screen, closes the transaction, cleans up resources and returns control back to your application.

Cleanup

After the 3DS Authentication is finished, the 3DS Requestor should close the Transaction by calling Transaction.close() in order to clear references and avoid memory leaks. After this method is called, any further operations on the Transaction object will result in SDKRuntimeException.

Similarly, in order to free up resources used by ThreeDS2Service, the ThreeDS2Service.cleanup() function can be used. Once an instance of ThreeDS2Service has freed up its resources, it’s in the same state as a newly created ThreeDS2Service and can be used again, however you’ll need to go through initialisation.


SDK Error Handling

This section covers SDK Errors and their meaning.

Exceptions

According to the specification, the SDK throws four types of exceptions when some error has occurred:

Exception Description
InvalidInputException Occurs due to invalid data provided to the SDK.
SDKAlreadyInitializedException Occurs when initialize is called on an already initialised ThreeDS2Service object.
SDKNotInitializedException Occurs due to attempted usage of an uninitialised ThreeDS2Service object.
SDKRuntimeException Internal SDK Error. Will contain information describing the error cause more in depth.

While in the Challenge Flow, instead of throwing exceptions, the SDK reports errors via ChallengeStatusReceiver.runtimeError(RuntimeErrorEvent). This RuntimeErrorEvent has both the error message and error code.

Error Codes

The SDKRuntimeException and RuntimeErrorEvent contain error codes that could be useful for debugging your application, or helpful to our Support Team:

Code Description
Transaction Errors
1010 Called method on closed Transaction object. Check error message for what method was called.
1011 Called Transaction object method that has ongoing Challenge Flow. Check message for what method was called.
Configuration Errors
1030 Failed loading Public Key from DS Configuration. Check error message for the invalid value.
1031 Invalid Drawable Resource ID provided in DS Configuration. Check error message for the invalid value.
1032 No DS Configuration nor default values found for the required DS. Check error message for which DS you’re missing configuration for.
License Validation Errors
1050 3DS SDK License is missing.
1051, 1053, 1054 License is in an invalid format.
1052 License has expired. Check error message for the validity period.
Device Data Errors
1060 The provided DS Encryption Key cannot be used because it is neither RSA nor EC type.
Challenge Errors
2000 ACS Signed Content verification failed.
2001 ACS Signed Content signed with unsupported algorithm.
2002 ACS Signed content has invalid signature.

Security Features

This section goes into detail about the security aspects concerning the SDK and its integration.

The SDK implements a number of security functions that are defined in the EMVCo 3DS SDK Specification and in PCI 3DS SDK Security Standard.

Security Warnings

During Initialisation, the SDK performs a number of required security checks. These checks may result in warnings that are handed over to your Application. It’s up to you to act upon these warnings - The SDK will continue to operate as normal should you decide to, for example, ignore them.

Below is a list of the possible warnings:

Code Severity Description Note
SW01 HIGH Jailbroken device. -
SW02 HIGH The SDK has been tampered with. -
SW03 HIGH An emulator is being used to run the Application. -
SM04 MEDIUM Debugger is attached. -
SW05 HIGH Unsupported OS Version. -
PCI1.2 MEDIUM The Application was not installed from a Trusted Store Currently trusted stores are the Google Play Store, Amazon Appstore, Galaxy Apps Store and HUAWEI AppGallery. This is the only warning that is not included in the Device Data sent to the ACS.

Secure Communication

The SDK uses several cryptographic methods to secure the communication and transfer of data.

Device Data collected during initialisation is sent to the 3DS Server, which forwards it to the DS and ACS. In order to secure the transmission, the SDK encrypts that data with the DS Public Key in JWE format. The encrypted data can be retrieved by calling AuthenticationRequestParameters.getDeviceData().

After the DS receives this encrypted data, it decrypts it and sends it to the ACS. Using data transferred in the Authentication, the 3DS SDK and ACS exchange keys using the Diffie-Hellman protocol - this establishes the secure channel that is used during the Challenge Flow.

The Ephemeral Key, used for the key exchange, is generated by the SDK. It can be retrieved in JWK format by invoking AuthenticationRequestParameters.getSDKEphemeralPublicKey(). This key should be sent in the Authentication Request to the 3DS Server together with the other parameters.

Ensuring Security Provider is up-to-date

To protect against known vulnerabilities such as SSL exploits found in the default Android Security Provider, the SDK will try to update it during initialisation. In order to perform this update, it requires the Google Play Services API. The least intrusive way to provide this is to include the Google Play Service Base library as a dependency.

Note: If the device doesn’t have / doesn’t support the Google Play Services API, the SDK will continue to work as intended, it just won’t be able to update the Security Provider. In this case, your Application might be vulnerable.

Application Resources Integrity

All sensitive resources included with the SDK are protected to make sure their integrity isn’t compromised. It is up to the integrator, however, to make sure that additional resources have appropriate integrity protection. For example, such resources may be certificates or keys that are used for Scheme / Directory Server configuration.

PCI 3-D Secure SDK Compliance

This section describes the PCI requirements that are met by the SDK:

Requirement Description
1.1 Security Checks Conduct several security checks of the Requestor environment and display warnings, including: Jailbreak detection, Emulator detection, 3DS SDK Integrity, Debugger detection
1.2 Installed from Approved Source Ensure the Requestor App is installed from a trusted source (Platform Store)
1.3 Run-Time Integrity Checks to detect when SDK functionality has been modified
1.4 Protection against Reverse Engineering Protection against reverse engineering
1.5 Protection of 3DS SDK Reference Data Data is securely stored within the 3DS SDK
2.1 Collection of Sensitive 3DS SDK Data Elements Only data that is essential for functionality is collected and retained for the necessary duration
2.2 Clearing of Sensitive 3DS SDK Data Elements All sensitive data is removed after it’s not needed anymore, unless permitted
2.3 Use of Third-Party Services Third-Party services are documented and only used when justified
2.4 Protection against Disclosure through Unintended Channels Sensitive data is not disclosed outside of the SDK
2.5 Hardcoded 3DS SDK Data Element Sensitive data is not hardcoded in the SDK
2.6 Run-Time Data Protection Run-time data protection against unauthorized third-party access
2.7 UI Protection The UI is secured, and data from it cannot be accessed outside the SDK
2.8 HTML Rendering All requests are intercepted and are handled inside the SDK
2.9 Prevention of External Code of Script Execution Prevent JS Code execution outside the SDK
3.1 Approved Algorithms and Modes of Operation Only approved cryptographic algorithms and methods are used
3.2 Random Number Generator(s) Approved RNG algorithms or libraries are used
3.3 Random Number Entropy Random numbers meet minimum effective security strength
4.1 Threat and Vulnerability Analysis Threats, attack scenarios and / or attack vectors applicable are known and are documented
4.2 Development of Defensive Strategies Various mechanisms are implemented to protect against attack vectors and / or scenarios are designed and implemented
4.3 Software Security Testing Code is tested during its lifecycle
4.4 Vulnerability Identification and Monitoring The SDK is monitored for vulnerabilities / infrastructure exists to report vulnerabilities
4.5 Updates during Transaction Processing The SDK will not update while processing
5.1 Availability of Stakeholder Guidance Guidance is made available and maintained to all stakeholders
5.2 Disclosure of Updates to Stakeholders Stakeholders are updated and informed about changes made to the SDK
5.3 Frequency of Updates to Stakeholder Guidance Updates are made to the SDK as changes as warrant updates

Feedback

© Ravelin Technology Ltd. All rights reserved