最近在研究JAVA CLASS LOADING技術(shù),已實(shí)現(xiàn)了一個(gè)自定義的加載器。對(duì)目前自定義加載器的應(yīng)用,還在探討中。下面是自定義的CLASSLOADER在JAVA加密解密方面的一些研究。
JAVA安全
JAVA是解釋執(zhí)行的語言,對(duì)于不同的操作平臺(tái)都有相應(yīng)的JVM對(duì)字節(jié)碼文件進(jìn)行解釋執(zhí)行。而這個(gè)字節(jié)碼文件,也就是我們平時(shí)所看到的每一個(gè).class文件。
這是我們大家都知道的常識(shí),也就是由.java文件,經(jīng)過編譯器編譯,變成JVM所能解釋的.class文件。
而這個(gè)過程,在現(xiàn)在公開的網(wǎng)絡(luò)技術(shù)中,利用一個(gè)反編譯器,任何人都可以很容易的獲取它的源文件。這對(duì)于很多人來說是不希望看到的。
對(duì)于加密解密技術(shù),我懂的不多,有些可以利用某種技術(shù)“模糊”JAVA類文件。這樣能夠使反編譯的難度增加。但估計(jì)反編譯器的技術(shù)水平也在不斷提升,導(dǎo)致這種方法層層受阻。另外還有很多其他的技術(shù)也可以實(shí)現(xiàn)對(duì)JAVA文件的加密解密。我現(xiàn)在所想要研究的,就是其中的一種。
JAVA的靈活性使反編譯變得容易,同時(shí),也讓我們的加密解密的方法變得靈活。
利用自定義的CLASSLOADER
參照:http://www.aygfsteel.com/realsmy/archive/2007/04/18/111582.html
JAVA中的每一個(gè)類都是通過類加載器加載到內(nèi)存中的。對(duì)于類加載器的工作流程如下表示:
1.searchfile()
找到我所要加載的類文件。(拋除JAR包的概念,現(xiàn)在只是要加載一個(gè).class文件)
2.loadDataClass()
讀取這個(gè)類文件的字節(jié)碼。
3.difineClass()
加載類文件。(加載的過程其實(shí)很復(fù)雜,我們現(xiàn)在先不研究它。)
從這個(gè)過程中我們能很清楚的發(fā)現(xiàn),自定義的類加載能夠很輕松的控制每個(gè)類文件的加載過程。這樣在第二步(loadDataClass)和第三步(difineClass)之間,我們將會(huì)有自己的空間靈活的控制這個(gè)過程。
我們加密解密的技術(shù)就應(yīng)用到這里。
加密解密
JAVA加密解密的技術(shù)有很多。JAVA自己提供了良好的類庫(kù)對(duì)各種算法進(jìn)行支持。對(duì)于采用哪種算法,網(wǎng)絡(luò)上說法不一,自己去GOOGLE一下吧。
下面用DES對(duì)稱加密算法(設(shè)定一個(gè)密鑰,然后對(duì)所有的數(shù)據(jù)進(jìn)行加密)來簡(jiǎn)單舉個(gè)例子。
首先,生成一個(gè)密鑰KEY。
我把它保存到key.txt中。這個(gè)文件就象是一把鑰匙。誰擁有它,誰就能解開我們的類文件。代碼參考如下:
package com.neusoft.jiami;

import java.io.File;
import java.io.FileOutputStream;
import java.security.SecureRandom;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;


class Key
{

private String keyName;


public Key(String keyName)
{
this.keyName = keyName;
}


public void createKey(String keyName) throws Exception
{

// 創(chuàng)建一個(gè)可信任的隨機(jī)數(shù)源,DES算法需要
SecureRandom sr = new SecureRandom();
// 用DES算法創(chuàng)建一個(gè)KeyGenerator對(duì)象
KeyGenerator kg = KeyGenerator.getInstance("DES");
// 初始化此密鑰生成器,使其具有確定的密鑰長(zhǎng)度
kg.init(sr);
// 生成密匙
SecretKey key = kg.generateKey();
// 獲取密鑰數(shù)據(jù)
byte rawKeyData[] = key.getEncoded();
// 將獲取到密鑰數(shù)據(jù)保存到文件中,待解密時(shí)使用
FileOutputStream fo = new FileOutputStream(new File(keyName));
fo.write(rawKeyData);
}


public static void main(String args[])
{

try
{
new Key("key.txt");

} catch (Exception e)
{
e.printStackTrace();
}

}
}
package com.neusoft.jiami;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;


