/

String Encryption

Protection ID: stringEncryption

String Encryption replaces plaintext string literals in your bytecode with encrypted versions that are decrypted at runtime. This prevents attackers from extracting API keys, URLs, credentials, and other sensitive data by simply decompiling the APK.


Configuration

Groovy
shield {
    protections {
        stringEncryption = true
    }
}

How It Works

String encryption transforms literal string values in your code (API keys, URLs, database connection strings, error messages, and other constants) into encrypted values that are only resolved at runtime. This prevents attackers from easily identifying important values during static analysis of the decompiled APK.

The protection replaces direct string references with calls to optimized decoding methods, effectively hiding the actual values in the decompiled code. Each string uses a unique combination of parameters, making it impractical to write a generic decoder.

Before Shield

Java
public class ApiClient {
    private static final String API_KEY = "sk_live_abc123def456";
    private static final String BASE_URL = "https://api.example.com/v2";
    private static final String AUTH_HEADER = "Authorization";
}

After Shield

Java
public class ApiClient {
    private static final String API_KEY = htys("\u0012\u0045\u0078...", "xK", 42, true);
    private static final String BASE_URL = htys("\u0033\u0067\u0021...", "mQ", 17, false);
    private static final String AUTH_HEADER = htys("\u0055\u0012\u0039...", "rT", 8, true);
}

Each encrypted string uses a different combination of key parameters, making pattern-based decryption impractical.


Excluding Strings

If specific strings should not be encrypted (for example, strings used in reflection or JNI), use the @Exclude annotation:

Java
import com.bytehide.shield.annotations.Exclude;

@Exclude(protections = {"StringEncryption"})
public class ReflectionHelper {
    // Strings in this class will not be encrypted
    public static final String CLASS_NAME = "com.example.MyService";
}

Or use @Keep to exclude from all protections:

Java
@Keep
public native void nativeMethod();

Performance Impact

String decryption adds a small overhead per string access. In practice, this is negligible because decryption is performed at runtime in an optimized way, most strings are accessed infrequently (initialization, error messages), and the runtime cost is microseconds per decryption.

For performance-critical hot paths with repeated string access, consider using @Exclude(protections = {"StringEncryption"}) on the relevant methods.


When to Use

String encryption is recommended for all production builds. It is particularly important for applications that contain API keys or service credentials, authentication tokens or secrets, backend URLs and endpoint paths, database connection strings, license validation logic, or any hardcoded sensitive values.


Previous
Reference Proxy