當前位置:首頁 » 密碼管理 » javaclassloader加密

javaclassloader加密

發布時間: 2022-07-30 03:34:43

『壹』 為什麼要自定義classloader

比較典型的自定義classloader使用情況就是給類加密java編譯的代碼可以輕易的被反編譯,有些企業會給自己的類做特殊的加密,防止反編譯,類加密後就不能再用java的
classloader去載入類了,這時就需要自定義classloader,再載入類的時候先解密類,然後再載入。
具體的代碼自己可以網路一下class加密有很多文章介紹的。

『貳』 classloader來自哪個類

ClassLoader主要對類的請求提供服務,當JVM需要某類時,它根據名稱向ClassLoader要求這個類,然後由ClassLoader返回這個類的class對象。 1.1 幾個相關概念ClassLoader負責載入系統的所有Resources(Class,文件,來自網路的位元組流等),通過ClassLoader從而將資源載入JVM
每個class都有一個reference,指向自己的ClassLoader。Class.getClassLoader()
array的ClassLoader就是其元素的ClassLoader,若是基本數據類型,則這個array沒有ClassLoader
1.2 主要方法和工作過程Java1.1及從前版本中,ClassLoader主要方法:
Class loadClass( String name, boolean resolve ); ClassLoader.loadClass() 是 ClassLoader 的入口點
defineClass 方法是 ClassLoader 的主要訣竅。該方法接受由原始位元組組成的數組並把它轉換成 Class 對象。原始數組包含如從文件系統或網路裝入的數據。
findSystemClass 方法從本地文件系統裝入文件。它在本地文件系統中尋找類文件,如果存在,就使用 defineClass 將原始位元組轉換成 Class 對象,以將該文件轉換成類。當運行 Java 應用程序時,這是 JVM 正常裝入類的預設機制。
resolveClass可以不完全地(不帶解析)裝入類,也可以完全地(帶解析)裝入類。當編寫我們自己的 loadClass 時,可以調用 resolveClass,這取決於 loadClass 的 resolve 參數的值
findLoadedClass 充當一個緩存:當請求 loadClass 裝入類時,它調用該方法來查看 ClassLoader 是否已裝入這個類,這樣可以避免重新裝入已存在類所造成的麻煩。應首先調用該方法
一般load方法過程如下:

調用 findLoadedClass 來查看是否存在已裝入的類。
如果沒有,那麼採用某種特殊的神奇方式來獲取原始位元組。(通過IO從文件系統,來自網路的位元組流等)
如果已有原始位元組,調用 defineClass 將它們轉換成 Class 對象。
如果沒有原始位元組,然後調用 findSystemClass 查看是否從本地文件系統獲取類。
如果 resolve 參數是 true,那麼調用 resolveClass 解析 Class 對象。
如果還沒有類,返回 ClassNotFoundException。
否則,將類返回給調用程序。
1.3 委託模型自從JDK1.2以後,ClassLoader做了改進,使用了委託模型,所有系統中的ClassLoader組成一棵樹,ClassLoader在載入類庫時先讓Parent尋找,Parent找不到才自己找。
JVM在運行時會產生三個ClassLoader,Bootstrap ClassLoader、Extension ClassLoader和App ClassLoader。其中,Bootstrap ClassLoader是用C++編寫的,在Java中看不到它,是null。它用來載入核心類庫,就是在lib下的類庫,Extension ClassLoader載入lib/ext下的類庫,App ClassLoader載入Classpath里的類庫,三者的關系為:App ClassLoader的Parent是Extension ClassLoader,而Extension ClassLoader的Parent為Bootstrap ClassLoader。載入一個類時,首先BootStrap進行尋找,找不到再由Extension ClassLoader尋找,最後才是App ClassLoader。

將ClassLoader設計成委託模型的一個重要原因是出於安全考慮,比如在Applet中,如果編寫了一個java.lang.String類並具有破壞性。假如不採用這種委託機制,就會將這個具有破壞性的String載入到了用戶機器上,導致破壞用戶安全。但採用這種委託機制則不會出現這種情況。因為要載入java.lang.String類時,系統最終會由Bootstrap進行載入,這個具有破壞性的String永遠沒有機會載入。

