Selamlar, bu yazımda Proguard ile Spring Boot uygulamamız üzerinde nasıl obfuscation yapılacağını öğreneceğiz.
Code Obfuscation Nedir?
Class ve variable isimlerini, okunması ve anlaşılması zor hale gelecek şekilde değiştirerek uygulanan bir “şaşırtma” işlemine bu isim veriliyor. Sözlük anlamı olarak da obfuscation “şaşırtma” anlamına gelmektedir.
Neden Bu İşleme İhtiyaç Duyarız?
Kaynak kodlarımızın okunarak know-how’a ait bilgiler veya projemize özel geliştirdiğimiz algoritmaların açık bir şekilde ortaya çıkması engellemek için obfuscation işlemi yapıyoruz. Kodlarımız bize ait bir sunucuda çalışmıyorsa veya bir android uygulaması geliştiriyor isek mecburen uygulamamızın kaynak kodlarını da son kullanıcıya bir şekilde vermiş oluyoruz. Dolayısıyla emeklerimizin korunabilmesi için bu işleme ihtiyaç duymaktayız. Bu süreçte genellikle shrinking ve optimizing işlemlerini de yapabildiğimiz için uygulamanın dosya boyutunda azalma ve performansında da olumlu bir etki sağlanıyor.
Proguard Nedir?
Java tabanlı kodlar için dosya küçültme, optimize etme ve obfuscate işlemlerini yapmayı sağlayan açık kaynak kodlu ve ücretsiz bir tool’dur. Kullanılmayan class, field, method ve attribute’leri algılar ve build anında bunları siler. Proguard, Android SDK’nın bir parçasıdır ve release build alınırken kullanılır.
Maven Nedir?
Maven, Java tabanlı projelerin yapılandırılması, bağımlılıkların yönetilmesi ve proje yaşam döngüsünün kolayca yönetilmesi için kullanılan bir proje yönetim aracıdır. Maven, açık kaynaklı bir proje yönetim aracıdır ve özellikle Java geliştirme ekosisteminde oldukça yaygın olarak kullanılır. Spring Boot gibi büyük ve karmaşık projeleri yönetmek için Maven, geliştiricilere büyük bir kolaylık sağlar.
Maven, projelerinizin yapılandırılması için XML tabanlı bir yapı kullanır ve projenizin bağımlılıklarını, kaynak kodunu, testleri ve dökümantasyonu yönetmek için kullanabileceğiniz bir dizi komut sunar. Bu sayede projenizin bağımlılıkları otomatik olarak çözülür ve projenizin derlenmesi, paketlenmesi ve dağıtılması gibi işlemler kolayca gerçekleştirilir.
Ayrıca, Maven, projenizi standart bir yapıya sahip bir dizin yapısında yönetmenize yardımcı olur ve bu sayede projelerin kolayca anlaşılabilir ve sürdürülebilir olmasını sağlar. Spring Boot projeleri genellikle Maven kullanır ve Proguard gibi güvenlik araçlarıyla birleştirildiğinde, uygulamanızın güvenliği ve yönetilebilirliği önemli ölçüde artırılabilir. Bu nedenle, Spring Boot projeleri oluştururken ve yönetirken Maven’i kullanmak, geliştirme sürecinizi büyük ölçüde kolaylaştırabilir.
Spring Projesine Proguard Nasıl Eklenir?
Proguard standalone olarak kullanılabileceği gibi Maven ile birlikte bizim de yapacağımız gibi unofficial open source bir proje yardımıyla da kullanılabiliyor. Eğer Gradle kullanıyorsanız official olarak kullanıma sunulmuş olan paketi bağımlılıklarınıza ekleyerek kullanabilirsiniz.
Öncelikle projemizin pom.xml dosyasına şu build adımlarını eklemeniz gerekiyor:
<?xml version="1.0" encoding="UTF-8"?> <plugins> <plugin> <groupId>com.github.wvengen</groupId> <artifactId>proguard-maven-plugin</artifactId> <version>2.5.3</version> <executions> <execution> <phase>package</phase> <goals> <goal>proguard</goal> </goals> </execution> </executions> <configuration> <proguardVersion>6.2.2</proguardVersion> <injar>${project.build.finalName}.jar</injar> <outjar>${project.build.finalName}.jar</outjar> <obfuscate>true</obfuscate> <proguardInclude>config.cfg</proguardInclude> </configuration> <dependencies> <dependency> <groupId>net.sf.proguard</groupId> <artifactId>proguard-base</artifactId> <version>6.2.2</version> </dependency> </dependencies> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <executions> <execution> <goals> <goal>repackage</goal> </goals> <configuration> <mainClass>com.codingbytime.app.MainApplication</mainClass> </configuration> </execution> </executions> </plugin> </plugins>
Projenin ana dizinine config.cfg isimli bir dosya oluşturalım ve içerisine bunları yapıştıralım:
-dontshrink -dontoptimize -useuniqueclassmembernames -adaptclassstrings -dontnote -ignorewarnings -dontwarn -keep class * extends org.springframework.boot.web.support.SpringBootServletInitializer -keep class * extends org.springframework.boot.loader.** -keepclasseswithmembers public class * { public static void main(java.lang.String[]);} -keepclassmembers enum * { *; } -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 *; @org.springframework.context.annotation.Primary *; @org.springframework.boot.context.properties.ConfigurationProperties *; @org.springframework.boot.context.properties.EnableConfigurationProperties *; ## thymeleaf kullanıyorsanız gerekiyor *** get*(); void set*(***); } -keep @org.springframework.cache.annotation.EnableCaching class * -keep @org.springframework.context.annotation.Configuration class * -keep @org.springframework.boot.context.properties.ConfigurationProperties class * -keep @org.springframework.boot.autoconfigure.SpringBootApplication class * -keep @org.springframework.stereotype.Repository class * -allowaccessmodification -keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod,RuntimeVisibleAnnotations -keepdirectories org.springframework.boot.autoconfigure -keepclassmembernames class * { java.lang.Class class$(java.lang.String); java.lang.Class class$(java.lang.String, boolean); } -keepnames class * implements java.io.Serializable -keepclassmembers class * implements java.io.Serializable { static final long serialVersionUID; !static !transient ; !private ; }
Pom.xml içerisinde belirtilen main class ve config.cfg kısımlarını kendi uygulamanıza göre değiştirmelisiniz. Ek olarak Maven’a ekleyeceğiniz build kısmını profile altında ekleyerek temel düzeninizi bozmadan yalnızca ihtiyaç olduğunda “mvn clean package -P proguard” şeklinde profile id nizi vererek Proguard ile build alınmasını sağlayabilirsiniz.
Üzerinde çalıştığımız projeler burada göstereceğim kadar basit olmadığından dolayı ek konfigürasyonlara ihtiyacınız olacak, bu durumlarda proguard dokümantasyonunu kullanmanız fazla kaynak olmamasından dolayı hızlıca internette aratmanızdan çok daha fazla yarar sağlamakta. Karşınıza çıkacak bazı sorunlara çözüm getirebilecek durumlardan birkaçını da yazmaya çalışacağım.
- Belirli bir class’ı extend eden her şeyi olduğu gibi bırak: -keep class * extends com.codingbytime.app.MyClass
- Obfuscate edilen paketleri belirli bir paket altında toplamak: -repackageclasses com.codingbytime.app.obfuscate
- Değişken isimlerini sabit tut: -keepclassmembernames class com.codingbytime.app.model.** { *; }
- Verilen class’ları olduğu gibi bırakmak: -keep class com.codingbytime.app.entity.** { *; }
- Değişken isimlerini şu dosyadaki isimlere bakarak değiştir: -obfuscationdictionary variableNames.txt
- Class isimlerini şu dosyadaki isimlere bakarak değiştir: -classobfuscationdictionary classNames.txt #Aynı isimde bean oluşmasını engellemek için kullanılabilir
Bu işlemlerin ardından mvn clean package komutunu çalıştıralım ve oluşan jar dosyamızı da basitçe inceleyerek aradaki değişimleri görelim.
HelloDTO sınıfımızın öncesi ve sonrası:
Controller sınıfımızın öncesi ve sonrası:
Proguard’ın Spring Boot ile kulanımını bu şekilde göstermeye çalıştım. Sorularınız olursa aşağıdan sorularınızı iletebilir, güncel yazılarımıza da şuradan ulaşabilirsiniz.