Derlemenin çözülmesini önlemek için derlenmiş Java sınıfları nasıl kilitlenir?


98

Ayrıştırmayı önlemek için derlenmiş Java sınıflarını nasıl kilitlerim?

İnternette çok iyi tartışılan bir konu olduğunu biliyorum, ancak onlara atıfta bulunduktan sonra herhangi bir sonuca varamadım.

Pek çok insan obfuscator'ı öneriyor, ancak sadece hatırlanması zor karakter dizileri olan sınıfları, yöntemleri ve alanları yeniden adlandırıyorlar, peki ya hassas sabit değerler?

Örneğin, şifreleme ve şifre çözme bileşenini şifre tabanlı bir şifreleme tekniğine dayalı olarak geliştirdiniz. Şimdi bu durumda, herhangi bir ortalama bir Java kişi kullanabilir JAD sınıf dosyası derleme ve kolay yanı sıra (sabit olarak tanımlanır) şifre değerini almak için tuz küçük bağımsız bir program yazarak verilerin şifresini çözebilir ve sırayla!

Veya bu tür hassas bileşenler yerel kodda (örneğin, VC ++) oluşturulmalı ve bunları JNI aracılığıyla mı çağırmalı ?


Demonte edilmiş yerel kod bile bazı insanlar tarafından oldukça okunabilir olsa da, açık olmaması için muhtemelen bir gizleyici veya el yapımı montaj kullanmanız gerekir (optimizasyonla derlenen ortak C ++ yeterince okunabilir). Kullanıcının cihazında çalıştırılan kod ne olursa olsun, ele geçirilebilir. Bu tür bir müdahalenin maliyet / beceri gereksinimleri oldukça yüksek olabilse de, örneğin akıllı kart "kurcalamaya dayanıklı" yonga kodunu kırmak önemsiz değildir, yalnızca en iyi ekipman ve beceri ile yapılabilir. Java dersleriyle ... Çok fazla uğraşmam, muhtemelen onları senaryo çocuklarını uzaklaştıracak kadar şifreleyebilirsin, daha fazlasını değil.
Ped7g

Yanıtlar:


97

Daha gelişmiş Java bayt kodu gizleyicilerinden bazıları, sınıf adı karıştırmaktan çok daha fazlasını yapar. Örneğin Zelix KlassMaster , kod akışınızı takip etmeyi gerçekten zorlaştıracak ve mükemmel bir kod iyileştirici olarak çalışacak şekilde karıştırabilir ...

Ayrıca birçok obfuscator, string sabitlerinizi karıştırabilir ve kullanılmayan kodu kaldırabilir.

Başka bir olası çözüm (gizlemeyi dışlamak zorunda değildir), şifrelenmiş JAR dosyaları ve şifre çözme işlemini gerçekleştiren özel bir sınıf yükleyici (tercihen yerel çalışma zamanı kitaplığı kullanarak) kullanmaktır.

Üçüncüsü (ve muhtemelen en güçlü korumayı sunan), örneğin Java kodunuzu doğrudan platforma özgü yerel ikili dosyada derleyen GCC veya Excelsior JET gibi yerel önceden derleyiciler kullanmaktır .

Her halükarda, Estonca'da "Kilitler hayvanlar içindir" denildiği gibi unutulmamalıdır. Bu, çalışma süresi boyunca her kod parçasının mevcut olduğu (belleğe yüklendiği) ve yeterli beceri, kararlılık ve motivasyon verildiği anlamına gelir, insanlar kodunuzu çözebilir, çözebilir ve kıracaktır ... İşiniz, süreci basitçe bir şeyi çalıştırabilir ve hala devam ettirebilirsiniz ...


14
"Kilitler hayvanlar içindir" için +1. Sanırım buradaki uygun terim senaryo çocukları olacaktır.
Antimon

GCJ demek istiyorsun ve o öldü.
user207421

1
Componio jar dosyası şifrelemesi de öldü. Kullanım JarProtector yerine.
J.Profi

16