委託模型還帶來了一些問題,在某些情況下會產生混淆,如下是Tomcat的ClassLoader結構圖:

Bootstrap
|
System
|
Common
/
Catalina Shared
/
Webapp1 Webapp2 ...

由 Common 類裝入器裝入的類決不能(根據名稱)直接訪問由 Web 應用程序裝入的類。使這些類聯系在一起的唯一方法是通過使用這兩個類集都可見的介面。在這個例子中,就是包含由 Java servlet 實現的 javax.servlet.Servlet。
如果在lib或者lib/ext等類庫有與應用中同樣的類,那麼應用中的類將無法被載入。通常在jdk新版本出現有類庫移動時會出現問題,例如最初我們使用自己的xml解析器,而在jdk1.4中xml解析器變成標准類庫,load的優先順序也高於我們自己的xml解析器,我們自己的xml解析器永遠無法找到,將可能導致我們的應用無法運行。

相同的類,不同的ClassLoader,將導致ClassCastException異常

1.4 線程中的ClassLoader每個運行中的線程都有一個成員contextClassLoader,用來在運行時動態地載入其它類,可以使用方法Thread.currentThread().setContextClassLoader(...);更改當前線程的contextClassLoader,來改變其載入類的行為;也可以通過方法Thread.currentThread().getContextClassLoader()來獲得當前線程的ClassLoader。
實際上,在Java應用中所有程序都運行在線程里,如果在程序中沒有手工設置過ClassLoader,對於一般的java類如下兩種方法獲得的ClassLoader通常都是同一個

this.getClass.getClassLoader();
Thread.currentThread().getContextClassLoader();
方法一得到的Classloader是靜態的,表明類的載入者是誰;方法二得到的Classloader是動態的,誰執行(某個線程),就是那個執行者的Classloader。對於單例模式的類,靜態類等,載入一次後,這個實例會被很多程序(線程)調用,對於這些類,載入的Classloader和執行線程的Classloader通常都不同。

1.5 Web應用中的ClassLoader回到上面的例子,在Tomcat里,WebApp的ClassLoader的工作原理有點不同,它先試圖自己載入類(在ContextPath/WEB-INF/...中載入類),如果無法載入,再請求父ClassLoader完成。
由此可得:

對於WEB APP線程,它的contextClassLoader是WebAppClassLoader
對於Tomcat Server線程,它的contextClassLoader是CatalinaClassLoader
1.6 獲得ClassLoader的幾種方法可以通過如下3種方法得到ClassLoader
this.getClass.getClassLoader(); // 使用當前類的ClassLoader
Thread.currentThread().getContextClassLoader(); // 使用當前線程的ClassLoader
ClassLoader.getSystemClassLoader(); // 使用系統ClassLoader,即系統的入口點所使用的ClassLoader。(注意,system ClassLoader與根ClassLoader並不一樣。JVM下system ClassLoader通常為App ClassLoader)
1.7 幾種擴展應用用戶定製自己的ClassLoader可以實現以下的一些應用
安全性。類進入JVM之前先經過ClassLoader,所以可以在這邊檢查是否有正確的數字簽名等
加密。java位元組碼很容易被反編譯,通過定製ClassLoader使得位元組碼先加密防止別人下載後反編譯,這里的ClassLoader相當於一個動態的解碼器
歸檔。可能為了節省網路資源,對自己的代碼做一些特殊的歸檔,然後用定製的ClassLoader來解檔
自展開程序。把java應用程序編譯成單個可執行類文件,這個文件包含壓縮的和加密的類文件數據,同時有一個固定的ClassLoader,當程序運行時它在內存中完全自行解開,無需先安裝
動態生成。可以生成應用其他還未生成類的類,實時創建整個類並可在任何時刻引入JVM
2.0 資源載入
所有資源都通過ClassLoader載入到JVM里,那麼在載入資源時當然可以使用ClassLoader,只是對於不同的資源還可以使用一些別的方式載入,例如對於類可以直接new,對於文件可以直接做IO等。 2.1 載入類的幾種方法假設有類A和類B,A在方法amethod里需要實例化B,可能的方法有3種。對於載入類的情況,用戶需要知道B類的完整名字(包括包名,例如"com.rain.B")
1. 使用Class靜態方法 Class.forName

