防止java反编译的1点想法
防止java反编译的一点想法
为了企业的代码的安全,可以在打包之前将类文件加密之后,打包成相关的文件,在加载时,获取类文件信息,并解密加载到JVM中。
关于实现的代码如下:
package com.easyway.space.commons.classloaders.security; import static com.easyway.space.commons.classloaders.security.CommonSpaceConstant.SECURITY_KEY_FILE_LOCATION_KEY; import static com.easyway.space.commons.classloaders.security.CommonSpaceConstant.SYSTEMCONFIG_FILE_LOCATION; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.spec.InvalidKeySpecException; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESKeySpec; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.log4j.Logger; /** * * 类安全加载工具类 * @author longgangbai * */ public class ClassSecurityUtils { public static Logger logger=Logger.getLogger(ClassSecurityUtils.class); public static String SECURITY_KEY_FILE_LOCATION; static{ SECURITY_KEY_FILE_LOCATION =PropertiesUtils.getProperties(SYSTEMCONFIG_FILE_LOCATION).getProperty(SECURITY_KEY_FILE_LOCATION_KEY); } /** * 将客户端的jar文件通过循环依次加密 * @param clazzPath 类文件路径 * @throws Exception */ public static void cryptClass(String clazzPath) throws Exception { //获取密钥信息 FileInputStream fi = new FileInputStream(new File(SECURITY_KEY_FILE_LOCATION)); byte rawKeyData[]=IOUtils.toByteArray(fi); //创建加密的对象 SecureRandom sr = new SecureRandom(); DESKeySpec dks = new DESKeySpec(rawKeyData); SecretKey key = SecretKeyFactory.getInstance("DES").generateSecret(dks); Cipher cipher = Cipher.getInstance("DES"); cipher.init(Cipher.ENCRYPT_MODE, key, sr); //获取class文件加密前的信息 File clazzFile=new File(clazzPath); FileInputStream fi2 = new FileInputStream(clazzFile); byte data[] = IOUtils.toByteArray(fi2); //获取加密之后的信息并写入文件 byte encryptedData[] = cipher.doFinal(data); FileOutputStream fo = new FileOutputStream(clazzFile); IOUtils.write(encryptedData, fo); } /** * * 用于解析加密过的class文件的并加载到JVM中 * @param filepath 密钥文件的路径 * @param clazzPath 需要解密的classpath文件的路径 * @param clazzLoader 相应的类加载器 * @throws InvalidKeyException * @throws InvalidKeySpecException * @throws NoSuchAlgorithmException * @throws NoSuchPaddingException * @throws IllegalBlockSizeException * @throws BadPaddingException * @throws ClassNotFoundException */ public static void decryptClass(String filepath,String clazzPath,CustomerClassLoader clazzLoader) throws InvalidKeyException, InvalidKeySpecException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, ClassNotFoundException{ //获取密钥文件的信息 File file=new File(filepath); //获取Class 文件的信息 File clazzFile=new File(clazzPath); if(file.exists()){ try { //获取密钥的信息 byte rawKeyData[] = FileUtils.readFileToByteArray(file); //设置安全算法的密钥 SecureRandom sr = new SecureRandom(); DESKeySpec dks = new DESKeySpec(rawKeyData); //采用DES加密的算法 SecretKey key = SecretKeyFactory.getInstance("DES").generateSecret(dks); Cipher cipher = Cipher.getInstance("DES"); //初始化密钥对象 cipher.init(Cipher.DECRYPT_MODE, key, sr); if(clazzFile.exists()) { //获取加密之前的文件的信息 byte rawEncryptedClassData[] = FileUtils.readFileToByteArray(clazzFile); //解密加密文件的信息 byte decryptedClazzData[] = cipher.doFinal(rawEncryptedClassData); //通过类加载器加载类到JVM中 String className=clazzFile.getName(); clazzLoader.loadClass(decryptedClazzData, className); } } catch (IOException e) { logger.error("解析加载文件"+clazzFile.getName(), e); } } } }
1 楼
ybw31549490
2011-11-07
加密后影响实际编程调用jar包内的方法吗?