public class JiaMi
{


public static void main(String[] args) throws Exception
{

// DES算法要求有一個(gè)可信任的隨機(jī)數(shù)源
SecureRandom sr = new SecureRandom();
// 獲得密匙數(shù)據(jù)
FileInputStream fi = new FileInputStream(new File("key.txt"));
byte rawKeyData[] = new byte[fi.available()];
fi.read(rawKeyData);
fi.close();
// 從原始密匙數(shù)據(jù)創(chuàng)建DESKeySpec對(duì)象
DESKeySpec dks = new DESKeySpec(rawKeyData);
// 創(chuàng)建一個(gè)密匙工廠,然后用它把DESKeySpec轉(zhuǎn)換成一個(gè)SecretKey對(duì)象
SecretKey key = SecretKeyFactory.getInstance("DES").generateSecret(dks);
// Cipher對(duì)象實(shí)際完成加密操作
Cipher cipher = Cipher.getInstance("DES");
// 用密匙初始化Cipher對(duì)象
cipher.init(Cipher.ENCRYPT_MODE, key, sr);
// 現(xiàn)在,獲取要加密的文件數(shù)據(jù)
FileInputStream fi2 = new FileInputStream(new File("DigestPass.class"));
byte data[] = new byte[fi2.available()];
fi2.read(data);
fi2.close();
// 正式執(zhí)行加密操作
byte encryptedData[] = cipher.doFinal(data);
// 用加密后的數(shù)據(jù)覆蓋原文件
FileOutputStream fo = new FileOutputStream(new File("DigestPass.class"));
fo.write(encryptedData);
fo.close();
}
}
第三步,用自定義的CLASSLOADER進(jìn)行加載。參考代碼如下:
package com.neusoft.jiami;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import com.neusoft.classloader.MyClassLoader;


