· 7 years ago · Jan 04, 2019, 12:28 PM
1mport javax.crypto.*;
2import java.security.*;
3import java.io.*;
4import java.util.*;
5import javax.tools.*;
6public class SourceCrypter{
7
8 private SecretKey key;
9 private DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
10 private String inputClassName = "";
11 private String crypterClassName;
12 //Decrypt Method
13 private List<String> dm = new ArrayList<String>();
14 //Main Method
15 private List<String> mm = new ArrayList<String>();
16 //JavaSourceFromString Class
17 private List<String> jsfs = new ArrayList<String>();
18 //Header
19 private List<String> imports = new ArrayList<String>();
20 //Everything else
21 private String byteKey = "private static byte[] byteKey = {";
22 private String encCode = "private static byte[] encSource = {";
23 private String keyString = "private static SecretKey key = new SecretKeySpec(byteKey, \"AES\");";
24
25 //fileName must be different than sourceFile!!!!
26 public SourceCrypter(String sourceFile, String fileName, boolean compile){
27 try{
28 crypterClassName = fileName;
29
30 if(!sourceFile.toLowerCase().endsWith(".java")){
31 System.out.println("Crypter only works with *.java files!");
32 return;
33 }
34
35 System.out.println("Read "+sourceFile);
36 FileReader fr = new FileReader(sourceFile);
37 BufferedReader br = new BufferedReader(fr);
38
39 //Read File
40 String fileString = "";
41 String line = "";
42 while((line = br.readLine()) != null){
43 if(line.isEmpty()){
44 continue;
45 }else if(inputClassName.isEmpty() && line.contains(" class ")){
46 int start_index = line.indexOf(" class ") + 7;
47 int end_index = start_index + 1;
48 while(end_index < line.length()-1 && Character.isLetter(line.charAt(end_index))){
49 end_index++;
50 }
51 inputClassName = line.substring(start_index, end_index);//get classname as substring!
52 }else if(line.contains(" ")){
53 line = line.replace(" ", "");
54 }
55 fileString = fileString + line;
56 }
57 //Close Streams
58 br.close();
59 fr.close();
60
61 System.out.println("Generate AES Key...");
62 generateKey();
63 System.out.println("Add AES Key to SourceString...");
64 byte[] tmpKey = key.getEncoded();
65 for(int i = 0; i < tmpKey.length; i++){
66 byteKey = byteKey + tmpKey[i] + ",";
67 }
68 byteKey = byteKey + "};";
69
70 System.out.println("Encrypt SourceCode...");
71 byte[] encryptedSource = encryptString(fileString);
72 System.out.println("Add encrypted SourceCode...");
73 for(int i = 0; i < encryptedSource.length; i++){
74 encCode = encCode + encryptedSource[i] + ",";
75 }
76 encCode = encCode + "};";
77
78 System.out.println("Init Crypter SourceCode...");
79 init();
80
81 System.out.println("Write CrypterClass File....");
82 FileWriter fw = new FileWriter(crypterClassName+".java");
83 BufferedWriter bw = new BufferedWriter(fw);
84 for(String tmp : imports){
85 bw.write(tmp);
86 }
87 bw.write("public class "+crypterClassName+"{");
88 bw.write(byteKey);
89 bw.write(encCode);
90 bw.write(keyString);
91 for(String tmp : mm){
92 bw.write(tmp);
93 }
94 for(String tmp : dm){
95 bw.write(tmp);
96 }
97 bw.write("}");
98 for(String tmp : jsfs){
99 bw.write(tmp);
100 }
101 bw.close();
102 fw.close();
103
104 if(compile){
105 System.out.println("Compiling "+crypterClassName+".java...");
106 compileFile(new File(crypterClassName + ".java"));
107 for(Diagnostic diagnostic : diagnostics.getDiagnostics()){
108 System.out.println("Error on Line "+diagnostic.getLineNumber());
109 }
110 }
111 System.out.println("Done!");
112 }catch(Throwable e){
113 e.printStackTrace();
114 }
115 }
116
117 private void init(){
118 //Init imports
119 imports.add("import java.util.*;");
120 imports.add("import java.net.*;");
121 imports.add("import java.io.*;");
122 imports.add("import javax.tools.*;");
123 imports.add("import javax.tools.JavaCompiler.*;");
124 imports.add("import javax.crypto.*;");
125 imports.add("import javax.crypto.spec.*;");
126
127 //Init Main Method
128 mm.add("public static void main(String[] argv){");
129 mm.add("try{");
130 mm.add("JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();");
131 mm.add("DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();");
132 mm.add("String sourceCode = decryptSource(encSource);");
133 mm.add("StringWriter writer = new StringWriter();");
134 mm.add("PrintWriter out = new PrintWriter(writer);");
135 mm.add("out.println(sourceCode);");
136 mm.add("out.close();");
137 mm.add("JavaFileObject file = new JavaSourceFromString(\""+inputClassName+"\", writer.toString());");
138 mm.add("Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(file);");
139 mm.add("CompilationTask task = compiler.getTask(null, null, diagnostics, null, null, compilationUnits);");
140 mm.add("boolean success = task.call();");
141 mm.add("for(Diagnostic diagnostic : diagnostics.getDiagnostics()){");
142 mm.add("System.out.println(\"Error on Line \"+diagnostic.getLineNumber());}");
143 mm.add("if(success){");
144 mm.add("Class.forName(\""+inputClassName+"\").getDeclaredMethod(\"main\", new Class[]{String[].class}).invoke(null,new Object[]{null});}");
145 mm.add("}catch(Throwable e){e.printStackTrace();}}");
146
147 //Init Decryption Method
148 dm.add("private static String decryptSource(byte[] input){");
149 dm.add("try{");
150 dm.add("Cipher cipher = Cipher.getInstance(\"AES\");");
151 dm.add("cipher.init(Cipher.DECRYPT_MODE, key);");
152 dm.add("byte[] output = cipher.doFinal(input);");
153 dm.add("return new String(output);");
154 dm.add("}catch(Throwable e){");
155 dm.add("e.printStackTrace();");
156 dm.add("return null;}}");
157
158 //Init JavaSourceFromString Class
159 jsfs.add("class JavaSourceFromString extends SimpleJavaFileObject{");
160 jsfs.add("final String code;");
161 jsfs.add("JavaSourceFromString(String name, String code){");
162 jsfs.add("super(URI.create(\"string:///\"+name.replace('.','/')+Kind.SOURCE.extension),Kind.SOURCE);");
163 jsfs.add("this.code = code;}");
164 jsfs.add("@Override ");
165 jsfs.add("public CharSequence getCharContent(boolean ignoreEncodingErrors){");
166 jsfs.add("return code;}}");
167 }
168
169
170
171 private void generateKey(){
172 try{
173 KeyGenerator keygen = KeyGenerator.getInstance("AES");
174 SecureRandom random = new SecureRandom();
175 keygen.init(random);
176 key = keygen.generateKey();
177 }catch(Throwable e){
178 e.printStackTrace();
179 }
180 }
181
182 private byte[] encryptString(String words){
183 try{
184 byte[] input = words.getBytes();
185
186 Cipher cipher = Cipher.getInstance("AES");
187 cipher.init(Cipher.ENCRYPT_MODE, key);
188
189 byte[] output = cipher.doFinal(input);
190 return output;
191 }catch(Throwable e){
192 e.printStackTrace();
193 return null;
194 }
195 }
196
197 private void compileFile(File file){
198 try{
199 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
200 StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
201 Iterable<? extends JavaFileObject> compilationUnit = fileManager.getJavaFileObjects(file);
202 compiler.getTask(null, fileManager, diagnostics, null, null, compilationUnit).call();
203 fileManager.close();
204 }catch(Throwable e){
205 e.printStackTrace();
206 }
207 }