├── Readme.md ├── Readme_resource ├── image-20220131041634355.png ├── image-20220131041913646.png └── image-20220131043954432.png ├── pom.xml └── src ├── META-INF └── MANIFEST.MF └── main └── java ├── CLI.java ├── Decrypt.java ├── GetEncode.java ├── META-INF └── MANIFEST.MF ├── main.java └── utils.java /Readme.md: -------------------------------------------------------------------------------- 1 | # jasyptAutoDecrypt 2 | 3 | 在线的那几个咱也不知道咋写的,反正不好使,那就自己造个呗。。。 4 | 5 | > 妈妈再也不用怕我试不出来spring的加密密码了 6 | 7 | 没啥技术含量,就是挨个试一遍。。。 8 | 9 | 嗯,单线程的,有空再改个多线程吧。。。🤡 10 | 11 | ## 关于部分fuzz的数值 12 | 13 | ### keyObtentionIterations 14 | 15 | 默认是1000,应该能应付绝大部分情况。。。 16 | 17 | 其余的是我从github上用了jasypt的项目里找的 18 | 19 | ### StringOutputType 20 | 21 | 官方文档里都说了,就俩 base64 hex 22 | 23 | ### algorithm 24 | 25 | 都是jasypt支持的方式 26 | 27 | ### salt、iv、其他 28 | 29 | jasypt的包里的方法,直接拿来用了(其实可以筛去几个的。。。 30 | 31 | 需要注意的是jasypt版本问题,新旧版本iv的classname不一样,我这直接用了1.9.3新版的 32 | 33 | 新版的iv是`org.jasypt.iv` 旧版的是`org.jasypt.salt` 34 | 35 | [Springboot使用jasypt需要注意的一个小地方 - 知乎 (zhihu.com)](https://zhuanlan.zhihu.com/p/347135701) 36 | 37 | ## 傻瓜式用法 38 | 39 | ``` 40 | java -jar jasyptAtuoDecrypt.jar 41 | usage: 42 | -e,--encryptedMessage encryptedMessage 43 | -h,--help display help text 44 | -p,--password password of the encryptedMessage 45 | ``` 46 | 47 | ![image-20220131041634355](Readme_resource/image-20220131041634355.png) 48 | 49 | 运行过程中成功的会带颜色输出 50 | 51 | ``` 52 | java -jar jasyptAtuoDecrypt.jar -e 16CF6CD023DF60DB8C6F0CE250D0CCC49D6239504AEA34E0EC0EAA4C46F05CFCC21F1F07E32B330EBDD32FF2F344E1D7 -p xhsnauw77sj 53 | Get password: xhsnauw77sj 54 | Get encrypted message: 16CF6CD023DF60DB8C6F0CE250D0CCC49D6239504AEA34E0EC0EAA4C46F05CFCC21F1F07E32B330EBDD32FF2F344E1D7 55 | [=] Loading iv methods... 56 | [+] Load iv success 57 | [=] Loading salt methods... 58 | [+] Load salt success 59 | [+] Now Trying PBEWITHMD5ANDDES 60 | [+] Now Trying PBEWITHHMACSHA1ANDAES_128 61 | [+] Now Trying PBEWITHHMACSHA1ANDAES_256 62 | [+] Now Trying PBEWITHHMACSHA224ANDAES_128 63 | [*] hello 64 | ``` 65 | 66 | ![image-20220131041913646](Readme_resource/image-20220131041913646.png) 67 | 68 | 运行结束,会统一输出,没有乱吗的会用[+]标出来,乱码的用[?]标出了。 69 | 70 | ![image-20220131043954432](Readme_resource/image-20220131043954432.png) 71 | -------------------------------------------------------------------------------- /Readme_resource/image-20220131041634355.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbelChe/jasyptAtuoDecrypt/80bf435491ec62235f5b3d8fcfb2312c5706260f/Readme_resource/image-20220131041634355.png -------------------------------------------------------------------------------- /Readme_resource/image-20220131041913646.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbelChe/jasyptAtuoDecrypt/80bf435491ec62235f5b3d8fcfb2312c5706260f/Readme_resource/image-20220131041913646.png -------------------------------------------------------------------------------- /Readme_resource/image-20220131043954432.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbelChe/jasyptAtuoDecrypt/80bf435491ec62235f5b3d8fcfb2312c5706260f/Readme_resource/image-20220131043954432.png -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.example 8 | jasyptAtuoDecrypt 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 8 13 | 8 14 | 15 | 16 | 17 | 18 | 19 | org.jasypt 20 | jasypt 21 | 1.9.3 22 | 23 | 24 | 25 | org.reflections 26 | reflections 27 | 0.10.2 28 | 29 | 30 | 31 | 32 | commons-cli 33 | commons-cli 34 | 1.5.0 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Main-Class: main 3 | 4 | -------------------------------------------------------------------------------- /src/main/java/CLI.java: -------------------------------------------------------------------------------- 1 | import org.apache.commons.cli.*; 2 | 3 | public class CLI { 4 | 5 | static String[] args; 6 | static String password; 7 | static String encryptedMessage; 8 | static Option optionKey = new Option("p", "password", true, "password of the encryptedMessage"); 9 | static Option optionPassword = new Option("e", "encryptedMessage", true, "encryptedMessage"); 10 | static Option optionHelp = new Option("h", "help", false, "display help text"); 11 | 12 | public CLI(String[] args) { 13 | CLI.args = args; 14 | } 15 | 16 | private static boolean checkForHelp(String[] args) throws ParseException { 17 | boolean hashelp = false; 18 | Options options = new Options(); 19 | try { 20 | options.addOption(CLI.optionHelp); 21 | new DefaultParser(); 22 | CommandLineParser parser = new DefaultParser(); 23 | CommandLine cmd = parser.parse(options, args); 24 | if (cmd.hasOption(optionHelp.getOpt()) || args.length == 0) { 25 | hashelp = true; 26 | } 27 | } catch (ParseException e) { 28 | return hashelp; 29 | } 30 | 31 | return hashelp; 32 | } 33 | 34 | public static boolean parseCLI() throws ParseException { 35 | Options options = new Options(); 36 | 37 | CLI.optionKey.setRequired(true); 38 | CLI.optionPassword.setRequired(true); 39 | 40 | options.addOption(optionKey); 41 | options.addOption(optionPassword); 42 | options.addOption(optionHelp); 43 | 44 | try { 45 | if (checkForHelp(CLI.args)) { 46 | HelpFormatter fmt = new HelpFormatter(); 47 | fmt.printHelp(" ", options); 48 | return false; 49 | } 50 | } catch (ParseException e) { 51 | throw e; 52 | } 53 | 54 | try { 55 | CommandLine commandLine = new DefaultParser().parse(options, CLI.args); 56 | 57 | if (commandLine.hasOption("p") || commandLine.hasOption("password")) { 58 | //获取参数 59 | CLI.password = commandLine.getOptionValue('p'); 60 | System.out.println("Get password: " + CLI.password); 61 | } 62 | 63 | if (commandLine.hasOption("e") || commandLine.hasOption("encryptedMessage")) { 64 | //获取参数 65 | CLI.encryptedMessage = commandLine.getOptionValue('e'); 66 | System.out.println("Get encrypted message: " + CLI.encryptedMessage); 67 | } 68 | } catch (ParseException e) { 69 | e.printStackTrace(); 70 | } 71 | return true; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/Decrypt.java: -------------------------------------------------------------------------------- 1 | import org.jasypt.encryption.pbe.StandardPBEStringEncryptor; 2 | import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig; 3 | import org.jasypt.exceptions.EncryptionInitializationException; 4 | import org.jasypt.exceptions.*; 5 | 6 | import java.util.ArrayList; 7 | import java.util.Set; 8 | 9 | 10 | public class Decrypt { 11 | static String Talgorithm; 12 | static String plaintext; 13 | static ArrayList result = new ArrayList<>(); 14 | 15 | static String ivClass = "org.jasypt.iv"; 16 | static String saltClass = "org.jasypt.salt"; 17 | static ArrayList ivClassList = new ArrayList<>();; 18 | static ArrayList saltClassList = new ArrayList<>(); 19 | static String[] algorithmList = { 20 | "PBEWITHMD5ANDDES", // default 21 | "PBEWITHHMACSHA1ANDAES_128", 22 | "PBEWITHHMACSHA1ANDAES_256", 23 | "PBEWITHHMACSHA224ANDAES_128", 24 | "PBEWITHHMACSHA224ANDAES_256", 25 | "PBEWITHHMACSHA256ANDAES_128", 26 | "PBEWITHHMACSHA256ANDAES_256", 27 | "PBEWITHHMACSHA384ANDAES_128", 28 | "PBEWITHHMACSHA384ANDAES_256", 29 | "PBEWITHHMACSHA512ANDAES_128", 30 | "PBEWITHHMACSHA512ANDAES_256", 31 | "PBEWITHMD5ANDTRIPLEDES", 32 | "PBEWITHSHA1ANDDESEDE", 33 | "PBEWITHSHA1ANDRC2_128", 34 | "PBEWITHSHA1ANDRC2_40", 35 | "PBEWITHSHA1ANDRC4_128", 36 | "PBEWITHSHA1ANDRC4_40" 37 | }; 38 | static String[] keyObtentionIterationsDefaultList = { 39 | "1000", // default 40 | "1001", 41 | "4000", 42 | "20", 43 | "10000", 44 | "1500", 45 | "13", 46 | "666", 47 | "2000000", 48 | "100", 49 | "253210", 50 | }; 51 | static String[] StringOutputTypeList = { 52 | "base64", // default 53 | "hexadecimal" 54 | }; 55 | 56 | 57 | public Decrypt() throws Exception { 58 | Set> ivclasses = utils.getClasses(ivClass); 59 | System.out.println("[=] Loading iv methods..."); 60 | for(Class c:ivclasses){ 61 | ivClassList.add(c.getName()); 62 | // System.out.println(" - " + c.getName()); 63 | } 64 | System.out.println("[+] Load iv success"); 65 | 66 | Set> saltclasses = utils.getClasses(saltClass); 67 | System.out.println("[=] Loading salt methods..."); 68 | for(Class c:saltclasses){ 69 | saltClassList.add(c.getName()); 70 | // System.out.println(" - " + c.getName()); 71 | } 72 | System.out.println("[+] Load salt success"); 73 | } 74 | 75 | public static boolean doDecrypt(String thisAlogrithm, String password, String encryptedMessage, String keyObtentionIterations, String providerName, String stringOutputType, String ivGeneratorClassName, String saltGeneratorClassName, String poolSize) throws EncryptionInitializationException, EncryptionOperationNotPossibleException{ 76 | try{ 77 | StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor(); 78 | SimpleStringPBEConfig config = new SimpleStringPBEConfig(); 79 | config.setAlgorithm(thisAlogrithm); 80 | config.setPassword(password); 81 | config.setKeyObtentionIterations(keyObtentionIterations); // 设置应用于获取加密密钥的哈希迭代次数 default 1000 82 | config.setProviderName(providerName); // 设置要请求加密算法的安全提供程序的名称 default SunJCE 83 | config.setSaltGeneratorClassName(saltGeneratorClassName); // default org.jasypt.salt.RandomSaltGenerator 84 | config.setStringOutputType(stringOutputType); // 设置字符串输出的编码形式,可用的编码类型有 base64、hexadecimal default base64 85 | config.setIvGeneratorClassName(ivGeneratorClassName); // default org.jasypt.iv.RandomIvGenerator 86 | config.setPoolSize(poolSize); // default 1 87 | encryptor.setConfig(config); 88 | // System.out.println("[-] " + thisAlogrithm + ", " + keyObtentionIterations + ", " + providerName + ", " + stringOutputType + ", " + saltGeneratorClassName); 89 | Decrypt.plaintext = encryptor.decrypt(encryptedMessage); 90 | Decrypt.Talgorithm = thisAlogrithm; 91 | return true; 92 | } 93 | catch (EncryptionInitializationException|EncryptionOperationNotPossibleException|AlreadyInitializedException e) { 94 | // System.out.println(e); 95 | return false; 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/main/java/GetEncode.java: -------------------------------------------------------------------------------- 1 | import java.util.regex.Matcher; 2 | import java.util.regex.Pattern; 3 | 4 | public class GetEncode { 5 | public static boolean isMessyCode(String strName) { 6 | try { 7 | Pattern p = Pattern.compile("\\s*|\t*|\r*|\n*"); 8 | Matcher m = p.matcher(strName); 9 | String after = m.replaceAll(""); 10 | String temp = after.replaceAll("\\p{P}", ""); 11 | char[] ch = temp.trim().toCharArray(); 12 | 13 | int length = (ch != null) ? ch.length : 0; 14 | for (int i = 0; i < length; i++) { 15 | char c = ch[i]; 16 | if (!Character.isLetterOrDigit(c)) { 17 | String str = "" + ch[i]; 18 | if (!str.matches("[\u4e00-\u9fa5]+")) { 19 | return true; 20 | } 21 | } 22 | } 23 | } catch (Exception e) { 24 | e.printStackTrace(); 25 | } 26 | 27 | return false; 28 | } 29 | } -------------------------------------------------------------------------------- /src/main/java/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Main-Class: main 3 | 4 | -------------------------------------------------------------------------------- /src/main/java/main.java: -------------------------------------------------------------------------------- 1 | public class main { 2 | 3 | public static void main(String[] args) throws Exception { 4 | 5 | CLI cli = new CLI(args); 6 | if (cli.parseCLI()) { 7 | Decrypt decrypt = new Decrypt(); 8 | for (String algorithm : decrypt.algorithmList) { 9 | System.out.println("[+] Now Trying " + algorithm); 10 | for (String iv : decrypt.ivClassList) 11 | for (String salt : decrypt.saltClassList) 12 | for (String keyobs : decrypt.keyObtentionIterationsDefaultList) 13 | for (String outtype : decrypt.StringOutputTypeList) { 14 | if (decrypt.doDecrypt( 15 | algorithm, 16 | CLI.password, 17 | CLI.encryptedMessage, 18 | keyobs, 19 | "SunJCE", 20 | outtype, 21 | iv, 22 | salt, 23 | "1" 24 | )) { 25 | if (GetEncode.isMessyCode(decrypt.plaintext)) { 26 | System.out.println("\033[32m[*] " + decrypt.plaintext + "\033[m"); 27 | decrypt.result.add("[?] " + decrypt.plaintext + " : " + decrypt.Talgorithm + ", " + CLI.encryptedMessage + ", " + CLI.password); 28 | } else { 29 | System.out.println("\033[32m[*] " + Decrypt.plaintext + "\033[m"); 30 | decrypt.result.add("[+] " + decrypt.plaintext + " : " + decrypt.Talgorithm + ", " + CLI.encryptedMessage + ", " + CLI.password); 31 | } 32 | } 33 | } 34 | } 35 | if (decrypt.result.size() != 0) { 36 | System.out.println("================================SUCCESS================================"); 37 | for (String s : decrypt.result) 38 | System.out.println(s); 39 | System.out.println("======================================================================="); 40 | } else { 41 | System.out.println("[-] Failed..."); 42 | } 43 | } 44 | 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/utils.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | import java.io.FileFilter; 3 | import java.io.IOException; 4 | import java.net.JarURLConnection; 5 | import java.net.URL; 6 | import java.net.URLDecoder; 7 | import java.util.Enumeration; 8 | import java.util.LinkedHashSet; 9 | import java.util.Set; 10 | import java.util.jar.JarEntry; 11 | import java.util.jar.JarFile; 12 | 13 | public class utils { 14 | public static Set> getClasses(String pack) throws Exception { 15 | Set> classes = new LinkedHashSet>(); 16 | boolean recursive = true; 17 | String packageDirName = pack.replace('.', '/'); 18 | Enumeration dirs; 19 | try { 20 | dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName); 21 | while (dirs.hasMoreElements()) { 22 | URL url = dirs.nextElement(); 23 | String protocol = url.getProtocol(); 24 | if ("file".equals(protocol)) { 25 | String filePath = URLDecoder.decode(url.getFile(), "UTF-8"); 26 | findClassesInPackageByFile(pack, filePath, recursive, classes); 27 | } else if ("jar".equals(protocol)) { 28 | // System.out.println("jar类型的扫描"); 29 | JarFile jar; 30 | try { 31 | jar = ((JarURLConnection) url.openConnection()).getJarFile(); 32 | Enumeration entries = jar.entries(); 33 | findClassesInPackageByJar(pack, entries, packageDirName, recursive, classes); 34 | } catch (IOException e) { 35 | e.printStackTrace(); 36 | } 37 | } 38 | } 39 | } catch (IOException e) { 40 | e.printStackTrace(); 41 | } 42 | return classes; 43 | } 44 | 45 | private static void findClassesInPackageByFile(String packageName, String packagePath, final boolean recursive, Set> classes) { 46 | File dir = new File(packagePath); 47 | if (!dir.exists() || !dir.isDirectory()) { 48 | return; 49 | } 50 | File[] dirfiles = dir.listFiles(new FileFilter() { 51 | @Override 52 | public boolean accept(File file) { 53 | return (recursive && file.isDirectory()) || (file.getName().endsWith(".class")); 54 | } 55 | }); 56 | for (File file : dirfiles) { 57 | if (file.isDirectory()) { 58 | findClassesInPackageByFile(packageName + "." + file.getName(), file.getAbsolutePath(), recursive, classes); 59 | } else { 60 | String className = file.getName().substring(0, file.getName().length() - 6); 61 | try { 62 | classes.add(Thread.currentThread().getContextClassLoader().loadClass(packageName + '.' + className)); 63 | } catch (ClassNotFoundException e) { 64 | e.printStackTrace(); 65 | } 66 | } 67 | } 68 | } 69 | 70 | private static void findClassesInPackageByJar(String packageName, Enumeration entries, String packageDirName, final boolean recursive, Set> classes) { 71 | while (entries.hasMoreElements()) { 72 | JarEntry entry = entries.nextElement(); 73 | String name = entry.getName(); 74 | if (name.charAt(0) == '/') { 75 | name = name.substring(1); 76 | } 77 | if (name.startsWith(packageDirName)) { 78 | int idx = name.lastIndexOf('/'); 79 | if (idx != -1) { 80 | packageName = name.substring(0, idx).replace('/', '.'); 81 | } 82 | if ((idx != -1) || recursive) { 83 | if (name.endsWith(".class") && !entry.isDirectory()) { 84 | String className = name.substring(packageName.length() + 1, name.length() - 6); 85 | try { 86 | classes.add(Class.forName(packageName + '.' + className)); 87 | } catch (ClassNotFoundException e) { 88 | e.printStackTrace(); 89 | } 90 | } 91 | } 92 | } 93 | } 94 | } 95 | } 96 | 97 | 98 | --------------------------------------------------------------------------------