Class cls = Class.forName("com.rain.B");
B b = (B)cls.newInstance();

2. 使用ClassLoader
/* Step 1. Get ClassLoader */
ClassLoader cl; // 如何獲得ClassLoader參考1.6

/* Step 2. Load the class */
Class cls = cl.loadClass("com.rain.B"); // 使用第一步得到的ClassLoader來載入B

/* Step 3. new instance */
B b = (B)cls.newInstance(); // 有B的類得到一個B的實例

3. 直接new
B b = new B();

2.2 文件載入(例如配置文件等)假設在com.rain.A類里想讀取文件夾 /com/rain/config 里的文件sys.properties,讀取文件可以通過絕對路徑或相對路徑,絕對路徑很簡單,在Windows下以盤號開始,在Unix下以"/"開始
對於相對路徑,其相對值是相對於ClassLoader的,因為ClassLoader是一棵樹,所以這個相對路徑和ClassLoader樹上的任何一個ClassLoader相對比較後可以找到文件,那麼文件就可以找到,當然,讀取文件也使用委託模型

1. 直接IO

/**
* 假設當前位置是 "C:/test",通過執行如下命令來運行A "java com.rain.A"
* 1. 在程序里可以使用絕對路徑,Windows下的絕對路徑以盤號開始,Unix下以"/"開始
* 2. 也可以使用相對路徑,相對路徑前面沒有"/"
* 因為我們在 "C:/test" 目錄下執行程序,程序入口點是"C:/test",相對路徑就
* 是 "com/rain/config/sys.properties"
* (例子中,當前程序的ClassLoader是App ClassLoader,system ClassLoader = 當前的
* 程序的ClassLoader,入口點是"C:/test")
* 對於ClassLoader樹,如果文件在jdk lib下,如果文件在jdk lib/ext下,如果文件在環境變數里,
* 都可以通過相對路徑"sys.properties"找到,lib下的文件最先被找到
*/
File f = new File("C:/test/com/rain/config/sys.properties"); // 使用絕對路徑
//File f = new File("com/rain/config/sys.properties"); // 使用相對路徑
InputStream is = new FileInputStream(f);

如果是配置文件,可以通過java.util.Properties.load(is)將內容讀到Properties里,Properties默認認為is的編碼是ISO-8859-1,如果配置文件是非英文的,可能出現亂碼問題。
2. 使用ClassLoader

/**
* 因為有3種方法得到ClassLoader,對應有如下3種方法讀取文件
* 使用的路徑是相對於這個ClassLoader的那個點的相對路徑,此處只能使用相對路徑
*/
InputStream is = null;
is = this.getClass().getClassLoader().getResourceAsStream(
"com/rain/config/sys.properties"); //方法1
//is = Thread.currentThread().getContextClassLoader().getResourceAsStream(
"com/rain/config/sys.properties"); //方法2
//is = ClassLoader.getSystemResourceAsStream("com/rain/config/sys.properties"); //方法3

如果是配置文件,可以通過java.util.Properties.load(is)將內容讀到Properties里,這里要注意編碼問題。
3. 使用ResourceBundle

ResourceBundle bundle = ResourceBundle.getBoundle("com.rain.config.sys");

這種用法通常用來載入用戶的配置文件,關於ResourceBunlde更詳細的用法請參考其他文檔
總結:有如下3種途徑來載入文件

1. 絕對路徑 ---> IO
2. 相對路徑 ---> IO
---> ClassLoader
3. 資源文件 ---> ResourceBundle

2.3 如何在web應用里載入資源在web應用里當然也可以使用ClassLoader來載入資源,但更常用的情況是使用ServletContext,如下是web目錄結構
ContextRoot
|- JSP、HTML、Image等各種文件
|- [WEB-INF]
|- web.xml
|- [lib] Web用到的JAR文件
|- [classes] 類文件

