总结加密、机密jar中的class
1、加密和解密部署到jboss中间件中的的单个class文件,原理:使用“java源程序加密解决方案(基于Classloader解密) (2014-07-13 11:31)”blog即可实现;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
//加密class文件
public class EncryptionClass {
public static void main(String[] args) throws Exception{
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:/Program Files/jboss-4.0.5.GA/server/default/deploy/icmp.war/WEB-INF/classes/com/zzst/application/meeting/mcu/operate/rmx2000/RMX2000Sender2.class"));
byte[] data = new byte[bis.available()];
bis.read(data);
bis.close();
for(int i = 0; i < data.length; i++){
data[i] =(byte)( data[i] + 1);
}
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:/Program Files/jboss-4.0.5.GA/server/default/deploy/icmp.war/WEB-INF/classes/com/zzst/application/meeting/mcu/operate/rmx2000/RMX2000Sender2.class"));
bos.write(data);
bos.close();
}
}
package com.zzst.application.mcuUtil.test;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
public class MyClassLoader extends NetworkClassLoader{
String classpath;
Map<String, Class> loadedClassPool = new HashMap<String, Class>();
public MyClassLoader(String classpath) {
this.classpath = classpath;
}
public MyClassLoader(String classpath, String otherBaseURL) {
this.classpath = classpath;
setBaseUrl(otherBaseURL);
}
@SuppressWarnings("unchecked")
@Override
public synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
Class claz = null;
if (loadedClassPool.containsKey(name)) {
claz = this.loadedClassPool.get(name);
} else {
try {
if (claz == null) {
claz = super.loadClass(name, false);
if (claz != null) {
System.out.println("系统加载成功:" + name);
}
}
} catch (ClassNotFoundException e) {
System.out.println("系统无法加载:" + name);
}
try {
if (claz == null) {
//解密RMX2000Sender2.class文件,然后再加载成Class
if(name.equals("com.zzst.application.meeting.mcu.operate.rmx2000.RMX2000Sender2")){
try{
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(classNameToPath(name)));
byte[] data = new byte[bis.available()];
bis.read(data);
bis.close();
for(int i = 0; i < data.length; i++){
data[i] =(byte)( data[i] - 1);
}
//Class claz = defineClass(“Hello”, data, 0, data.length);
System.out.println("============my class loader===============" + "com.zzst.application.meeting.mcu.operate.rmx2000.RMX2000Sender2");
claz = defineClass(name, data, 0, data.length);
}catch(Exception e){
e.printStackTrace();
}
}
if (claz != null) {
System.out.println("自定义解密 加载成功:" + name);
}
}
} catch (Exception e) {
System.out.println("自定义解密 无法加载:" + name);
}
try {
if (claz == null) {
claz = findClass(name);
if (claz != null) {
System.out.println("lib 系统加载成功:" + name);
}
}
} catch (ClassNotFoundException e) {
System.out.println("lib 系统无法加载:" + name);
}
try {
if (claz == null) {
claz = loadByCjClassLoader(name);
if (claz != null) {
System.out.println("自定义加载成功:" + name);
}
}
} catch (Exception e) {
System.out.println("自定义无法加载:" + name);
}
if (claz != null) {
this.loadedClassPool.put(name, claz);
}
}
if (resolve) {
resolveClass(claz);
}
return claz;
}
/**
*
* 解密加载
*
*
* @param name
* @return
*/
@SuppressWarnings("unchecked")
private Class loadByCjClassLoader(String name) {
Class claz = null;
try {
byte[] rawData = loadClassData(name);
if (rawData != null) {
/* 临时不解密
byte[] classData = decrypt(getReverseCypher(this.cjcipher.getKeycode()), rawData);
classData = CipherUtil.filter(classData, this.cjcipher);
*/
byte[] classData = rawData;
claz = defineClass(name, classData, 0, classData.length);
}
} catch (Exception e) {
e.printStackTrace();
claz = null;
}
return claz;
}
private byte[] loadClassData(String className) {
String path = classNameToPath(className);
try{
InputStream ins = new FileInputStream(path);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int bufferSize = 4096;
byte[] buffer = new byte[bufferSize];
int bytesNumRead = 0;
while ((bytesNumRead = ins.read(buffer)) != -1) {
baos.write(buffer, 0, bytesNumRead);
}
return baos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private String classNameToPath(String className){
return classpath + File.separatorChar + className.replace('.', File.separatorChar) + ".class";
}
}
2、加密jar包中class文件:可采用先加密硬盘上的class文件,然后手动替换jar包中相同的class文件即可实现;
加载第三方jar包中的class,可以通过继承URLClassLoader来实现;在应用程序中,如果想先解密jar包中的class文件,然后再加载的话,同样也可使用URLClassLoader类中的方法:
package com.zzst.action.meeting.meeting;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLStreamHandlerFactory;
import java.security.AccessController;
import java.security.CodeSigner;
import java.security.CodeSource;
import java.security.PermissionCollection;
import java.security.PrivilegedExceptionAction;
import java.util.Enumeration;
import java.util.jar.Manifest;
import sun.misc.Resource;
import sun.misc.URLClassPath;
public class NetworkClassLoader extends URLClassLoader {
String baseUrl;
private URLClassPath myucp;
public String getBaseUrl() {
return baseUrl;
}
public void setBaseUrl(String baseUrl) {
this.baseUrl = baseUrl;
}
public NetworkClassLoader(){
this(new URL[]{});
}
/**
* URL 以'/'结尾的为目录
* 否则为jar包
* 未指定其父类加载器为系统类加载器
* @param urls
*/
public NetworkClassLoader(URL[] urls) {
super(urls);
myucp = new URLClassPath(urls);
}
/**
* 同上,指定classLoader
* @param urls
* @param parent
*/
public NetworkClassLoader(URL[] urls, ClassLoader parent) {
super(urls,parent);
}
/**
* 同上,URL工厂处理器
* @param urls
* @param parent
* @param factory
*/
public NetworkClassLoader(URL[] urls, ClassLoader parent,
URLStreamHandlerFactory factory) {
super(urls,parent,factory);
}
/**
* [添加baseUrl]
* @param url
*/
public void addURL(String url){
URL uurl=null;
try {
uurl = new URL(baseUrl+url);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
addURL(uurl);
}
/**
* 添加url[添加baseUrl]
*/
protected void addURL(URL url) {
super.addURL(url);
myucp.addURL(url);
}
/**
* 返回urls
*/
public URL[] getURLs() {
return super.getURLs();
}
/**
* 查找类对象
* 从以上的URLS中查找加载当前类对象[会打开所有的jars去查找指定的类]
* (可以通过调用findClass来得到以上URL加载包中的类)
*/
public Class<?> findClass(String name) throws ClassNotFoundException {
//return super.findClass(name);
return myFindClass(name);
}
/**
*此方法是从URLClassLoader类中拷贝出来的,用于读取第三方jar包中的class文件。
*/
protected Class<?> myFindClass(final String name)
throws ClassNotFoundException
{
try {
return (Class)
AccessController.doPrivileged(new PrivilegedExceptionAction() {
public Object run() throws ClassNotFoundException {
String path = name.replace('.', '/').concat(".class");
Resource res = myucp.getResource(path, false);
if (res != null) {
try {
return defineClass(name, res);
} catch (IOException e) {
throw new ClassNotFoundException(name, e);
}
} else {
throw new ClassNotFoundException(name);
}
}
}, AccessController.getContext());
} catch (java.security.PrivilegedActionException pae) {
throw (ClassNotFoundException) pae.getException();
}
}
private Class defineClass(String name, Resource res) throws IOException {
int i = name.lastIndexOf('.');
URL url = res.getCodeSourceURL();
if (i != -1) {
String pkgname = name.substring(0, i);
// Check if package already loaded.
Package pkg = getPackage(pkgname);
Manifest man = res.getManifest();
if (pkg != null) {
// Package found, so check package sealing.
if (pkg.isSealed()) {
// Verify that code source URL is the same.
if (!pkg.isSealed(url)) {
throw new SecurityException(
"sealing violation: package " + pkgname + " is sealed");
}
} else {
// Make sure we are not attempting to seal the package
}
} else {
if (man != null) {
definePackage(pkgname, man, url);
} else {
definePackage(pkgname, null, null, null, null, null, null, null);
}
}
}
// Now read the class bytes and define the class
java.nio.ByteBuffer bb = res.getByteBuffer();
if (bb != null) {
// Use (direct) ByteBuffer:
CodeSigner[] signers = res.getCodeSigners();
CodeSource cs = new CodeSource(url, signers);
return defineClass(name, bb, cs);
} else {
byte[] b = res.getBytes();
System.out.println(name);
//解密zzmcufv.jar中的RMX2000Sender2.class文件,然后在加载成class
if(name.equals("com.zzst.application.meeting.mcu.operate.rmx2000.RMX2000Sender2")){
for(int j = 0; j < b.length; j++){
b[j] =(byte)( b[j] - 1);
}
}
// must read certificates AFTER reading bytes.
CodeSigner[] signers = res.getCodeSigners();
CodeSource cs = new CodeSource(url, signers);
return defineClass(name, b, 0, b.length, cs);
}
}
/**
* 查找资源[自定义相对URL查找路径]
* 从以上的URLS中查找当前名称的资源
* 这个必须重写,因为是public 哈哈
*/
public URL findResource(String name) {
URL url = null;
try {
url = new URL(baseUrl+name);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return url;
}
/**
* 查找资源列表[URL查找路径]
*/
public Enumeration<URL> findResources(String name) throws IOException {
return super.findResources(name);
}
/**
* 在当前的ClassLoader中,定义一个新的Package,Package的属性由Manifest指定.这个包的源文件
*/
protected Package definePackage(String name, Manifest man, URL url)
throws IllegalArgumentException {
return super.definePackage(name, man, url);
}
/**
* 加载路径权限
*/
protected PermissionCollection getPermissions(CodeSource codesource) {
return super.getPermissions(codesource);
}
}
在业务代码中可以这么调用:
NetworkClassLoader loader = new NetworkClassLoader();
loader.setBaseUrl("file:///D:\\Program Files\\jboss-4.0.5.GA\\server\\default\\deploy\\icmp.war\\WEB-INF\\lib\\");
loader.addURL("comm.jar");
loader.addURL("dom4j-1.6.1.jar");
loader.addURL("log4j.jar");
loader.addURL("commons-io-1.3.2.jar");
loader.addURL("commons-logging-1.0.4.jar");
loader.addURL("zzmcufv.jar");
try {
Class clazz= loader.findClass("com.zzst.application.meeting.mcu.operate.rmx2000.RMX2000Sender2");
System.out.println(clazz.getName());
Method taskMethod = clazz.getMethod("sendPost", String.class, String.class);//然后我们就可以用反射
Object o = taskMethod.invoke(null,"http://10.1.6.30", "abcdefg");
System.out.println("info:\n" + (String)o); //String类型对象由同一个父类加载器生成,所以,大家都能使用!
} catch (Exception e) {
e.printStackTrace();
}
总结加密、机密jar中的class的更多相关文章
- application.properties多环境配置文件、jar包外部配置文件、配置项加密、程序中配置使用
一.简介 spring boot项目application.properties文件存放及使用介绍 二.方法一多环境配置文件 我们一般都会有多个应用环境,开发环境.测试环境.生产环境,各个环境的配置会 ...
- Java ClassLoader基础及加载不同依赖 Jar 中的公共类
转载自:最新内容及最清晰格式请见 http://www.trinea.cn/android/java-loader-common-class/ 本文主要介绍 ClassLoader 的基础知识,Cla ...
- 修改jar中的class文件
在工作中有可能会遇到需要修改jar的情况.正常情况下,如果有源代码的话,就比较容易,直接修改源代码,再导出新的jar文件即可.但是如果没有源代码就比较麻烦了,下面记录了没有源代码的情况修改jar的方法 ...
- java中文件的相对路径以及jar中文件的读取
Java中File类的构造函数需要我们传入一个pathname,当我们传入以"/"开头的pathname表示绝对路径,其他均表示相对路径. 一:绝对路径名:是完整的路径名,不需要任 ...
- springmvc获取jar中的静态资源与jar包中的资源互相引用问题
1.首先看jar中的文件位置 2.在web工程中引用该jar 并且在springmvc文件中配置路径 如果有多个路径可用逗号隔开 3.在web工程找jsp页面如何引用 这样就可以了 关于jar中的资源 ...
- Maven把项目依赖的所有jar包都打到同一个jar中
目录 1 使用maven-shade-plugin 2 推荐: 使用maven-assembly-plugin 3 扩展: Maven安装本地jar包到本地仓库 4 扩展: 手动生成jar包 5 扩展 ...
- 使用RSA加密在Python中逆向shell
i春秋翻译小组-Neo(李皓伟) 使用RSA加密在Python中逆向shell 这是一个关于使用RSA加密编程逆向shell的python教程. 我想提一下,这篇文章更多的是关于理解shell中涉及的 ...
- maven笔记-将本地jar包打包进可执行jar中
参考资料:http://www.cnblogs.com/richard-jing/archive/2013/01/27/Maven_localjar.html 使用本地jar <dependen ...
- eclipse maven .jar中没有主清单属性
报错环境: windows系统eclipse maven 打包jar包后, 运行 java -jar 报错 E:\My_java\mysql\target>java -jar original- ...
随机推荐
- 10_PAE_非PAE
前置知识: 在 windows 中 保护模式 有两种模式: 段保护 和 页保护 段保护 主要体现在 段选择子上:但是数据段.代码段.栈段等采用的都是4GB平坦模式,段的特征并没有那样展现.所以具体的保 ...
- v-bind和v-model的区别
1:v-bind动态绑定指令,默认情况下标签自带属性的值是固定的,在为了能够动态的给这些属性添加值,可以使用v-bind:你要动态变化的值="表达式" 2:v-bind用于绑定属性 ...
- linux redis安装及JAVA使用jedis
一.redis安装 1.安装redis 将redis安装包放到指定目录下.并用tar -zxvf redis.*****.tar.gz解压2.想把redis安装到哪里,就在哪里创建redis文件夹. ...
- 在windows server 2012中安装完oracle 11 client如何使用
1.首先要添加监听配置,这样才可以没有报错的连接上服务器,至于如何添加,请自行搜索. 2.打开SQL Plus连接oracle server端,这里因为是小白,看到命令行界面上来就需要输入用户名密码 ...
- tcmalloc jemalloc 和ptmalloc 对比
ptmalloc 是glibc的内存分配管理 tcmalloc 是google的内存分配管理模块 jemalloc 是BSD的提供的内存分配管理 三者的性能对比参考从网上的一个图如下: 自己测试了一下 ...
- 将map转为Object,支持 Date/Boolean
import lombok.extern.log4j.Log4j2; import java.lang.reflect.Field; import java.lang.reflect.Method; ...
- Redis缓存数据库常见操作
Jedis的最为常见的操作.主要包括常用的列表(list).集合(set).有序集合(sorted set).哈希表(hash)等数据结构,以及其他特性支持. 参考资料:http://hello-ni ...
- GDI+图像与GDI位图的相互转换
Delphi的TBitmap封装了Windows的GDI位图,因此,TBitmap只支持bmp格式的图像,但是在Delphi应用程序中,常常会遇到图形格式的转换,如将Delphi位图TBitmap的图 ...
- Optimal Marks SPOJ - OPTM
传送门 一个无向图,每个点有点权,某些点点权确定了,某些点由你来确定,边权为两个点的异或和,要使边权和最小. 这不是一道按位做最小割的大水题么 非常开心地打了,还非常开心地以为有spj,然后非常开心地 ...
- [zz]使用OleDb,将Excel导入DataSet
本方法,将传入的Excel文件内所有的Sheet内的数据都填充入DataSet中.这是一个简单快捷的方法,不足之处是不适合带有格式复杂的Excel文件.(比如:有合并单元格的) public clas ...