javaで暗号化ツールを仲間からもらったのですがどういう仕組みで動いているかがわかりません。
この場合どのようにjar.datを作成、またjar.datの中身を戻してXXX.jarに保存する手法を教えてください
java
1package jcrypt; 2 3import java.io.InputStream; 4import java.lang.reflect.Method; 5import java.security.Key; 6import java.util.jar.JarInputStream; 7import java.util.zip.ZipEntry; 8import java.util.zip.ZipFile; 9import javax.crypto.Cipher; 10import javax.crypto.CipherInputStream; 11import javax.crypto.spec.IvParameterSpec; 12import javax.crypto.spec.SecretKeySpec; 13 14public class Main 15{ 16 public static final String ENCRYPTED_ARCHIVE = "/jar.dat"; 17 18 public static void main(String[] args) 19 throws Exception 20 { 21 ZipFile zip = new ZipFile(Utils.getJarFile()); 22 23 ZipEntry e = zip.getEntry("jar.dat"); 24 byte[] extra = e.getExtra(); 25 26 byte[] key = new byte[16]; 27 System.arraycopy(extra, 0, key, 0, 16); 28 29 byte[] iv = new byte[16]; 30 System.arraycopy(extra, 16, iv, 0, 16); 31 32 boolean cryptAll = extra[32] == 1; 33 34 byte[] bMainClass = new byte[extra.length - 33]; 35 System.arraycopy(extra, 33, bMainClass, 0, extra.length - 33); 36 String mainClass = new String(bMainClass); 37 38 zip.close(); 39 40 InputStream resource = Main.class.getResourceAsStream("/jar.dat"); 41 42 Cipher cipher = Cipher.getInstance("AES/CBC/NOPADDING"); 43 44 Key sks = new SecretKeySpec(key, "AES"); 45 cipher.init(2, sks, new IvParameterSpec(iv)); 46 47 JarInputStream jarInputStream = new JarInputStream(new CipherInputStream(resource, cipher)); 48 EncryptedClassLoader classLoader = new EncryptedClassLoader(Main.class.getClassLoader(), jarInputStream, cryptAll); 49 50 Class<?> classToLoad = classLoader.loadClass(mainClass); 51 Method method = classToLoad.getMethod("main", new Class[] { String[].class }); 52 53 method.invoke(classToLoad.newInstance(), new Object[] { args }); 54 55 jarInputStream.close(); 56 } 57}
java
1package jcrypt; 2 3import java.io.File; 4import java.net.URL; 5import java.security.CodeSource; 6import java.security.ProtectionDomain; 7 8public class Utils 9{ 10 public static File getJarFile() 11 { 12 return new File(Utils.class.getProtectionDomain().getCodeSource().getLocation().getPath().replace("file:", "")); 13 } 14 15 public static String getClassName(String fileName) 16 { 17 return fileName.substring(0, fileName.length() - 6).replace('/', '.'); 18 } 19}
java
1package jcrypt; 2 3import java.io.ByteArrayInputStream; 4import java.io.ByteArrayOutputStream; 5import java.io.IOException; 6import java.io.InputStream; 7import java.net.URL; 8import java.util.Enumeration; 9import java.util.HashMap; 10import java.util.jar.JarEntry; 11import java.util.jar.JarInputStream; 12 13public class EncryptedClassLoader 14 extends ClassLoader 15{ 16 private final HashMap<String, byte[]> classes = new HashMap(); 17 private final HashMap<String, byte[]> others = new HashMap(); 18 private final boolean encryptResources; 19 20 public EncryptedClassLoader(ClassLoader parent, JarInputStream stream, boolean encryptResources) 21 { 22 super(parent); 23 loadResources(stream); 24 this.encryptResources = encryptResources; 25 } 26 27 public InputStream getResourceAsStream(String name) 28 { 29 if (this.encryptResources) 30 { 31 byte[] buffer = (byte[])this.others.get(name); 32 if (buffer != null) { 33 return new ByteArrayInputStream(buffer); 34 } 35 } 36 return super.getResourceAsStream(name); 37 } 38 39 public URL getResource(String name) 40 { 41 if (this.encryptResources) { 42 throw null; 43 } 44 return super.getResource(name); 45 } 46 47 protected Enumeration<URL> findResources(String name) 48 throws IOException 49 { 50 if (this.encryptResources) { 51 throw new IOException("Cant get URL from resource in memory"); 52 } 53 return super.findResources(name); 54 } 55 56 public int hashCode() 57 { 58 return getParent().hashCode(); 59 } 60 61 public Class<?> findClass(String name) 62 throws ClassNotFoundException 63 { 64 byte[] data = getClassData(name); 65 if (data != null) { 66 return defineClass(name, data, 0, data.length, Main.class.getProtectionDomain()); 67 } 68 throw new ClassNotFoundException(name); 69 } 70 71 public void loadResources(JarInputStream stream) 72 { 73 byte[] buffer = new byte['?']; 74 try 75 { 76 JarEntry entry = null; 77 while ((entry = stream.getNextJarEntry()) != null) 78 { 79 ByteArrayOutputStream out = new ByteArrayOutputStream(); 80 int count; 81 while ((count = stream.read(buffer)) != -1) 82 { 83 int count; 84 out.write(buffer, 0, count); 85 } 86 out.close(); 87 88 byte[] array = out.toByteArray(); 89 if (entry.getName().toLowerCase().endsWith(".class")) { 90 this.classes.put(Utils.getClassName(entry.getName()), array); 91 } else if (this.encryptResources) { 92 this.others.put(entry.getName(), array); 93 } 94 } 95 } 96 catch (IOException e) 97 { 98 e.printStackTrace(); 99 } 100 } 101 102 public boolean equals(Object o) 103 { 104 if ((o instanceof EncryptedClassLoader)) { 105 return ((EncryptedClassLoader)o).getParent() == getParent(); 106 } 107 return false; 108 } 109 110 public byte[] getClassData(String name) 111 { 112 byte[] b = (byte[])this.classes.get(name); 113 this.classes.remove(name); 114 return b; 115 } 116}
回答1件
あなたの回答
tips
プレビュー