Android
Guidelines for tamper detection at host application
As a part of application security measures, the following code can be included to protect against tampering of the application.
This code has to be inlined in a method which does critical operation such as triggering method calls in OIP Risk Management SDK.
The strings provided in this code snippet has to be encrypted using Dexguard and the getPackageInfo() API has to be enabled with the accessthroughreflection setting in the Dexguard configuration.
Hash signature of the certificate can be obtained by executing the following commands in command prompt:
cd <path to Java installation\bin>
keytool.exe -list -v –keystore <path to .keystore file> -alias androiddebugkey -storepass <storePassword> -keypass <keyPassword>
Replace the SIGNATURE = “” in the following snippet code with the signature obtained above.
boolean matches = false;
try {
// Get the APK signature
PackageManager packageManager = mContext.getPackageManager();
PackageInfo packageInfo = packageManager.getPackageInfo(mContext.getPackageName(), PackageManager.GET_SIGNATURES);
Signature signature = packageInfo.signatures[0];
// Calculate hash of the signature
MessageDigest md = MessageDigest.getInstance("SHA");
md.update(signature.toByteArray());
byte[] sigHash = md.digest();
// Declare the expected signature hash as a String
// Modify this value based on the hash generated from certificate you use so that DexGuard can obfuscate it
String SIGNATURE = "";
// Convert the expected signature hash String into a Byte Array
int len = SIGNATURE.length();
byte[] bytes = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
bytes[i / 2] = (byte) ((Character.digit(SIGNATURE.charAt(i), 16) << 4) + Character.digit(SIGNATURE.charAt(i + 1), 16));
}
// Compare the signature hashes, add necessary steps here if the signature does not match
matches = Arrays.equals(sigHash, bytes);
} catch (PackageManager.NameNotFoundException | NoSuchAlgorithmException e) {
Log.d(TAG, "Exception in signature comparison");
}
Guidelines for obfuscation at host application
It is highly recommended that your application be obfuscated with ProGuard/DexGuard prior to delivery. OIP Risk Management SDK has applied basic obfuscation and advanced class/string encryption internally using DexGuard. To obfuscate your application on top of OIP Risk Management SDK, the following configuration file are to be included in your application obfuscation process:
- for using ProGuard or R8: include "proguard/proguard-project.txt"
- for using DexGuard: include "dexguard/dexguard-project.txt"
Both configuration files are available in the SDK delivery package. They are used on top of the obfuscation configurations specific to your application.
The configurations are validated with the following combination:
- DexGuard v9.1.1
It is recommended to add in your obfuscation configuration the following for troubleshooting purposes. Please archive the mapping files for each of your application delivery.
Issue on Dexguard v9.1.1
GuardSquare confirm issue on Dexguard on obfuscating resources which contains Java class references. This will impact BehavioSec integration. As workaround, you may need to keep related class and resource.
# Provide a custom path for mapping files
-printmapping obfuscation.map
-printseeds classes-processed.seeds
-printconfiguration obfuscation.config
In build.gradle (module level), the order of dexguard file configuration should be as follows:
android {
...
buildTypes {
release {
proguardFiles getDefaultDexGuardFile('dexguard-release.pro')
proguardFiles 'path to Thales SDK obfuscation configuration'
proguardFiles 'path to your app obfuscation configuration'
...
}
debug {
proguardFiles getDefaultDexGuardFile('dexguard-release.pro')
proguardFiles 'path to Thales SDK obfuscation configuration'
proguardFiles 'path to your app obfuscation configuration'
...
}
}
}
Warning
When encrypting native library projects, the code sets a temporary directory for maximum portability. One of the libraries integrated in OIP Risk Management SDK uses the native encryption feature from DexGuard.
DexGuard uses the environment variable
java.io.tmpdirto create a temporary file when decrypting the native library during runtime. In the older versions of Android, this variable may point to a location that the application does not have the permission to modify, for example,/sdcard. To ensure that there is a valid temporary directory at all times regardless of the Android version used, this variable has to be defined and points to a location that exists and is writable. To ensure that the device running the app has enough storage space, add this code snippet at the launch of the host application, as recommended by DexGuard:System.setProperty("java.io.tmpdir",getDir("files", Context.MODE_PRIVATE).getPath());.
Note
Since SDK version 2.7.0, if the application is applying Dexguard (from version 9.0.22), there are following warning messages, which can be ignored: * From D8/R8:
AGPBI: {"kind":"warning","text":"Expected stack map table for method with non-linear control flow.","sources":[{"file":"GAHRiskEngine.jar"}],"tool":"D8"}* From Dexguard:WARN: ignored invalid inner class name com/threatmetrix/TrustDefender/dddgdg$1, treating as anonymous inner class.