用戶程序通常在classes目錄下,如果想讀取classes目錄里的文件,可以使用ClassLoader,如果想讀取其他的文件,一般使用ServletContext.getResource()
如果使用ServletContext.getResource(path)方法,路徑必須以"/"開始,路徑被解釋成相對於ContextRoot的路徑,此處載入文件的方法和ClassLoader不同,舉例"/WEB-INF/web.xml","/download/WebExAgent.rar"

『叄』 我手頭有一個web系統,很多java class類都是加密的,是用classloader.dll載入

樓主你好,這種錯誤不在現場調試,沒有人可以給出一個正確的答案,而且還是偶爾報錯,屬於「幽靈事件」,我大致給出一個思路,jvm中類的載入器都遵循雙親委派模型,如果不清楚,網上可以了解下,而tomcat是正統的類載入器架構,如圖:

其中WebAppClassLoader會去載入/Webapp/WEB-INF/*中的Java類庫,所以,上述報錯可能與java環境出錯有關,可能java jar包殘缺,
並且報錯也隱約看出來,我認為是java 環境的問題,樓主看參考解決下,望對你有所幫助!

『肆』 classloader的原理 有哪些類載入器 為什麼要用自定義類載入器

原理之類的,你自己上網看資料吧,不是一兩句話說得清的。

至於為什麼用自定義類載入器,個人總結了一下可能有下面幾點吧,可能不全,也請大家補充:

  1. 加密:眾所周知,java代碼很容易被反編譯,如果你需要把自己的代碼進行加密,可以先將編譯後的代碼用某種加密演算法加密,然後實現自己的類載入器,負責將這段加密後的代碼還原。

  2. 從非標準的來源載入代碼:例如你的部分位元組碼是放在資料庫中甚至是網路上的,就可以自己寫個類載入器,從指定的來源載入類。

  3. 動態創建:為了性能等等可能的理由,根據實際情況動態創建代碼並執行。

  4. 其他(這個理由非常給力吧^_^)

『伍』 如何有效的防止Java程序被反編譯和破解

由於Java位元組碼的抽象級別較高,因此它們較容易被反編譯。下面介紹了幾種常用的方法,用於保護Java位元組碼不被反編譯。通常,這些方法不能夠絕對防止程序被反編譯,而是加大反編譯的難度而已,因為這些方法都有自己的使用環境和弱點。
1.隔離Java程序
最簡單的方法就是讓用戶不能夠訪問到Java Class程序,這種方法是最根本的方法,具體實現有多種方式。例如,開發人員可以將關鍵的Java Class放在伺服器端,客戶端通過訪問伺服器的相關介面來獲得服務,而不是直接訪問Class文件。這樣黑客就沒有辦法反編譯Class文件。目前,通過介面提供服務的標准和協議也越來越多,例如 HTTP、Web Service、RPC等。但是有很多應用都不適合這種保護方式,例如對於單機運行的程序就無法隔離Java程序。
2.對Class文件進行加密
為了防止Class文件被直接反編譯,許多開發人員將一些關鍵的Class文件進行加密,例如對注冊碼、序列號管理相關的類等。在使用這些被加密的類之前,程序首先需要對這些類進行解密,而後再將這些類裝載到JVM當中。這些類的解密可以由硬體完成,也可以使用軟體完成。
在實現時,開發人員往往通過自定義ClassLoader類來完成加密類的裝載(注意由於安全性的原因,Applet不能夠支持自定義的ClassLoader)。自定義的ClassLoader首先找到加密的類,而後進行解密,最後將解密後的類裝載到JVM當中。在這種保護方式中,自定義的ClassLoader是非常關鍵的類。由於它本身不是被加密的,因此它可能成為黑客最先攻擊的目標。如果相關的解密密鑰和演算法被攻克,那麼被加密的類也很容易被解密。
3.轉換成本地代碼
將程序轉換成本地代碼也是一種防止反編譯的有效方法。因為本地代碼往往難以被反編譯。開發人員可以選擇將整個應用程序轉換成本地代碼,也可以選擇關鍵模塊轉換。如果僅僅轉換關鍵部分模塊,Java程序在使用這些模塊時,需要使用JNI技術進行調用。當然,在使用這種技術保護Java程序的同時,也犧牲了Java的跨平台特性。對於不同的平台,我們需要維護不同版本的本地代碼,這將加重軟體支持和維護的工作。不過對於一些關鍵的模塊,有時這種方案往往是必要的。為了保證這些本地代碼不被修改和替代,通常需要對這些代碼進行數字簽名。在使用這些本地代碼之前,往往需要對這些本地代碼進行認證,確保這些代碼沒有被黑客更改。如果簽名檢查通過,則調用相關JNI方法。
4.代碼混淆
代碼混淆是對Class文件進行重新組織和處理,使得處理後的代碼與處理前代碼完成相同的功能(語義)。但是混淆後的代碼很難被反編譯,即反編譯後得出的代碼是非常難懂、晦澀的,因此反編譯人員很難得出程序的真正語義。從理論上來說,黑客如果有足夠的時間,被混淆的代碼仍然可能被破解,甚至目前有些人正在研製反混淆的工具。但是從實際情況來看,由於混淆技術的多元化發展,混淆理論的成熟,經過混淆的Java代碼還是能夠很好地防止反編譯。下面我們會詳細介紹混淆技術,因為混淆是一種保護Java程序的重要技術。

『陸』 【轉】如何保護Java代碼

以下從技術角度就常見的保護措施 和常用工具來看看如何有效保護java代碼:1. 將java包裝成exe 特點:將jar包裝成可執行文件,便於使用,但對java程序沒有任何保護。不要以為生成了exe就和普通可執行文件效果一樣了。這些包裝成exe的程序運行時都會將jar文件釋放到臨時目錄,很容易獲取。常用的工具有exe4j、jsmooth、NativeJ等等。jsmooth生成的exe運行時臨時目錄在exe所在目錄中或是用戶臨時目錄 中;exe4j生成的exe運行時臨時目錄在用戶臨時目錄中;NativeJ生成的exe直接用winrar打開,然後用zip格式修復成一個jar文件,就得到了原文件。如果只是為了使用和發布方便,不需要保護java代碼,使用這些工具是很好的選擇。2. java混淆器特點:使用一種或多種處理方式將class文件、java源代碼進行混淆處理後生成新的class,使混淆後的代碼不易被反編譯,而反編譯後的代碼難以閱 讀和理解。這類混淆器工具很多,而且也很有成效。缺點:雖然混淆的代碼反編譯後不易讀懂,但對於有經驗的人或是多花些時間,還是能找到或計算出你代碼中隱藏的敏感內容,而且在很多應用中不是全部代碼都能混淆的,往往一些關鍵的庫、類名、方法名、變數名等因使用要求的限制反而還不能混淆。3. 隔離java程序到服務端特點:把java程序放到服務端,讓用戶不能訪問到class文件和相關配套文件,客戶端只通過介面訪問。這種方式在客戶/服務模式的應用中能較好地保護java代碼。缺點是:必須是客戶/服務模式,這種特點限制了此種方式的使用范圍;客戶端因為邏輯的暴露始終是較為薄弱的環節,所以訪問介面時一般都需要安全性認證。4. java加密保護特點:自定義ClassLoader,將class文件和相關文件加密,運行時由此ClassLoader解密相關文件並裝載類,要起到保護作用必須自定 義本地代碼執行器將自定義ClassLoader和加密解密的相關類和配套文件也保護起來。此種方式能很有效地保護java代碼。缺點:可以通過替換JRE包中與類裝載相關的java類或虛擬機動態庫截獲java位元組碼。 jar2exe屬於這類工具。5. 提前編譯技術(AOT) 特點:將java代碼靜態編譯成本地機器碼,脫離通用JRE。此種方式能夠非常有效地保護java代碼,且程序啟動比通用JVM快一點。具有代表性的是GNU的gcj,可以做到對java代碼完全提前編譯,但gcj存在諸多局限性,如:對JRE 5不能完整支持、不支持JRE 6及以後的版本。由於java平台的復雜性,做到能及時支持最新java版本和JRE的完全提前編譯是非常困難的,所以這類工具往往採取靈活方式,該用即時編譯的地方還是 要用,成為提前編譯和即時編譯的混合體。缺點:由於與通用JRE的差異和java運用中的復雜性,並非java程序中的所有jar都能得到完全的保護;只能使用此種工具提供的一個運行環境,如果工具更新滯後或你需要特定版本的JRE,有可能得不到此種工具的支持。 Excelsior JET屬於這類工具。6. 使用jni方式保護特點:將敏感的方法和數據通過jni方式處理。此種方式和「隔離java程序到服務端」有些類似,可以看作把需要保護的代碼和數據「隔離」到動態庫中,不同的是可以在單機程序中運用。缺點和上述「隔離java程序到服務端」類似。7. 不脫離JRE的綜合方式保護特點:非提前編譯,不脫離JRE,採用多種軟保護方式,從多方面防止java程序被竊取。此種方式由於採取了多種保護措施,比如自定義執行器和裝載器、加密、JNI、安全性檢測、生成可執行文件等等,使保護力度大大增強,同樣能夠非常有效地保護java代碼。缺點:由於jar文件存在方式的改變和java運用中的復雜性,並非java程序中的所有jar都能得到完全的保護;很有可能並不支持所有的JRE版本。 JXMaker屬於此類工具。8. 用加密鎖硬體保護特點:使用與硬體相關的專用程序將java虛擬機啟動程序加殼,將虛擬機配套文件和java程序加密,啟動的是加殼程序,由加殼程序建立一個與硬體相關的 受保護的運行環境,為了加強安全性可以和加密鎖內植入的程序互動。此種方式與以上「不脫離JRE的綜合方式保護」相似,只是使用了專用硬體設備,也能很好地保護java代碼。缺點:有人認為加密鎖用戶使用上不太方便,且每個安裝需要附帶一個。從以上描述中我們可以看出:1. 各種保護方式都有其優缺點,應根據實際選用2. 要更好地保護java代碼應該使用綜合的保護措施3. 單機環境中要真正有效保護java代碼,必須要有本地代碼程序配合當然,安全都是相對的,一方面看你的保護措施和使用的工具能達到的程度,一方面看黑客的意願和能力,不能只從技術上保護知識產權。總之,在java 代碼保護方面可以採取各種可能的方式,不可拘泥於那些條條框框。

『柒』 最新我公司在使用部署一公司的java web應用程序發現他們的所有的class無法反編譯,怎麼做到的

怎麼可能不能反編譯,除非他的代碼不想讓機器運行。
java加密無非是模糊化或者是修改classloader加密。前一種直接反編譯,只是不容易看而已。
後一種先反編譯classloader,研究加密過程,再解密反編譯即可。

『捌』 如何使class文件不被反編譯呢

想不被反編譯是不可能的。混淆器可以吧所有變數名,函數名,類名(系統類,函數名不變)統統用一兩個字母代替,可以縮短代碼長度,並且被反編譯以後難以理解含義增加閱讀難度。

『玖』 javaclass類加密後 如何部署到tomcat

1.使用加密程序對classes下所有文件加密,加密之後所有的class文件後綴變為uikoo9,可以自己修改源代碼
2.將原classes文件夾刪除,將加密後的classes文件夾復制進去
3.修改context.xml
4.tomcat\lib下添加loader.class
5.啟動tomcat!

熱點內容
廣東人社賬號密碼多少 發布:2025-05-10 03:43:11 瀏覽:617
python對象參數 發布:2025-05-10 03:43:11 瀏覽:576
自己伺服器搭建梯子 發布:2025-05-10 03:31:39 瀏覽:574
華為升級包怎麼解壓 發布:2025-05-10 03:18:24 瀏覽:604
c語言以什麼結束 發布:2025-05-10 03:18:22 瀏覽:258
160android 發布:2025-05-10 03:03:30 瀏覽:179
pythonstorage 發布:2025-05-10 02:58:38 瀏覽:501
如何查看電腦配置顯卡參數 發布:2025-05-10 02:37:00 瀏覽:106
證券交易密碼在哪裡修改 發布:2025-05-10 02:31:56 瀏覽:839
javafor是什麼意思 發布:2025-05-10 02:23:09 瀏覽:842