Menu
Menu
inquire

Documentation

Configuring Stringer protection

Configuration file format

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <stringer-v3>
        <verbose/>
        <licenseFile/>
        <optimize/>
        <signMode/>
        <keystore/>
        <storepass/>
        <alias/>
        <keypass/>
        <proguardMapFile/>
        <trialExpirationTimestamp/>
        <trialExpirationTimestampPattern/>
        <protectionElements>
            <protectionElement>
                <paths>
                    <path/>
                    ...
                </paths>  
                <stringEncryption>
                    <mode/>
                    <checkCaller/> 
                    <filters>
                        <filter>...</filter>
                    </filters>
                </stringEncryption> 
                <hideAccess>
                    <mode/>
                    <filters>
                        <filter>...</filter>
                    </filters>
                </hideAccess>
                <resourceEncryption>
                    <mode/>
                    <filters>
                        <filter>...</filter>
                    </filters>
                </resourceEncryption>  
                <integrityControl>
                    <checkBytecode/>
                    <checkJar/>
                    <sealJar/>
                    <osgiCompatibility/>
                    <mode/>
                    <filters>
                        <filter>...</filter>
                    </filters>                  
                </integrityControl>
            </protectionElement>
        …
        </protectionElements>
    </stringer-v3>

Element: verbose
Description: Sets verbosity level to maximum
Format: boolean
Default value: false
Example: <verbose>true</verbose>

Element: licenseFile
Description: Path to the license file
Format: string
Default value: ${user.home}/stringer.licel
Example: <licenseFile>/Users/developer/stringer.licel</licenseFile>

Element: optimize
Description: Enables the class optimisation mode
Format: boolean
Default value: false
Example: <optimize>true</optimize>

Element: signMode
Description: Sets mode of signing of the output JAR file
Format: string
Valid values: default - signature is performed with an autogenerated key, release - signature is performed with the developer's key, none – signature is not performed)
Default value: none
Example: <signMode>release</signMode>

