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小时内删除。
发表评论