Hem şifrelenmiş verilere hem de şifresini çözen yazılıma erişimleri olduğu sürece, bunu tamamen güvenli hale getirmenin temelde hiçbir yolu yoktur. Bunun daha önce çözüldüğü yollar, dongle'lar, uzaktan kimlik doğrulama sunucuları vb. Gibi şifreleme / şifre çözmeyi işlemek için bir tür harici kara kutu kullanmaktı.Ancak o zaman bile, kullanıcının kendi sistemine tam erişimi olduğu göz önüne alındığında, bu yalnızca bir şeyler yapar zor, imkansız değil - ürününüzü, örneğin çevrimiçi oyun sunucuları gibi "kara kutuda" depolanan işlevselliğe doğrudan bağlayamazsanız.


13

Sorumluluk reddi: Ben bir güvenlik uzmanı değilim.

Kulağa kötü bir fikir gibi geliyor: Birisinin ona verdiğiniz 'gizli' bir anahtarla bir şeyleri şifrelemesine izin veriyorsunuz. Bunun güvenli hale getirilebileceğini sanmıyorum.

Belki asimetrik tuşlar işe yarayabilir:

  • şifresini çözmek için genel bir anahtarla şifrelenmiş bir lisans dağıtın
  • Müşterinin yeni bir lisans oluşturmasına ve şifreleme için size göndermesine izin verin
  • müşteriye yeni bir lisans gönderin.

Emin değilim, ancak müşterinin lisans anahtarını ona verdiğiniz genel anahtarla şifreleyebileceğine inanıyorum. Daha sonra özel anahtarınızla şifresini çözebilir ve yeniden şifreleyebilirsiniz.

Doğru müşteriden bir şeyler aldığınızdan emin olmak için müşteri başına ayrı bir genel / özel anahtar çifti tutabilirsiniz - artık anahtarlardan siz sorumlusunuz ...


2
Bu tekniği daha önce kullandım ve iyi çalışıyor. Bununla birlikte, saldırı açısından bakıldığında, ilk yaklaşım, yalnızca lisans kontrolünü gerçekleştiren kodu değiştirip kaldırmak olacaktır. Bu saldırı vektörünü zorlaştırmak için yapabileceğiniz şeyler var, ancak saldırgana donanımın kontrolünü verirseniz, kaderiniz uygun şekilde motive edilmiş ve yetenekli bir saldırganla başarısız olacaktır. Uygulamada amaç, çoğunlukla dürüst insanları dürüst tutmaktır.
Jim Rush

12

Ne yaparsanız yapın, 'derlenmiş olabilir'. Heck, onu parçalarına ayırabilirsin. Veya sabitlerinizi bulmak için bir bellek dökümüne bakın. Gördüğünüz gibi, bilgisayarın bunları bilmesi gerekiyor, bu yüzden kodunuzun da buna ihtiyacı olacak.

Bununla ilgili ne yapmalı?

Anahtarı kodunuzda sabit kodlanmış bir sabit olarak göndermemeye çalışın: Kullanıcı bazında bir ayar olarak tutun. Kullanıcıyı bu anahtara bakmakla sorumlu kılın.


6

@jatanp: veya daha iyisi, derlemeyi çözebilir, lisans kodunu kaldırabilir ve yeniden derleyebilirler. Java ile, bu soruna uygun, hacklenmeye karşı korumalı bir çözüm olduğunu düşünmüyorum. Küçük kötü bir dongle bile Java ile bunu engelleyemez.

Kendi şirket yöneticilerim bunun için endişeleniyor ve bence çok fazla. Ancak yine de uygulamamızı lisans koşullarına uyma eğiliminde olan büyük şirketlere satıyoruz - genellikle fasulye tezgahları ve avukatlar sayesinde güvenli bir ortam. Lisansınız doğru yazılırsa, kendi kendini kaynak koda dönüştürme eylemi yasa dışı olabilir.

Bu yüzden, başvurunuz için aradığınız gibi gerçekten sertleştirilmiş korumaya ihtiyacınız var mı? Müşteri tabanınız neye benziyor? (Şirketler mi? Veya genç oyuncu kitleleri, bu daha çok nerede sorun olur?)


Aslında, btw'nin
Dmitry Leskov

