- 18 Oct 2024
- 9 Minutes à lire
- SombreLumière
Shielding the Application via the OneSpan Mobile Portal
- Mis à jour le 18 Oct 2024
- 9 Minutes à lire
- SombreLumière
Android
When a configuration is created using the OneSpan Mobile Portal, it is possible to shield an application. You can bind your application to App Shielding via the OneSpan Mobile Portal either manually or automated.
App Shielding writes the shielded application to shielded-app.apk in the same directory as the application itself.
Manual shielding
Shielding modifies the executable of the application, which means that after shielding, the application needs to be re-signed.
This must be handled with special care so that all required parts of the application are re-signed.
To manually shield an app
The shielding section of the OneSpan Mobile Portal Home page is only enabled after a configuration has been created, the configuration options have been set, and the required certificates correctly uploaded.
In the Home page of the OneSpan Mobile Portal, select the project and configuration you want to use.
To upload the binary to be shielded, either click Select at the center of the page and browse to the file location, or add the file via drag and drop.
As soon as the file upload is complete, the shielding process starts.
The binary to shield (AAB or APK for Android) can be signed or unsigned.
App Shielding provides log where you can trace the shielding progress.
When the shielding process is completed, the OneSpan Mobile Portal displays a notification, and you can download the zip file with the shielded binary. The file time counter next to the file sets the expiry time after which the file can not be downloaded anymore.
After shielding, application startup performance could be impacted. If this occurs, exclusion options can be defined to reduce the impact of the shielding on the application.
The security provided by App Shielding is reduced when you exclude classes from the shielding process. The number of shieldings must be high enough to ensure security requirements (more than one thousand data shieldings).
To avoid performance issues, the following OneSpan packages can be excluded from shielding:
untouchable class com.vasco.digipass.sdk.obfuscated.*
untouchable class com.vasco.digipass.sdk.utils.utilities.obfuscated.*
App obfuscation
App Shielding provides app obfuscation mechanisms where the Java bytecode of an application is obfuscated, and e.g. class names, function names, and field names are modified. Parts of an application code are rewritten in a purposefully unintelligible way, while the application functionalities are left unchanged. The purpose of obfuscation is to discourage static analysis attempts.
If an attacker attempts a static analysis of the code by decompiling the app, the previously sequential instructions with telling variable names and significant values, should, after obfuscation, look like a seemingly random set of instructions. This can in turn prevent or at least slow down any attack whose success requires some knowledge of the underlying code – some forms of repackaging, code hooking, code injections etc. App Shielding offers the possibility to obfuscate the Java bytecode part of an Android APK or AAB application format.
You can obfuscate the application either with App Shielding alone, or use it in combination with the Android built-in minification and resource shrinking options. These options can be enabled in the app's gradle file. For more information about Android options for shrinking and obfuscation, refer to the Android Studio documentation.
Enabling the App Shielding obfuscation feature in combination with Android obfuscation options results in a greater obfuscation depth of your code.
Obfuscation of App Shielding
The design of the native App Shielding libraries makes it difficult to analyze, as it uses several layers of obfuscation, employing multiple techniques. This is done primarily to make it harder to partially or completely remove or disable App Shielding.
Features such as shielding, where parts of the application data are removed from the code, depend on App Shielding being hard to disassemble and analyze to obtain encryption keys or other information. The shielding mechanism tries to force the attacker to break App Shielding (or the cryptography).
Enable obfuscation with default rules
The Shielding Tool comes with a number of default rule files. These are loaded automatically, according to the enabled options. For instance, to enable obfuscation, you can pass a rules file to the Shielding Tool with the command line option --rules <file> with the following contents:
include "builtin:obfuscate-on.cfg"
This loads the built-in rules file builtin:obfuscate-on.cfg, which enables class name obfuscation for all classes, and then loads another built-in rules file, builtin:default-unobfuscate.cfg, which includes rules to not obfuscate some well-known exceptions.
To load the built-in rules file via the configuration settings of the OneSpan Customer Portal or OneSpan Mobile Portal, you have the following two options:
Enable Rules.cfg, and copy the include "builtin:obfuscate-on.cfg" command into the input field.
Enable Default Obfuscate.
Enable obfuscation with customized rules
You can customize the settings for obfuscation by defining rules in the Rules.cfg file. This determines how App Shielding will modify the Android application, especially in the context of shielding and obfuscation (see Configuration of Shielding Tool rules).
obfuscate class com.example.app.*; # Obfuscate all classes within com.example.app package.
Customize obfuscation rules is not a mere ON / OFF feature. The rules must be configured manually (see the table with the class_operation options in Configuration of Shielding Tool rules). The effort to fine-tune the configuration is comparable to the one required to fine-tune similar commercially available obfuscation tools.
Obfuscation techniques
App Shielding offers three types of obfuscation techniques:
Default obfuscation techniques
App Shielding employs these obfuscation techniques with any Java bytecode that is not implicitly or explicitly excluded from obfuscation. By default, App Shielding provides the implicit obfuscation rule. The explicit obfuscation rule is the sum of all rule lines that have been explicitly set in the configuration file, using the preserve and obfuscate keywords.
You can either apply none of these by implicitly or explicitly excluding the relevant piece of code, or apply all of them by targeting the relevant piece of code (or by not excluding it, either implicitly or explicitly).
The default obfuscation techniques are:
Class, method, and field name randomization
Classes, methods, and field names are replaced with random, meaningless, and often shorter values. All references and resources are also updated accordingly.
Namespace flattening
All classes will be moved into one big flat namespace which removes information about logical class grouping.
Code shuffling
Code that belongs in one class can be moved to another class, and all references to this code can be updated accordingly to the relocated piece of code. This creates new application-internal code dependencies which are confusing to an attacker but also act as an internal binding mechanism that makes it harder to remove certain parts of the code tree.
Obfuscation on demand: debug information removal
If you use this technique, obfuscation is only applied if a specific keyword is added as an rule line in the App Shielding configuration.
Debug information such as parameter type information, source file and line number information can be removed.
removeDebug / keepDebug
removeSourceFile / keepSourceFile
removeLines / keepLines
Java annotations can be removed with the removeAnnotation / keepAnnotation keywords.
This may break some uses of Java Generics.
Obfuscation as a side-effect
To enable your app to protect itself, App Shielding decompiles, modifies, and recompiles the app. Some of the modifications performed on the app also obfuscate the app code: the mandatory obfuscation and the binding and string scrambling mechanisms.
Mandatory obfuscation
Java bytecode related to App Shielding will be obfuscated, whether obfuscation is enabled or disabled on the configuration level. This is why every shielded app is retrieved with a mapping.txt file. This file contains the mapping of original names to obfuscated names. Also, it is useful for de-obfuscating the traces from the app and should therefore be preserved.
Binding and string scrambling
The main purpose of the binding and string scrambling mechanisms is to prevent an attacker from removing the App Shielding libraries and configurations from the shielded app. A side-effect of these mechanisms happens to be code obfuscation: where previously there was a plain text right-hand string value, there is now a piece of code. See Comparison of code after applying obfuscation as a side-effect for a comparison of the string value and the pieces of code after binding and string scrambling.
Comparison of code after applying obfuscation as a side-effect | ||
Original code | After Binding | After String Scrambling |
---|---|---|
const-string v0, "ABC" const-string v1, "DEF" const-string v2, "GHI" | const-class v0, Lcom/onespan/shieldenum/ObfTest; const v1, 0x15a invoke-static {v0, v1}, Ljt/d;->a(Ljava/lang/Class;I)V const v0, 0x7fb invoke-static {v0}, Ljt/d;->a(I)Ljava/lang/String; move-result-object v0 const v1, 0x7fc invoke-static {v1}, Ljt/d;->a(I)Ljava/lang/String; move-result-object v1 const v2, 0x7fd invoke-static {v2}, Ljt/d;->a(I)Ljava/lang/String; move-result-object v2 | const/16 v4, 0x3 new-array v3, v4, [C const/16 v5, 0x38ff xor-int/lit16 v5, v5, 0x38bd int-to-char v5, v5 const v4, 0x1 aput-char v5, v3, v4 const v4, 0x1 aget-char v5, v3, v4 xor-int/lit16 v5, v5, 0x1 int-to-char v5, v5 const v4, 0x2 aput-char v5, v3, v4 const v4, 0x1 aget-char v5, v3, v4 xor-int/lit16 v5, v5, 0x3 int-to-char v5, v5 const v4, 0x0 aput-char v5, v3, v4 new-instance v5, Ljava/lang/String; invoke-direct {v5, v3}, Ljava/lang/String;-><init>([C)V invoke-virtual {v5}, Ljava/lang/String; ->intern()Ljava/lang/String; move-result-object v0 const/16 v4, 0x3 new-array v3, v4, [C const/16 v5,0x3867 xor-int/lit16 v5, v5, 0x3822 int-to-char v5, v5 const v4, 0x1 aput-char v5, v3, v4 const v4, 0x1 aget-char v5, v3, v4 xor-int/lit16 v5, v5, 0x1 int-to-char v5, v5 const v4, 0x0 aput-char v5, v3, v4 const v4, 0x0 aget-char v5, v3, v4 xor-int/lit16 v5, v5, 0x2 int-to-char v5, v5 const v4, 0x2 aput-char v5, v3, v4 new-instance v5, Ljava/lang/String; invoke-direct {v5, v3}, Ljava/lang/String;-><init>([C)V invoke-virtual {v5}, Ljava/lang/String;->intern()Ljava/lang/String; move-result-object v1 const/16 v4, 0x3 new-array v3, v4, [C const/16 v5, 0x7f17 xor-int/lit16 v5, v5, 0x7f5f int-to-char v5, v5 const v4, 0x1 aput-char v5, v3, v4 const v4, 0x1 aget-char v5, v3, v4 xor-int/lit16 v5, v5, 0x1 int-to-char v5, v5 const v4, 0x2 aput-char v5, v3, v4 const v4, 0x1 aget-char v5, v3, v4 xor-int/lit16 v5, v5, 0xf int-to-char v5, v5 const v4, 0x0 aput-char v5, v3, v4 new-instance v5, Ljava/lang/String; invoke-direct {v5, v3}, Ljava/lang/String;-><init>([C)V invoke-virtual {v5}, Ljava/lang/String;->intern()Ljava/lang/String; move-result-object v2 |
The size of the obfuscated code does not necessarily mean it is safer or slower to execute. The String Scrambling mechanism leaves a longer code but is actually less safe and more performant than the Binding mechanism. Notice also the difference between the Binding and String Scrambling mechanisms and the default obfuscation techniques described above. The Binding mechanism affects the right-hand side of a string value while the String Scrambling essentially affects labels (classes, methods, fields etc.). Both are useful and contribute to strengthen the app against static analysis.
For more information about configuring rules, see Configuration of Shielding Tool rules.
iOS
When a configuration is created using the OneSpan Mobile Portal, it is possible to shield an application. You can bind your application to App Shielding via the OneSpan Mobile Portal either manually or automated.
Manual shielding
Shielding modifies the executable of the application, which means that after shielding, the application needs to be re-signed.
This must be handled with special care so that all required parts of the application are re-signed.
To manually shield an app
The shielding section of the OneSpan Mobile Portal Home page is only enabled after a configuration has been created, the configuration options have been set, and the required certificates correctly uploaded.
In the Home page of the OneSpan Mobile Portal, select the project and configuration you want to use.
To upload the binary to be shielded, either click Select at the center of the page and browse to the file location, or add the file via drag and drop.
As soon as the file upload is complete, the shielding process starts.
The binary to shield (i.e. IPA for iOS) can be signed or unsigned.
App Shielding provides log where you can trace the shielding progress.
When the shielding process is completed, the OneSpan Mobile Portal displays a notification, and you can download the zip file with the shielded binary. The file time counter next to the file sets the expiry time after which the file can not be downloaded anymore.
Shielding modifies the executable of the application, which means that after shielding, the application needs to be re-signed.
This must be handled with special care so that all required parts of the application are re-signed. Ensure that the correct provisioning profile is copied, and the correct entitlements are used.