使用ClassLoader对Java源码加解密
//样例
package com.epoch.core.security;
import java.io.*;
import java.security.PublicKey;
import java.security.Signature;
public class DSLoader extends ClassLoader {
private static final byte c[] = {
-84,-19,0,5,115,114,0,20,106,97,
118,97,46,115,101,99,117,114,105,116,
121,46,75,101,121,82,101,112,-67,-7,
79,-77,-120,-102,-91,67,2,0,4,76,
0,9,97,108,103,111,114,105,116,104,
109,116,0,18,76,106,97,118,97,47,
108,97,110,103,47,83,116,114,105,110,
103,59,91,0,7,101,110,99,111,100,
101,100,116,0,2,91,66,76,0,6,
102,111,114,109,97,116,113,0,126,0,
1,76,0,4,116,121,112,101,116,0,
27,76,106,97,118,97,47,115,101,99,
117,114,105,116,121,47,75,101,121,82,
101,112,36,84,121,112,101,59,120,112,
116,0,3,68,83,65,117,114,0,2,
91,66,-84,-13,23,-8,6,8,84,-32,
2,0,0,120,112,0,0,1,-68,48,
-126,1,-72,48,-126,1,44,6,7,42,
-122,72,-50,56,4,1,48,-126,1,31,
2,-127,-127,0,-3,127,83,-127,29,117,
18,41,82,-33,74,-100,46,-20,-28,-25,
-10,17,-73,82,60,-17,68,0,-61,30,
63,-128,-74,81,38,105,69,93,64,34,
81,-5,89,61,-115,88,-6,-65,-59,-11,
-70,48,-10,-53,-101,85,108,-41,-127,59,
-128,29,52,111,-14,102,96,-73,107,-103,
80,-91,-92,-97,-97,-24,4,123,16,34,
-62,79,-69,-87,-41,-2,-73,-58,27,-8,
59,87,-25,-58,-88,-90,21,15,4,-5,
-125,-10,-45,-59,30,-61,2,53,84,19,
90,22,-111,50,-10,117,-13,-82,43,97,
-41,42,-17,-14,34,3,25,-99,-47,72,
1,-57,2,21,0,-105,96,80,-113,21,
35,11,-52,-78,-110,-71,-126,-94,-21,-124,
11,-16,88,28,-11,2,-127,-127,0,-9,
-31,-96,-123,-42,-101,61,-34,-53,-68,-85,
92,54,-72,87,-71,121,-108,-81,-69,-6,
58,-22,-126,-7,87,76,11,61,7,-126,
103,81,89,87,-114,-70,-44,89,79,-26,
113,7,16,-127,-128,-76,73,22,113,35,
-24,76,40,22,19,-73,-49,9,50,-116,
-56,-90,-31,60,22,122,-117,84,124,-115,
40,-32,-93,-82,30,43,-77,-90,117,-111,
110,-93,127,11,-6,33,53,98,-15,-5,
98,122,1,36,59,-52,-92,-15,-66,-88,
81,-112,-119,-88,-125,-33,-31,90,-27,-97,
6,-110,-117,102,94,-128,123,85,37,100,
1,76,59,-2,-49,73,42,3,-127,-123,
0,2,-127,-127,0,-71,-5,-67,29,36,
122,97,-81,-108,-91,84,-121,-6,-4,32,
-80,-9,32,-20,-128,-95,-2,-22,-17,-18,
39,104,-99,-55,108,-51,-59,44,76,-90,
-1,-68,-72,32,72,-21,-41,-74,45,1,
-54,-81,4,-98,49,-53,79,-58,-110,57,
27,122,40,-113,-25,-8,12,40,-16,123,
94,-118,-58,88,-12,120,68,117,48,-46,
-87,-71,16,-114,-103,-20,-102,116,69,-8,
-128,60,103,27,-116,-36,-25,-102,-102,-21,
108,-54,-11,-93,51,121,-87,-35,-111,105,
-79,89,-21,97,127,-117,-29,79,109,18,
73,120,10,-26,-25,-114,-64,-116,-67,57,
3,-17,-17,116,0,5,88,46,53,48,
57,126,114,0,25,106,97,118,97,46,
115,101,99,117,114,105,116,121,46,75,
101,121,82,101,112,36,84,121,112,101,
0,0,0,0,0,0,0,0,18,0,
0,120,114,0,14,106,97,118,97,46,
108,97,110,103,46,69,110,117,109,0,
0,0,0,0,0,0,0,18,0,0,
120,112,116,0,6,80,85,66,76,73,
67
};
static Class a;
private static DSLoader d;
private static PublicKey e;
public DSLoader(ClassLoader classloader) {
super(classloader);
}
public DSLoader() {
}
static final Class a(String s) {
try {
return Class.forName(s);
} catch (ClassNotFoundException ex) {
throw new NoClassDefFoundError(ex.getMessage());
}
}
public static synchronized Class getClass(String s) {
if (d == null)
d = new DSLoader((a != null ? a
: (a = a("com.epoch.core.security.DSLoader")))
.getClassLoader());
try {
return d.load(s,true);
} catch (ClassNotFoundException ex) {
throw new NoClassDefFoundError(ex.getMessage());
}
}
private static PublicKey a() throws IOException, ClassNotFoundException {
if (e == null) {
ObjectInputStream in = new ObjectInputStream(
new BufferedInputStream(new ByteArrayInputStream(c)));
e = (PublicKey)in.readObject();
in.close();
}
return e;
}
protected synchronized Class load(String s,boolean resolve) throws ClassNotFoundException {
try {
ClassLoader classloader;
classloader = (a != null ? a
: (a = a("com.epoch.core.security.DSLoader")))
.getClassLoader();
Object obj = null;
Class clazz;
if ((clazz = findLoadedClass(s)) != null)
return clazz;
String s1 = s.replace('.', '/').concat(".class");
ObjectInputStream objectinputstream;
byte abyte0[] = (byte[]) (objectinputstream = new ObjectInputStream(
classloader.getResourceAsStream(s1))).readObject();
byte abyte1[] = (byte[]) objectinputstream.readObject();
objectinputstream.close();
if (abyte0 != null && abyte1 != null) {
PublicKey publickey = a();
String s2;
Signature signature;
(signature = Signature.getInstance(s2 = new String(new byte[] {
68, 83, 65 }))).initVerify(publickey);//DSA
signature.update(abyte0);
if (signature.verify(abyte1)){
clazz = defineClass(s, abyte0, 0, abyte0.length);
}
}
// 必需的步骤2:如果上面没有成功
// 我们尝试用默认的ClassLoader装入它
if (clazz == null)
clazz = findSystemClass(s);
// 必需的步骤3:如有必要,则装入相关的类
if (resolve && clazz != null)
resolveClass( clazz );
return clazz;
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
}
}
//=====================================================================================
package com.epoch.core.security;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.security.*;
import com.epoch.core.util.FileUtil;
public class DSManager {
private static final byte c[] = {
-84,-19,0,5,115,114,0,20,106,97,
118,97,46,115,101,99,117,114,105,116,
121,46,75,101,121,82,101,112,-67,-7,
79,-77,-120,-102,-91,67,2,0,4,76,
0,9,97,108,103,111,114,105,116,104,
109,116,0,18,76,106,97,118,97,47,
108,97,110,103,47,83,116,114,105,110,
103,59,91,0,7,101,110,99,111,100,
101,100,116,0,2,91,66,76,0,6,
102,111,114,109,97,116,113,0,126,0,
1,76,0,4,116,121,112,101,116,0,
27,76,106,97,118,97,47,115,101,99,
117,114,105,116,121,47,75,101,121,82,
101,112,36,84,121,112,101,59,120,112,
116,0,3,68,83,65,117,114,0,2,
91,66,-84,-13,23,-8,6,8,84,-32,
2,0,0,120,112,0,0,1,-68,48,
-126,1,-72,48,-126,1,44,6,7,42,
-122,72,-50,56,4,1,48,-126,1,31,
2,-127,-127,0,-3,127,83,-127,29,117,
18,41,82,-33,74,-100,46,-20,-28,-25,
-10,17,-73,82,60,-17,68,0,-61,30,
63,-128,-74,81,38,105,69,93,64,34,
81,-5,89,61,-115,88,-6,-65,-59,-11,
-70,48,-10,-53,-101,85,108,-41,-127,59,
-128,29,52,111,-14,102,96,-73,107,-103,
80,-91,-92,-97,-97,-24,4,123,16,34,
-62,79,-69,-87,-41,-2,-73,-58,27,-8,
59,87,-25,-58,-88,-90,21,15,4,-5,
-125,-10,-45,-59,30,-61,2,53,84,19,
90,22,-111,50,-10,117,-13,-82,43,97,
-41,42,-17,-14,34,3,25,-99,-47,72,
1,-57,2,21,0,-105,96,80,-113,21,
35,11,-52,-78,-110,-71,-126,-94,-21,-124,
11,-16,88,28,-11,2,-127,-127,0,-9,
-31,-96,-123,-42,-101,61,-34,-53,-68,-85,
92,54,-72,87,-71,121,-108,-81,-69,-6,
58,-22,-126,-7,87,76,11,61,7,-126,
103,81,89,87,-114,-70,-44,89,79,-26,
113,7,16,-127,-128,-76,73,22,113,35,
-24,76,40,22,19,-73,-49,9,50,-116,
-56,-90,-31,60,22,122,-117,84,124,-115,
40,-32,-93,-82,30,43,-77,-90,117,-111,
110,-93,127,11,-6,33,53,98,-15,-5,
98,122,1,36,59,-52,-92,-15,-66,-88,
81,-112,-119,-88,-125,-33,-31,90,-27,-97,
6,-110,-117,102,94,-128,123,85,37,100,
1,76,59,-2,-49,73,42,3,-127,-123,
0,2,-127,-127,0,-71,-5,-67,29,36,
122,97,-81,-108,-91,84,-121,-6,-4,32,
-80,-9,32,-20,-128,-95,-2,-22,-17,-18,
39,104,-99,-55,108,-51,-59,44,76,-90,
-1,-68,-72,32,72,-21,-41,-74,45,1,
-54,-81,4,-98,49,-53,79,-58,-110,57,
27,122,40,-113,-25,-8,12,40,-16,123,
94,-118,-58,88,-12,120,68,117,48,-46,
-87,-71,16,-114,-103,-20,-102,116,69,-8,
-128,60,103,27,-116,-36,-25,-102,-102,-21,
108,-54,-11,-93,51,121,-87,-35,-111,105,
-79,89,-21,97,127,-117,-29,79,109,18,
73,120,10,-26,-25,-114,-64,-116,-67,57,
3,-17,-17,116,0,5,88,46,53,48,
57,126,114,0,25,106,97,118,97,46,
115,101,99,117,114,105,116,121,46,75,
101,121,82,101,112,36,84,121,112,101,
0,0,0,0,0,0,0,0,18,0,
0,120,114,0,14,106,97,118,97,46,
108,97,110,103,46,69,110,117,109,0,
0,0,0,0,0,0,0,18,0,0,
120,112,116,0,6,80,85,66,76,73,
67
};
public static boolean generatekey() {
try {
KeyPairGenerator keygen = KeyPairGenerator.getInstance("DSA");
keygen.initialize(1024);
KeyPair keys = keygen.genKeyPair();
PublicKey pubKey = keys.getPublic();
PrivateKey priKey = keys.getPrivate();
ObjectOutputStream out = new ObjectOutputStream(
new FileOutputStream("myprikey.dat"));
out.writeObject(priKey);
out.close();
out = new ObjectOutputStream(new FileOutputStream("mypubkey.dat"));
out.writeObject(pubKey);
out.close();
byte[] pubs = FileUtil.getFileBytes("mypubkey.dat");
StringBuffer sb = new StringBuffer();
for(int i=0;i<pubs.length;i++){
if(i>0 && i%10==0)
sb.append("\n");
sb.append(pubs[i]+",");
}
FileUtil.createFile("mypubkey.txt",sb.toString().length()>0?
sb.toString().substring(0,sb.toString().length()-1):"");
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public static void generateSign(String src,String obj){
try {
ObjectInputStream in = new ObjectInputStream(new FileInputStream("myprikey.dat"));
PrivateKey priKey = (PrivateKey) in.readObject();
in.close();
byte[] plan = FileUtil.getFileBytes(src); //要签名的信息
//用私钥对信息生成数字签名
Signature signet = Signature.getInstance("DSA");
signet.initSign(priKey);
signet.update(plan);
byte[] signed = signet.sign(); //对信息的数字签名
//把信息和数字签名保存在一个文件中
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(obj));
out.writeObject(plan);
out.writeObject(signed);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void checkSign(String name){
try {
ObjectInputStream in = (ObjectInputStream)new ObjectInputStream(
new ByteArrayInputStream(c));
PublicKey pubKey = (PublicKey) in.readObject();
in.close();
in = new ObjectInputStream(new FileInputStream(name));
byte[] bytes0 = (byte[]) in.readObject();
byte[] bytes1 = (byte[]) in.readObject();
in.close();
Signature signature = Signature.getInstance("DSA");
signature.initVerify(pubKey);
signature.update(bytes0);
if (signature.verify(bytes1)) {
System.out.println("签名正常");
} else
System.out.println("非签名正常");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
if(args.length<1)return;
if(args[0].equalsIgnoreCase("key")){
if((args.length>1 && (args[1].equalsIgnoreCase("y") || args[1].equalsIgnoreCase("yes"))
|| ((new File("myprikey.dat")).exists() == false))) {
if (generatekey() == false) {
System.out.println("生成密钥对败");
return;
}
}
return ;
}
if(args[0].equalsIgnoreCase("sign")){
generateSign("d:/com/test/DSTest.class",
"d:/com/test/DSTest.class");
}
if(args[0].equalsIgnoreCase("check")){
checkSign("d:/com/test/DSTest.class");
}
}
}
//==============================================================================
package com.test;
public interface T {
public void test(String str);
}
//===============================================================================
package com.test;
public class DSTest implements T{
public void test(String str){
System.out.println("coming::"+str);
}
public static void main(String[] args) {
new DSTest().test("test");
}
}
//==============================================================================
package com.epoch.core.security;
import com.test.T;
public class Test {
public void test(){
try{
T a = (T)( DSLoader.getClass("com.test.DSTest")).newInstance();
a.test("hello world");
}catch(Exception ex){
ex.printStackTrace();
}
}
public static void main(String[] args){
new Test().test();
}
}
上一篇: 感觉比较漂亮的系统下拉式菜单
下一篇: 在线HTML编辑器
推荐阅读
-
【java】本地客户端内嵌浏览器3 - Swing 使用 Spring 框架 + 打包项目 + 转exe + 源码
-
对Web中的Action使用反射与否影响不大 博客分类: Java WebJDKXP软件测试C
-
对Web中的Action使用反射与否影响不大 博客分类: Java WebJDKXP软件测试C
-
PHP:使用Zend对源码加密、Zend Guard安装以及Zend Guard Run-time support mi_PHP教程
-
Java使用正则表达式对注册页面进行验证功能实现
-
在java中对LIst集合的两种排序方法(即sort的使用方法)
-
基于spring-boot和docker-java实现对docker容器的动态管理和监控功能[附完整源码下载]
-
学以致用——Java源码——使用多态输出平面及立体几何图形的面积和体积(Project: Shape Hierarchy)
-
【MySQL 05】使用Java对MySQL进行操作(创建数据库)
-
PHP:使用Zend对源码加密、Zend Guard安装以及Zend Guard Run-time support mi_PHP教程