@DmitryLeskov 'hack dirençli', belki. Ancak bu, kodu isteyen herkes için sadece bir hız artışıdır. Günün sonunda, bayt kodunun şifrelenmemiş bir ana bilgisayar platformunda çalışması gerekir. Tam dur.
Stu Thompson

Bağlantı verdiğim gönderiyi okumadınız. Bayt kodu, dongle'ın CPU koduna dönüştürülür ve şifrelenir. Son kullanıcı korumalı uygulamayı çalıştırdığında, bu şifreli kod "dongle" a aktarılır. Dongle, şifresini çözer ve CPU'sunda çalıştırır.
Dmitry Leskov

2
Kurumsal genç oyuncular.
odiszapc

3

Bir lisanslama çözümü arıyorsanız TrueLicense API'ye göz atabilirsiniz . Asimetrik tuşların kullanımına dayanır. Ancak bu, uygulamanızın kırılamayacağı anlamına gelmez. Her uygulama yeterli çabayla kırılabilir. Gerçekten önemli olan, Stu'nun yanıtladığı gibi , ne kadar güçlü bir korumaya ihtiyacınız olduğunu bulmak.


2

Etkili bir çevrimdışı anti-korsanlık yöntemi olduğunu sanmıyorum. Video oyunu endüstrisi bunu birçok kez bulmaya çalıştı ve programları her zaman kırıldı. Tek çözüm, programın sunucularınızla çevrimiçi bağlantılı olarak çalıştırılması gerektiğidir, böylece lincense anahtarını doğrulayabilirsiniz ve lisans sahibi tarafından aynı anda yalnızca bir etkin bağlantı vardır. Bu nasıl World of Warcraft ya da Diablo çalışır. Zorlu bile olsa, güvenliği aşmaları için geliştirilmiş özel sunucular vardır.

Bunu söyledikten sonra, orta / büyük şirketlerin yasadışı kopyalanmış yazılım kullandıklarına inanmıyorum, çünkü onlar için lisans maliyeti minimumdur (belki, programınız için ne kadar ücretlendireceğinizi bilmiyorum) deneme sürümünün maliyeti.


2

Bayt kodu şifrelemesini korkmadan kullanabilirsiniz.

Gerçek şu ki, yukarıda bahsedilen "Java bayt kodu şifrelemesini kırma" makalesi bir mantık yanılgısı içeriyor. Makalenin ana iddiası, tüm sınıfların çalıştırılmadan önce şifresinin çözülmesi ve ClassLoader.defineClass(...)yönteme aktarılması gerektiğidir . Ama bu doğru değil.

Burada gözden kaçan varsayım , bunların otantik veya standart java çalışma zamanı ortamında çalıştıklarıdır . Hiçbir şey korumalı java uygulamasını yalnızca bu sınıfları başlatmakla kalmaz, aynı zamanda bunların şifresini çözüp ona iletmesini bile zorlayamaz ClassLoader. Diğer bir deyişle, standart JRE içindeyseniz defineClass(...), standart java bu amaç için API'ye sahip olmadığından yöntemi engelleyemezsiniz ve yamalı ClassLoaderveya başka bir "hacker hilesi" ile değiştirilmiş JRE kullanıyorsanız java uygulaması hiç çalışmayacak ve bu nedenle araya girecek hiçbir şeyiniz olmayacak. Ve kesinlikle hangi "yama bulucunun" kullanıldığı veya hackerlar tarafından hangi numaranın kullanıldığı önemli değil. Bu teknik detaylar oldukça farklı bir hikaye.


Yamalı bir JVM'yi tam olarak nasıl tespit etmeyi düşünüyorsunuz? Her neyse, tüm bunların yaptığı işleri biraz daha zorlaştırmaktır.
Antimon

Uygulama başlatıcınızda defineClass () için bir çağrı bulamıyor musunuz? Bu aramayı yaptığınızda, yine de bir dizi şifresi çözülmüş bayt vermeniz gerekir. Orijinal kaynağın sızabileceği başka bir nokta değil mi?
Yükselen

4
Bu yanıta gerçekten katılmıyorum. Bana göre bu, "Soru: Pi'yi bulmanın en kolay yolu nedir? Cevap: 2 * Pi alın ve ikiye bölün." Fikre katılmıyorum, ancak daha fazla ayrıntı verebilir misiniz? Örneğin, ana programın saf java ile yazılmasını bekliyor musunuz? Buna değişiklik arayan kod dahil mi?
Patrick M

