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/u
i 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
.
-
Overview
Introduction to Stringer > Overview -
Features
Introduction to Stringer > Features -
Samples
Introduction to Stringer > Samples -
Introduction
Getting started > Introduction -
1. Download
Getting started > 1. Download -
2. Activate
Getting started > 2. Activate -
3. After Activation
Getting started > 3. After Activation -
Configuration file format
Configuring Stringer protection > Configuration file format -
Filters: A guide to targeting code and resources
Configuring Stringer protection > Filters: A guide to targeting code and resources -
Annotations
Configuring Stringer protection > Annotations -
Run Stringer via the CLI
Implementing Stringer protection > Run Stringer via the CLI -
Run Stringer via the Stringer GUI
Implementing Stringer protection > Run Stringer via the Stringer GUI -
Eclipse Plugin
Implementing Stringer protection > Eclipse Plugin -
Ant Task
Implementing Stringer protection > Ant Task -
Maven Plugin
Implementing Stringer protection > Maven Plugin -
Gradle Plugin
Implementing Stringer protection > Gradle Plugin -
NetBeans
Implementing Stringer protection > NetBeans -
JavaFX Projects
Implementing Stringer protection > JavaFX Projects
Link copied!