public class JieMi
{


public static void main(String[] args) throws Exception
{

// DES算法要求有一個(gè)可信任的隨機(jī)數(shù)源
SecureRandom sr = new SecureRandom();
// 獲得密匙數(shù)據(jù)
FileInputStream fi = new FileInputStream(new File("key.txt"));
byte rawKeyData[] = new byte[fi.available()];// = new byte[5];
fi.read(rawKeyData);
fi.close();
// 從原始密匙數(shù)據(jù)創(chuàng)建一個(gè)DESKeySpec對(duì)象
DESKeySpec dks = new DESKeySpec(rawKeyData);
// 創(chuàng)建一個(gè)密匙工廠,然后用它把DESKeySpec對(duì)象轉(zhuǎn)換成一個(gè)SecretKey對(duì)象
SecretKey key = SecretKeyFactory.getInstance("DES").generateSecret(dks);
// Cipher對(duì)象實(shí)際完成解密操作
Cipher cipher = Cipher.getInstance("DES");
// 用密匙初始化Cipher對(duì)象
cipher.init(Cipher.DECRYPT_MODE, key, sr);
// 現(xiàn)在,獲取數(shù)據(jù)并解密
FileInputStream fi2 = new FileInputStream(new File("DigestPass.class"));
byte encryptedData[] = new byte[fi2.available()];
fi2.read(encryptedData);
fi2.close();
// 正式執(zhí)行解密操作
byte decryptedData[] = cipher.doFinal(encryptedData);
// 這時(shí)把數(shù)據(jù)還原成原有的類文件
// FileOutputStream fo = new FileOutputStream(new
// File("DigestPass.class"));
// fo.write(decryptedData);
// 用解密后的數(shù)據(jù)加載類并應(yīng)用
MyClassloader mcl = new MyClassloader("E:/");
Class cl = mcl.loadClass(decryptedData, "com.neusoft.jiami.DigestPass");
DigestPass dp = cl.newInstance();
}
}
這樣,我們就完成了類的加密解密。這個(gè)過程留給我們修改的空間還很多。我也在理解過程中。
總結(jié)
自定義的類加載器能夠靈活的控制類的加載過程。從而可以實(shí)現(xiàn)一些我們所要的功能。
但是,即使是這樣的加密技術(shù),對(duì)于某些高手來說,依然是脆弱的。我們所需要做的就是,理解這其中的過程,掌握這樣的技術(shù),最終能夠應(yīng)用到我們自己的實(shí)際項(xiàng)目中來。
JAVA安全
JAVA是解釋執(zhí)行的語言,對(duì)于不同的操作平臺(tái)都有相應(yīng)的JVM對(duì)字節(jié)碼文件進(jìn)行解釋執(zhí)行。而這個(gè)字節(jié)碼文件,也就是我們平時(shí)所看到的每一個(gè).class文件。
這是我們大家都知道的常識(shí),也就是由.java文件,經(jīng)過編譯器編譯,變成JVM所能解釋的.class文件。
而這個(gè)過程,在現(xiàn)在公開的網(wǎng)絡(luò)技術(shù)中,利用一個(gè)反編譯器,任何人都可以很容易的獲取它的源文件。這對(duì)于很多人來說是不希望看到的。
對(duì)于加密解密技術(shù),我懂的不多,有些可以利用某種技術(shù)“模糊”JAVA類文件。這樣能夠使反編譯的難度增加。但估計(jì)反編譯器的技術(shù)水平也在不斷提升,導(dǎo)致這種方法層層受阻。另外還有很多其他的技術(shù)也可以實(shí)現(xiàn)對(duì)JAVA文件的加密解密。我現(xiàn)在所想要研究的,就是其中的一種。
JAVA的靈活性使反編譯變得容易,同時(shí),也讓我們的加密解密的方法變得靈活。
利用自定義的CLASSLOADER
參照:http://www.aygfsteel.com/realsmy/archive/2007/04/18/111582.html
JAVA中的每一個(gè)類都是通過類加載器加載到內(nèi)存中的。對(duì)于類加載器的工作流程如下表示:
1.searchfile()
找到我所要加載的類文件。(拋除JAR包的概念,現(xiàn)在只是要加載一個(gè).class文件)
2.loadDataClass()
讀取這個(gè)類文件的字節(jié)碼。
3.difineClass()
加載類文件。(加載的過程其實(shí)很復(fù)雜,我們現(xiàn)在先不研究它。)
從這個(gè)過程中我們能很清楚的發(fā)現(xiàn),自定義的類加載能夠很輕松的控制每個(gè)類文件的加載過程。這樣在第二步(loadDataClass)和第三步(difineClass)之間,我們將會(huì)有自己的空間靈活的控制這個(gè)過程。
我們加密解密的技術(shù)就應(yīng)用到這里。
加密解密
JAVA加密解密的技術(shù)有很多。JAVA自己提供了良好的類庫(kù)對(duì)各種算法進(jìn)行支持。對(duì)于采用哪種算法,網(wǎng)絡(luò)上說法不一,自己去GOOGLE一下吧。
下面用DES對(duì)稱加密算法(設(shè)定一個(gè)密鑰,然后對(duì)所有的數(shù)據(jù)進(jìn)行加密)來簡(jiǎn)單舉個(gè)例子。
首先,生成一個(gè)密鑰KEY。
我把它保存到key.txt中。這個(gè)文件就象是一把鑰匙。誰擁有它,誰就能解開我們的類文件。代碼參考如下:






















































第二步,對(duì)我們所要進(jìn)行加密的類文件進(jìn)行加密。
比如我有一個(gè)DigestPass類,已經(jīng)被正常編譯好生成DigestPass.class文件。此時(shí),這個(gè)類文件是任何人都可以用的。因?yàn)橄到y(tǒng)的類加載器可以自動(dòng)的加載它。那么下一步,我們要做的就是把這個(gè)類文件加密。使系統(tǒng)的類加載器無法讀取到正確的字節(jié)碼文件。參考代碼如下:
















































第三步,用自定義的CLASSLOADER進(jìn)行加載。參考代碼如下:





















































這樣,我們就完成了類的加密解密。這個(gè)過程留給我們修改的空間還很多。我也在理解過程中。
總結(jié)
自定義的類加載器能夠靈活的控制類的加載過程。從而可以實(shí)現(xiàn)一些我們所要的功能。
但是,即使是這樣的加密技術(shù),對(duì)于某些高手來說,依然是脆弱的。我們所需要做的就是,理解這其中的過程,掌握這樣的技術(shù),最終能夠應(yīng)用到我們自己的實(shí)際項(xiàng)目中來。
歡迎來訪!^.^!
本BLOG僅用于個(gè)人學(xué)習(xí)交流!
目的在于記錄個(gè)人成長(zhǎng).
所有文字均屬于個(gè)人理解.
如有錯(cuò)誤,望多多指教!不勝感激!