-1

S: .class dosyalarımı şifrelersem ve bunları anında yüklemek ve şifresini çözmek için özel bir sınıf yükleyici kullanırsam, bu durum derlemenin çözülmesini engeller mi?

C: Java bayt kodu çözümlemesini engelleme sorunu neredeyse dilin kendisi kadar eskidir. Piyasada bulunan bir dizi gizleme aracına rağmen, acemi Java programcıları fikri mülkiyetlerini korumak için yeni ve akıllı yollar düşünmeye devam ediyor. Bu Java Soru-Cevap bölümünde, tartışma forumlarında sık sık tekrarlanan bir fikirle ilgili bazı mitleri ortadan kaldırıyorum.

Java .class dosyalarının orijinallere çok benzeyen Java kaynaklarına yeniden yapılandırılabilmesinin son derece kolay olması, Java bayt kodu tasarım hedefleri ve değiş tokuşlarla çok ilgilidir. Diğer şeylerin yanı sıra, Java bayt kodu kompaktlık, platform bağımsızlığı, ağ hareketliliği ve bayt kodu yorumlayıcıları ve JIT (tam zamanında) / HotSpot dinamik derleyicileri tarafından analiz kolaylığı için tasarlanmıştır. Muhtemelen, derlenmiş .class dosyaları programcının amacını açık bir şekilde ifade eder, o kadar net bir şekilde analiz edilmeleri orijinal kaynak kodundan daha kolay olabilir.

Derlemenin tamamen çözülmesini engellemek olmasa da en azından daha zor hale getirmek için birkaç şey yapılabilir. Örneğin, derleme sonrası bir adım olarak, bayt kodunun derlenmiş haldeyken okunmasını veya geçerli Java koduna (veya her ikisine) dönüştürülmesini zorlaştırmak için .class verilerine masaj yapabilirsiniz. Aşırı yöntem adının aşırı yüklenmesi gibi teknikler ilki için iyi işliyor ve Java sözdizimi aracılığıyla temsil edilmesi mümkün olmayan kontrol yapıları oluşturmak için kontrol akışını manipüle etmek ikincisi için iyi çalışıyor. Daha başarılı ticari obfuscatorlar, bunların ve diğer tekniklerin bir karışımını kullanır.

Ne yazık ki, her iki yaklaşım da JVM'nin çalıştıracağı kodu gerçekten değiştirmelidir ve birçok kullanıcı bu dönüşümün uygulamalarına yeni hatalar ekleyebileceğinden korkar (haklı olarak öyle). Ayrıca, yöntem ve alan yeniden adlandırma, yansıma çağrılarının çalışmayı durdurmasına neden olabilir. Gerçek sınıf ve paket adlarını değiştirmek, diğer birkaç Java API'sini (JNDI (Java Adlandırma ve Dizin Arayüzü), URL sağlayıcıları vb.) Bozabilir. Değiştirilen adlara ek olarak, sınıf bayt kodu uzaklıkları ile kaynak satır numaraları arasındaki ilişki değiştirilirse, orijinal istisna yığını izlerini kurtarmak zor olabilir.

Daha sonra orijinal Java kaynak kodunu gizleme seçeneği vardır. Ancak temelde bu, benzer bir dizi soruna neden olur. Gizlemek değil, şifrelemek mi?

Belki de yukarıdakiler, "Bayt kodunu değiştirmek yerine, derlemeden sonra tüm sınıflarımı şifrelersem ve JVM içinde anında şifresini çözersem (ki bu özel bir sınıf yükleyiciyle yapılabilir)? Sonra JVM benim orijinal bayt kodu ve yine de derlemeyi çözecek veya tersine mühendislik yapacak bir şey yok, değil mi? "

Ne yazık ki, hem bu fikri ilk ortaya atanın siz olduğunu düşünürken hem de gerçekten işe yaradığını düşünürken yanılıyorsunuz. Ve bunun nedeninin şifreleme planınızın gücüyle hiçbir ilgisi yoktur.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.