Element: keystore (only for signMode == release
Description: Path to the keystore
Format: string
Default value: no default value
Example: <keystore>/Users/developer/.keystore</keystore>

Element: storepass (only for signMode == release)
Description: Password for the keystore>
Format: string
Default value: no default value
Example: <storepass>password</storepass>

Element: alias (only for signMode == release)
Description: Key alias in the keystore
Format: string
Default value: no default value
Example: <alias>java</alias>

Element: keypass (only for signMode == release)
Description: Password for the key
Format: string
Default value: no default value
Example: <keypass>password</keypass>

Element: proguardMapFile
Description: Path to ProGuard's map file (class name mappings after name obfuscation)
Format: string
Default value: no default value
Example: <proguardMapFile>/Users/developer/project/proguard_map.txt</proguardMapFile>

Element: trialExpirationTimestamp
Description: Time points to the end of working period of a protected application. By
default, the value is to be set in seconds (unix time/Epoch)
Format: string
Default value: no default value
Example: <trialExpirationTimestamp>20180101</trialExpirationTimestamp>
Note: JEXL expressions might be used to set trialExpirationTimestamp

Element: trialExpirationTimestampPattern
Description: Pattern that is used to parse a value of trialExpirationTimestamp.
Format: string
Default value: no default value
Example: <trialExpirationTimestampPattern>yyyyMMdd</trialExpirationTimestampPattern>

Element: protectionElements (Standard/Enterprise)
Description: Elements that are to be protected
Format: contains nested elements
Nested elements: (list of <protectionElement>)

Element: protectionElement (one or more for the Enterprise/one for the Standard version)
Format: contains nested elements
Nested elements (<paths/> - Only for Enterprise, Not Allowed in the Standard version, <stringEncryption/>, <hideAccess/>, <resourceEncryption/>, <integrityControl/>)
Default value: no default value

Element: paths (Enterprise Only)
Description: Paths to the JAR files/directories to be protected inside of the main container (archive or directory)
Format: contains nested elements
Nested elements (List of <path/> tags)

  Element: path (one or many)
    Format: string
    Default value: no default value

Element: stringEncryption
Description: Encrypt Strings in the input class files in accordance with the filter/annotations.
Format: contains nested elements
Nested elements (<mode>, <checkCaller>, <filters>List of <filter/> tags</filters>) (Only for <mode>filter</mode>):

    Element: mode
    Format: string
    Valid values: off- disable encryption of strings, filter – strings are encrypted in accordance with the filters set in tag, annotations – strings to be encrypted are configured via annotations.
    Default value: filters
    Example: <mode>filter</mode>

    Element: checkCaller
    Description: Enable the call context checks
    Format: boolean
    Valid values: true- the call context checks are enabled, false – disable the checks.
    Default value: true
    Example: <checkCaller>false</checkCaller>

    Element: filter (Many)
    Format: string
    Default value: no default value
    Example: <filter>glob:com/sample/Library/**</filter>

Example (filters):

<stringEncryption>
    <mode>filter</mode>
    <checkCaller>true</checkCaller>
    <filters>
        <filter>glob:com/sample/Library/**</filter>
    </filters>  
</stringEncryption>

Example (annotations):

<stringEncryption>
    <mode>annotations</mode>
</stringEncryption>

Element: hideAccess
Description: Hides accesses to methods/fields in the input class files in accordance with the filter/annotations.
Format: contains nested elements
Nested elements (<mode>, <filters>List of <filter/> tags</filters>) (Only for <mode>filter</mode>):

    Element: mode
    Format: string
    Valid values: off - protection of field accesses and method calls is disabled, filter – the hide access is applied in accordance with <filters>, annotations – the hide access is applied in accordance with annotations.
    Default value: filters
    Example: <mode>filter</mode>

    Element: filter (Many)
    Format: string
    Default value: no default value
    Example: `glob:com/sample/Library/**

Example (filters):

<hideAccess>
    <mode>filter</mode>
    <filters>
        <filter>glob:com/sample/Library/**</filter>
    </filters>  
</hideAccess>

Example (annotations):

<hideAccess>
    <mode>annotations</mode>
</hideAccess>

Element: resourceEncryption
Description: Encrypt resources in the input JAR or directory
Format: contains nested elements
Nested elements (<filters>List of <filter/> tags</filters>) (Only for <mode>filter</mode>):

    Element: filter (Many)
    Format: string
    Default value: no default value
    Example: <filter>*.html</filter>

Example:

<resourceEncryption>
        <filters>
            <filter>*.html</filter>
        </filters>
</resourceEncryption>

Element: integrityControl
Description: Controls the configuration of the tamper resistance module
Format: contains nested elements
Nested elements (<checkBytecode/>, <checkJar/>, <sealJar/>, <mode/>, <filters>List of <filter/> tags</filters>):

    Element: checkBytecode
    Description: Enables the integrity checks at the bytecode level
    Format: boolean
    Valid values: true - enable bytecode checks, false - disable bytecode checks
    Default value: true
    Example: `false

    Element: checkJar
    Description: Enables integrity check at the level of JAR
    Format: boolean
    Valid values: true - enable JAR check, false - disable JAR check
    Default value: true
    Example: <checkJar>false</checkJar>

    Element: sealJar
    Description: Controls JAR sealing (see https://docs.oracle.com/javase/tutorial/deployment/jar/sealman.html)
    Format: boolean
    Valid values: true - enable JAR sealing, false - disable JAR sealing
    Default value: true
    Example: <sealJar>false</sealJar>

    Element: osgiCompatibility
    Description: Switches the protection mechanisms to the mode that is compatible for OSGI containers
    Format: boolean
    Default value: false
    Example: <osgiCompatibility>true</osgiCompatibility>

    Element: mode
    Format: string
    Valid values: off - the integrity protection is disabled, filter – the function is applied in accordance with <filters>
    Default value: filters
    Example: <mode>filter</mode>

    Element: filter (Many)
      Format: string
      Default value: no default value
      Example: <filter>glob:com/sample/Library/**</filter>

Example:

<integrityControl>
    <checkBytecode>true</checkBytecode>
    <checkJar>true</checkJar>
    <sealJar>true</sealJar>
    <osgiCompatibility>true</osgiCompatibility>
    <mode>filter</mode>
    <filters>
        <filter>glob:com/sample/Library/**</filter>
    </filters>  
</integrityControl>

IMPORTANT: If you use a name obfuscator alongside Stringer, for example, ProGuard, in your build chain, it is needed to follow the requirements below:

  • Stringer must be the last step of your build chain

  • If you use annotations to configure Stringer they should be preserved, here is an example for ProGuard:

-keepattributes SourceFile, LineNumberTable, *Annotation*

-keep @interface com.stringer.annotations.** { *; }

  • To be able to use original class names in the configuration, instead of using obfuscated names, you might set proguardMappingFile in Stringer's configuration.


Filters: A guide to targeting code and resources

Stringer Java Obfuscator provides a flexible mechanism of setting the filters for its protection functions. You can use glob or regex syntax modes. Wherein it is possible to use exclusions by placing ! before the filter's expression.

Let us see at different filter settings (glob syntax is used in the following examples).

Say we want to configure a String Encryption's filter and we have got the following structure of packages:

com/google/..
    com/mycompany/..
    com/mycompany/ui/..
    com/mycompany/core/..
  • Protection of certain packages

In order to protect the com/mycompany package (i.e. all the classes that lie under com/mycompany) we should set the following filter:

glob:com/mycompany/**
  • Protection of a certain class

To protect a single class, for example com/mycompany/core/InternalEngine.class we use the following filter:

glob:com/mycompany/core/InternalEngine*
  • Exclusion of certain packages from processing

Here is an example of how to exclude a certain package or packages from processing:


glob:!com/google/**

In this case, a result will be the same as in the first case, where we included everything except com/google. And in the second example, we excluded everything except com/mycompany.

Exclusion for a single class is made in the same way and it is needed to place ! before the class name:

glob:!com/mycompany/core/BumpGenerator*
  • Mixed configuration

Stringer allows using inclusions and exclusions at the same time. When doing that keep in mind the following logic:

  • At first we add an exclusion filter for all the packages and classes

  • Set include filters

  • Add exclude filters for certain packages and/or classes

In other words, Stringer reads and applies rules from the top to the bottom.

For example:

glob:!**/**
    glob:com/mycompany/**
    glob:!com/mycompany/ui/**
    glob:com/mycompany/ui/Payment*

As a result all the classes from com/mycompany and com/mycompany/core are protected, and the com/mycompany/ui/Payment.class is protected as well. Remaining classes from com/mycompany/ui are leaved untouched.

The same approach is used for all the functions that use filters, i.e. Hide Access, Resource Encryption.

Please see stringer.xml file in the root folder of the distribution kit for additional examples.

Detailed syntax information

Filter is to be defined by the syntax and the pattern and takes the form: syntax:pattern, where ':' stands for itself.

Two syntaxes are supported: the "glob" and "regex". The value of the syntax component is compared without regard to case. When the syntax is "glob" then the String representation of the path is matched using a limited pattern language that resembles regular expressions but with a simpler syntax. For example:

  • *.* Matches file names containing a dot.

  • foo.? Matches file names starting with foo. and a single character extension.

  • com/*/* Matches package /com/test/a.

  • com/**Matches all packages and classes inside a com package.

The following rules are used to interpret glob patterns:

  • The * character matches zero or more characters of a name component without crossing directory boundaries.

  • The ** characters matches zero or more characters crossing directory boundaries.

  • The ? character matches exactly one character of a name component.

  • The backslash character (\) is used to escape characters that would otherwise be interpreted as special characters. The expression \\ matches a single backslash and \{ matches a left brace for example.

  • The [ ] characters are a bracket expression that matches a single character of a name component out of a set of characters. For example, [abc] matches "a", "b", or "c". The hyphen (-) may be used to specify a range so [a-z] specifies a range that matches from "a" to "z" (inclusive). These forms can be mixed so [abce-g] matches "a", "b", "c", "e", "f" or "g". If the character after the [ is a ! then it is used for negation so [!a-c] matches any character except "a", "b", or "c". Within a bracket expression the *, ? and \ characters match themselves. The - character matches itself if it is the first character within the brackets or the first character after the ! if negating.

  • The { } characters are a group of subpatterns, where the group matches if any subpattern in the group matches. The , character is used to separate the subpatterns. Groups cannot be nested.

  • Leading period/dot characters in the file name are treated as regular characters in match operations. For example, the * glob pattern matches file name ".login".

  • The ! character in the beginning of the pattern component negates the pattern.

When the syntax is "regex" then the pattern component is a regular expression composed in accordance with java regex rules.

Note: If the syntax is not set (glob: or regex:) old filter format will be used in order to preserve backward compatibility with Stringer’s versions < 3.0.


Annotations

To fine tune your protection process, you can use annotations. Annotations will be used only if you will enable the corresponding parameters in your configuration. You can enable annotations for String Encryption and Hide Access, the annotations are respectively: @StringEncryption and @HideAccess. If there are the annotations in a project then class files and/or their elements marked with the annotations will be protected.

The @StringEncryption annotation can be used at the following hierarchy levels:

Class field - a specified class String is encrypted:

'
import com.stringer.annotations.*;

    public class Test {
     @StringEncryption
      final String SOME_TEXT="12345678";
       ....
    }

Class - all Strings of the class are encrypted:

...
    import com.stringer.annotations.*;

    @StringEncryption 
    public class Test {
       ....
    }

Class method - all Strings of the method are encrypted:

import com.stringer.annotations.*;

    public class Test {
       ....
      @StringEncryption
      public void someMethod(){
         ...
      }
       ....
    }

The @HideAccess annotation can be used at the following hierarchy levels:

Class - all calls of all class methods are hidden:


...
    import com.stringer.annotations.*;

    @HideAccess 
    public class Test {
       ....
    }

To use the annotations in your projects, add the stringer-annotations.jar library from the distribution kit to the project classpath.