Java代码加密与反编译(⼆:⽤加密算法DES修改classLoader实现对.class⽂
件加密
也欢迎⼤家转载本篇⽂章。分享知识,造福⼈民,实现我们中华民族伟⼤复兴!
⼆、利⽤加密算法DES实现java代码加密
传统的C/C++⾃动带有保护机制,但java不同,只要使⽤反编译⼯具,代码很容易被暴露,这⾥需要了解的就是Java的ClassLoader 对象。
Java运⾏时装⼊字节码的机制隐含地意味着可以对字节码进⾏修改。JVM每次装⼊类⽂件时都需要⼀个称为ClassLoader的对象,这个对象负责把新的类装⼊正在运⾏的JVM。JVM给ClassLoader⼀个包含了待装⼊类(⽐如java.lang.Object)名字的字符串,然后由ClassLoader负责到类⽂件,装⼊原始数据,并把它转换成⼀个Class对象。可以通过定制ClassLoader,在类⽂件执⾏之前修改它。在这⾥,它的⽤途是在类⽂件装⼊之时进⾏解密,因此可以看成是⼀种即时解密器。由于解密后的字节码⽂件永远不会保存到⽂件系统,所以窃密者很难得到解密后的代码。
创建定制ClassLoader对象:只需先获得原始数据,接着就可以进⾏包含解密在内的任何转换。这⾥我们可以⾃⼰实现loadClass。
制定类装⼊器:
每⼀个运⾏着的JVM已经拥有⼀个ClassLoader。这个默认的ClassLoader根据CLASSPATH环境变量的值,在本地⽂件系统中寻合适的字节码⽂件。
⾸先创建⼀个定制ClassLoader类的实例,然后显式地要求它装⼊另外⼀个类。这就强制JVM把该类以及所有它所需要的类关联到定制的ClassLoader。
step1:⽣成⼀个安全秘钥。
在加密或解密任何数据之前需要有⼀个密匙。密匙是随同被加密的应⽤⼀起发布的⼀⼩段数据。⽣成过后的秘钥为key.data。
Util.java:
1. import java.io.*;
2.
3. public class Util
4. {
5.  // 把⽂件读⼊byte数组
6.  static public byte[] readFile(String filename) throws IOException {
7.    File file = new File(filename);
8.    long len = file.length();
9.    byte data[] = new byte[(int)len];
10.    FileInputStream fin = new FileInputStream(file);
11.    int r = ad(data);
12.    if (r != len)
13.      throw new IOException("Only read "+r+" of "+len+" for "+file);
14.    fin.close();
15.    return data;
16.  }
17.
18.  // 把byte数组写出到⽂件
19.  static public void writeFile(String filename, byte data[]) throws IOException {
20.    FileOutputStream fout = new FileOutputStream(filename);
21.    fout.write(data);
22.    fout.close();
23.  }
24. }
GenerateKey.java:
1. import java.security.SecureRandom;
2. pto.KeyGenerator;
3. pto.SecretKey;
4.
5. public class GenerateKey
6. {
7.  static public void main(String args[]) throws Exception {
8.    String keyFilename = args[0];
9.    String algorithm = "DES";
10.
11.    // ⽣成密匙
12.    SecureRandom sr = new SecureRandom();
13.    KeyGenerator kg = Instance(algorithm);
14.    kg.init(sr);
15.    SecretKey key = kg.generateKey();
16.
17.    // 把密匙数据保存到⽂件
18.    Util.writeFile(keyFilename, Encoded());
19.  }
20. }
step2:加密待加密的.class⽂件。
得到密匙之后,接下来就可以⽤它加密数据。除了解密的ClassLoader之外,⼀般还要有⼀个加密待发布应⽤的独⽴程序:EncryptClasses.java:
1. import java.security.*;
2. pto.*;
3. pto.spec.*;
4.
5. public class EncryptClasses
6. {
7.  static public void main(String args[]) throws Exception {
8.    String keyFilename = args[0];
9.    String algorithm = "DES";
10.
11.    // ⽣成密匙
12.    SecureRandom sr = new SecureRandom();
13.    byte rawKey[] = adFile(keyFilename);
14.    DESKeySpec dks = new DESKeySpec(rawKey);
15.    SecretKeyFactory keyFactory = Instance( algorithm );
16.    SecretKey key = ateSecret(dks);
17.
18.    // 创建⽤于实际加密操作的Cipher对象
19.    Cipher ecipher = Instance(algorithm);
20.    ecipher.init(Cipher.ENCRYPT_MODE, key, sr);
21.
22.    // 加密命令⾏中指定的每⼀个类
23.    for (int i=1; i<args.length; ++i) {
24.      String filename = args[i];
25.      byte classData[] = adFile(filename);  //读⼊类⽂件
26.      byte encryptedClassData[] = ecipher.doFinal(classData);  //加密
27.      Util.writeFile(filename, encryptedClassData);  // 保存加密后的内容
28.      System.out.println("Encrypted "+filename);
29.    }
30.  }
31. }
step3:加密待加密的.class⽂件。
编译之后⽤命令⾏启动程序,下⾯是源码:java源代码加密
DecryptStart.java:
1. import java.io.*;
2. import java.security.*;
3. import flect.*;
4. pto.*;
5. pto.spec.*;
6.
7. public class DecryptStart extends ClassLoader
8. {
9.  // 这些对象在构造函数中设置,以后loadClass()⽅法将利⽤它们解密类
10.  private SecretKey key;
11.  private Cipher cipher;
12.
13.  // 构造函数:设置解密所需要的对象
14.  public DecryptStart(SecretKey key) throws GeneralSecurityException, IOException {
15.    this.key = key;
16.
17.    String algorithm = "DES";
18.    SecureRandom sr = new SecureRandom();
19.    println("[DecryptStart: creating cipher]");
20.    cipher = Instance(algorithm);
21.    cipher.init(Cipher.DECRYPT_MODE, key, sr);
22.  }
23.
24.  // main过程:在这⾥读⼊密匙,创建DecryptStart的实例,它就是定制ClassLoader。
25.  // 设置好ClassLoader以后,⽤它装⼊应⽤实例,
26.  // 最后,通过Java Reflection API调⽤应⽤实例的main⽅法
27.  public static void main(String args[]) throws Exception {
28.    String keyFilename = args[0];
29.    String appName = args[1];
30.
31.    // 传递给应⽤本⾝的参数
32.    String realArgs[] = new String[args.length-2];
33.    System.arraycopy( args, 2, realArgs, 0, args.length-2 );
34.
35.    // 读取密匙
36.    println( "[DecryptStart: reading key]" );
37.    byte rawKey[] = adFile(keyFilename);
38.    DESKeySpec dks = new DESKeySpec(rawKey);
39.    SecretKeyFactory keyFactory = Instance("DES");

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。