javaee加密部署项目通过tomcat使用自定义的classload解密
来源:互联网 发布:知乎大神侵权 编辑:程序博客网 时间:2024/06/15 17:19
参考文章:http://blog.itpub.net/29754888/viewspace-1220306/
如上述文章所说,继承tomcat的WebappClassLoader自定义自己的classload,并不适用于spring。
原因是spring加载类是用另外的方式来加载。
意思应该是是需要封装的jar代码中不能有spring的注解(依赖注入、控制器声明等等)
原理:
通过加密java代码的class文件,实现对源代码的保护,并通过自定义的classload文件来解密class文件,把类加载到项目中
自定义自己的classload,并重写findClass方法。类加载器通过调用findClass方法,寻找并加载类文件。
通过重写findClass方法,可以把预先加密好的class文件,解密后再加载到项目中
package generator;import java.io.BufferedReader;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStreamReader;import java.io.UnsupportedEncodingException;import java.security.InvalidKeyException;import java.security.NoSuchAlgorithmException;import java.util.ArrayList;import java.util.List;import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.NoSuchPaddingException;import javax.crypto.spec.SecretKeySpec;import org.apache.catalina.loader.WebappClassLoader;/** * 自定义的classloader 可以解密文件并加载 * * @author uikoo9 */public class UClassLoader extends WebappClassLoader {/** * 算法 */private String algorithmStr="AES/ECB/PKCS5Padding";/** * key */private String keyStr="abcdefg123456789";/** * 默认构造器 * * @throws Exception */public UClassLoader() {super();}/** * 默认构造器 * * @param parent * @throws Exception */public UClassLoader(ClassLoader parent) {super(parent);}/* * (non-Javadoc) * * @see * org.apache.catalina.loader.WebappClassLoader#findClass(java.lang.String) */public Class findClass(String name) throws ClassNotFoundException {if (name.contains("com.A")|| name.contains("com.B")|| name.contains("com.C")) {return findClassEncrypt(name);} else {return super.findClass(name);}}/** * 查找class * * @param name * @return * @throws ClassNotFoundException */private Class findClassEncrypt(String name) throws ClassNotFoundException {byte[] classBytes = null;try {classBytes = loadClassBytesEncrypt(name);} catch (Exception e) {e.printStackTrace();}Class cl = defineClass(name, classBytes, 0, classBytes.length);if (cl == null) {System.out.println("找不到该类:" + name);throw new ClassNotFoundException(name);}return cl;}/** * 加载加密后的class字节流 * * @param name * @return * @throws Exception */private byte[] loadClassBytesEncrypt(String name) throws Exception {// 获取当前文件路径// File directory = new File("");// String parentPath = directory.getAbsolutePath()+File.separator;String parentPath = "F:\\";List<String> basepath = new ArrayList<String>();basepath.add(parentPath + "A\\");// 项目物理地址basepath.add(parentPath + "B\\");// 项目物理地址basepath.add(parentPath + "C\\");// 项目物理地址String cname = null;File file = null;for (String path : basepath) {cname = path + name.replace('.', '\\') + ".cls";file = new File(cname);if (file.exists()) {break;}}if (file != null) {if (!file.exists()) {throw new Exception("File Not found:" + cname);}}FileInputStream in = new FileInputStream(cname);try {ByteArrayOutputStream buffer = new ByteArrayOutputStream();byte[] buf = new byte[1024 * 100];// 100KBint len = 0;while ((len = in.read(buf)) != -1) {buffer.write(buf, 0, len);}in.close();return decrypt(parseHexStr2Byte(new String(buffer.toByteArray())));} finally {in.close();}}/** * 解密 * * @param content * @return */private byte[] decrypt(byte[] content) {try {byte[] keyBytes = this.keyStr.getBytes("utf-8");SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");Cipher cipher = Cipher.getInstance(this.algorithmStr);cipher.init(Cipher.DECRYPT_MODE, key);byte[] result = cipher.doFinal(content);return result;} catch (UnsupportedEncodingException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (NoSuchPaddingException e) {e.printStackTrace();} catch (InvalidKeyException e) {e.printStackTrace();} catch (IllegalBlockSizeException e) {e.printStackTrace();} catch (BadPaddingException e) {e.printStackTrace();}return null;}/** * 十六进制字符串转字节 * * @param hexStr * @return */private byte[] parseHexStr2Byte(String hexStr) {if (hexStr.length() < 1)return null;byte[] result = new byte[hexStr.length() / 2];for (int i = 0; i < hexStr.length() / 2; i++) {int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);result[i] = (byte) (high * 16 + low);}return result;}}在tomcat的content.xml文件中,配置自定义的classload为tomcat默认的classload
在<Content>中添加如下代码
<Loader loaderClass="generator.UClassLoader" delegate="true"></Loader>指定环境上下文类加载为自定义的classload
注意:自定义的classload放在tomcat的lib下,并且文件夹层级结构需要跟包名一致generator/UClassLoader.class
大概步骤如下
1、对需要加密的class进行算法加密,本人是用AES加密
2、把加密后的class文件放到固定的地方,把项目中的对应class删除
3、修改context.xml的指定上下文类加载器为自定义加载器
4、启动tomcat
另外:如果不想自定义tomcat的classload,也可以自定义classload继承URLClassLoader
代码方式类似,也是通过重写findClass方法。编写好自定义classload后,在项目中实例化该类。
package classload;import java.io.BufferedInputStream;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.io.UnsupportedEncodingException;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.net.MalformedURLException;import java.net.URL;import java.net.URLClassLoader;import java.security.InvalidKeyException;import java.security.NoSuchAlgorithmException;import java.util.ArrayList;import java.util.List;import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.NoSuchPaddingException;import javax.crypto.spec.SecretKeySpec;public class MyClassLoader extends URLClassLoader {/** * 算法 */private String algorithmStr="AES/ECB/PKCS5Padding";/** * key */private String keyStr="abcdefg123456789"; public MyClassLoader(URL[] urls){super(urls);}public MyClassLoader(URL[] urls, ClassLoader parent){super(urls,parent);}public static void main(String[] args) throws MalformedURLException {URL url = new File("a.jar").toURI().toURL();MyClassLoader classLoader = new MyClassLoader(new URL[]{url},Thread.currentThread().getContextClassLoader());//设置自定义classload为环境上下文类加载器Thread.currentThread().setContextClassLoader(classLoader);}public Class findClass(String name) throws ClassNotFoundException {if (name.contains("com.A")|| name.contains("com.B")|| name.contains("com.C")) {return findClassEncrypt(name);} else {return super.findClass(name);}}/** * 查找class * * @param name * @return * @throws ClassNotFoundException */private Class findClassEncrypt(String name) throws ClassNotFoundException {byte[] classBytes = null;try {classBytes = loadClassBytesEncrypt(name);} catch (Exception e) {e.printStackTrace();}Class cl = defineClass(name, classBytes, 0, classBytes.length);if (cl == null) {System.out.println("找不到该类:" + name);throw new ClassNotFoundException(name);}return cl;}/** * 加载加密后的class字节流 * * @param name * @return * @throws Exception */private byte[] loadClassBytesEncrypt(String name) throws Exception {// 获取当前文件路径// File directory = new File("");// String parentPath = directory.getAbsolutePath()+File.separator;String parentPath = "F:\\";List<String> basepath = new ArrayList<String>();basepath.add(parentPath + "A\\");// 项目物理地址basepath.add(parentPath + "B\\");// 项目物理地址basepath.add(parentPath + "C\\");// 项目物理地址String cname = null;File file = null;for (String path : basepath) {cname = path + name.replace('.', '\\') + ".cls";file = new File(cname);if (file.exists()) {break;}}if (file != null) {if (!file.exists()) {throw new Exception("File Not found:" + cname);}}FileInputStream in = new FileInputStream(cname);try {ByteArrayOutputStream buffer = new ByteArrayOutputStream();byte[] buf = new byte[1024 * 100];// 100KBint len = 0;while ((len = in.read(buf)) != -1) {buffer.write(buf, 0, len);}in.close();return decrypt(parseHexStr2Byte(new String(buffer.toByteArray())));} finally {in.close();}}/** * 解密 * * @param content * @return */private byte[] decrypt(byte[] content) {try {byte[] keyBytes = this.keyStr.getBytes("utf-8");SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");Cipher cipher = Cipher.getInstance(this.algorithmStr);cipher.init(Cipher.DECRYPT_MODE, key);byte[] result = cipher.doFinal(content);return result;} catch (UnsupportedEncodingException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (NoSuchPaddingException e) {e.printStackTrace();} catch (InvalidKeyException e) {e.printStackTrace();} catch (IllegalBlockSizeException e) {e.printStackTrace();} catch (BadPaddingException e) {e.printStackTrace();}return null;}/** * 十六进制字符串转字节 * * @param hexStr * @return */private byte[] parseHexStr2Byte(String hexStr) {if (hexStr.length() < 1)return null;byte[] result = new byte[hexStr.length() / 2];for (int i = 0; i < hexStr.length() / 2; i++) {int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);result[i] = (byte) (high * 16 + low);}return result;}}
URL url = new File("a.jar").toURI().toURL();MyClassLoader classLoader = new MyClassLoader(new URL[]{url},Thread.currentThread().getContextClassLoader());//设置自定义classload为环境上下文类加载器Thread.currentThread().setContextClassLoader(classLoader);
构造函数必须传URL对象参数进去,所以要随便指定一个jar。
阅读全文
0 0
- javaee加密部署项目通过tomcat使用自定义的classload解密
- javaee加密部署,tomcat使用自己的classloader解密【正解】
- javaee加密部署,tomcat使用自己的classloader解密
- javaee加密,tomcat使用自己的classloader解密
- Tomcat自定义classLoader加密解密
- Java加密部署,使用自定义的classloader解密的方法实例
- centos上面在Tomcat部署JavaEE项目的步骤
- tomcat classload
- 自定义classload加载自定义的class文件
- javaEE Tomcat 部署方式
- 浪潮优派培训笔记:Tomcat中部署JavaEE项目的两种方式
- 使用maven的tomcat插件部署项目
- Tomcat项目部署+Nginx的简单使用
- 通过windows把项目部署到Linux的tomcat中
- Intellij IDEA通过tomcat部署web项目的机制
- CentOS服务器,Nginx+Tomcat 上部署javaEE项目,负载均衡
- IDE/ JavaEE webstorm将项目部署到Tomcat目录
- RSA加密解密的使用!
- js面向对象基础(进阶)
- BZOJ4177: Mike的农场
- windows webrtc编译二:下载源码并编译
- Vue.js 官方文档摘记:Vue 实例
- 关于SqlServer数据库中自增型ID的优势及不足的分析
- javaee加密部署项目通过tomcat使用自定义的classload解密
- opencv3之目标跟踪(单目标、多目标)
- jenkins的使用
- JDK动态代理
- 回归
- itemCF 基于物品的协同过滤
- 数据结构BinaryTree实例(七):二叉树转成双向链表
- Vue2.0实现懒加载
- openstack的RPC机制之AMQP协议