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