Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot obfuscator

I'm using Spring Boot with bootRepackage gradle to build release jar file. My project need to obfuscator code before deliver to customer. I tried proguard and some other tool but many problem occur. Can i have advice how to config such tools for spring boot.

I tried ProGuard with these config

-injars  ./build/libs/webservice-1.0.jar
-outjars ./build/libs/webservice-obs-1.0.jar
-libraryjars <java.home>/lib/rt.jar
-keep class !myapplicationpackage.** { *; }
-keep class myapplicationpackage.Application { *; }

-ignorewarnings
-keepdirectories **
-dontshrink
-keepattributes *Annotation*

-keepclassmembers class com.yumyumlabs.** { java.lang.Long id; }
-keepnames class com.yumyumlabs.** implements java.io.Serializable

-keepclassmembers class * implements java.io.Serializable {
    static final long serialVersionUID;
    private static final java.io.ObjectStreamField[] serialPersistentFields;
    !static !transient <fields>;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}


-keepclassmembers class * { 
    @org.springframework.beans.factory.annotation.Autowired *; 
    @org.springframework.beans.factory.annotation.Qualifier *; 
    @org.springframework.beans.factory.annotation.Value *; 
    @org.springframework.beans.factory.annotation.Required *;
    @org.springframework.context.annotation.Bean *;
    @javax.annotation.PostConstruct *;
    @javax.annotation.PreDestroy *;
    @org.aspectj.lang.annotation.AfterReturning *;
    @org.aspectj.lang.annotation.Pointcut *;
    @org.aspectj.lang.annotation.AfterThrowing *;
    @org.aspectj.lang.annotation.Around *;
}
-keep @org.springframework.stereotype.Service class *
-keep @org.springframework.stereotype.Controller class *
-keep @org.springframework.stereotype.Component class *
-keep @org.springframework.stereotype.Repository class *
-keep @org.springframework.cache.annotation.EnableCaching class *
-keep @org.springframework.context.annotation.Configuration class *
-keepattributes Signature

-dontwarn com.yumyumlabs.web.controllers.auth.AuthController



-dontwarn com.google.apphosting.api.ReflectionUtils
-dontwarn sun.misc.Unsafe




-dontwarn org.tartarus.snowball.**
-dontnote

-keepattributes Signature,RuntimeVisibleAnnotations,AnnotationDefault

But the generated jar cant run

java.lang.IllegalStateException: Unable to open nested entry 'lib/spring-boot-starter-web-1.2.0.RELEASE.jar'. It has been compressed and nested jar files must be stored without compression. Please check the mechanism used to create your executable jar file
at org.springframework.boot.loader.jar.JarFile.createJarFileFromFileEntry(Unknown Source)
at org.springframework.boot.loader.jar.JarFile.createJarFileFromEntry(Unknown Source)
at org.springframework.boot.loader.jar.JarFile.getNestedJarFile(Unknown Source)
at org.springframework.boot.loader.archive.JarFileArchive.getNestedArchive(Unknown Source)
at org.springframework.boot.loader.archive.JarFileArchive.getNestedArchives(Unknown Source)
at org.springframework.boot.loader.ExecutableArchiveLauncher.getClassPathArchives(Unknown Source)
at org.springframework.boot.loader.Launcher.launch(Unknown Source)
at org.springframework.boot.loader.JarLauncher.main(Unknown Source)
like image 222
Cao Manh Dat Avatar asked Dec 18 '14 08:12

Cao Manh Dat


2 Answers

It is telling you the problem. It is compressing the embedded JAR files which is not allowed. You need to get it to skip the compression of child elements. Probably best to skip the compression altogether.

Really you could just skip all of it as this makes it a little harder to reverse engineer, but not does not stop it. If you really need to keep it secret that badly then your only real choice is to sell your app as service rather than providing a JAR, WAR, EAR, etc.

IllegalStateException: Unable to open nested entry 'lib/spring-boot-starter-web-1.2.0.RELEASE.jar'. It has been compressed and nested jar files must be stored without compression. Please check the mechanism used to create your executable jar file

like image 196
BrianC Avatar answered Sep 21 '22 02:09

BrianC


This can be done by repacking the uncompressed library. This can be done using the jar tool with the following bash script. The script simply has to be executed in the projects main directory.

# some constant settings we use
work_dir=work
uncompress_dir=uncompress
library_dir=lib

# parameters for input and output files
# the name of the library that should be uncompressed
library_name="spring-boot-starter-web-1.2.0.RELEASE.jar"
# the obfuscated artifact
original_jar='webservice-obs-1.0.jar'
# the new obfuscated artifact (can be the same)
repacked_jar='webservice-obs-repack-1.0.jar'

# build the obfuscated library
mvn clean package -Dobfuscation

# create working directory and copy obfuscated artifact
mkdir target/$work_dir
cp target/$original_jar target/$work_dir
cd target/$work_dir

# extract contents of obfuscated artifact
jar xvf $original_jar
rm $original_jar

# uncompress the target library and jar again without compression (c0)
mkdir $uncompress_dir
mv $library_dir/$library_name $uncompress_dir
cd $uncompress_dir
jar xvf $library_name
rm $library_name
jar c0mf ./META-INF/MANIFEST.MF $library_name *
mv $library_name ../$library_dir
cd ..
rm -r $uncompress_dir

# jar the complete obfuscated artifact again
# it is important here to copy the manifest as otherwise the library would not be executeable any more by spring-boot
jar c0mf ./META-INF/MANIFEST.MF ../$repacked_jar *

# cleanup work dir
cd ..
rm -r $work_dir

Probably you have to do this again if more files need this special handling. One of the libraries which do this is for example quartz.

like image 33
kap Avatar answered Sep 19 '22 02:09

kap