import java.io.File; import java.io.FileWriter; import java.io.PrintWriter; import java.math.BigDecimal; import java.math.RoundingMode; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESKeySpec; public class RelynDictionary { // 密码可能会包含的字符集合 private static char[] fullCharSource = { '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '{', '}', '|', ':', '"', '<', '>', '?', ';', '\'', ',', '.', '/', '-', '=', '`' }; // private static char[] fullCharSource = { '1','2','3','4','5','6','7','8','9','0', // 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', // 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'}; // private static char[] fullCharSource = { '1','2','3','4','5','6','7','8','9','0', // 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}; // private static char[] fullCharSource = { '1','2','3','4','5','6','7','8','9','0'}; // 密码集合长度 private static int fullCharLength = fullCharSource.length; public static void main(String[] args) { // 明文 String plainText = "123123"; // 密文 String secretCode = "1B0C23406F38F1AE"; // 密钥位数 int keyLength = 8; // DES密钥爆破 RelynDictionary.generate(keyLength, plainText, secretCode); } public static void generate(int passLength, String plainText, String secretCode) { System.out.println("预设密码长度:" + passLength); System.out.println("组成密码的字符个数:" + fullCharLength); System.out.println("密码组合总数量(" + fullCharLength + "^" + passLength + "):" + Math.pow(fullCharLength, passLength)); // x(1-x^n)/(1-x) BigDecimal allCounter = new BigDecimal(fullCharLength); BigDecimal a = allCounter.multiply(new BigDecimal(1).subtract(allCounter.pow(passLength))); BigDecimal b = new BigDecimal(1).subtract(allCounter); BigDecimal c = allCounter.multiply(new BigDecimal(1).subtract(allCounter.pow(passLength - 1))); BigDecimal d = new BigDecimal(1).subtract(allCounter); BigDecimal allPassword = a.divide(b, RoundingMode.HALF_UP).subtract(c.divide(d, RoundingMode.HALF_UP)); BigDecimal startPos = c.divide(d, RoundingMode.HALF_UP); System.out.println("密码组开始位置 >> " + startPos); System.out.println("密码组合总数量 >> " + allPassword); try { Thread.sleep(3000); } catch (InterruptedException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } BigDecimal counter = startPos; // 起始位 StringBuilder buider = new StringBuilder(); while (buider.toString().length() <= passLength) { buider = new StringBuilder(passLength * 2); BigDecimal myCounter = counter; // 10进制转换成26进制 while (myCounter.compareTo(new BigDecimal(fullCharLength)) == 1 || myCounter.compareTo(new BigDecimal(fullCharLength)) == 0) { // 获得低位 buider.append(fullCharSource[myCounter.divideAndRemainder(new BigDecimal(fullCharLength))[1].intValue()]); myCounter = myCounter.divide(new BigDecimal(fullCharLength), RoundingMode.HALF_UP); // 处理进制体系中只有10没有01的问题,在穷举里面是可以存在01的 myCounter = myCounter.subtract(new BigDecimal(1)); } // 最高位 buider.append(fullCharSource[myCounter.intValue()]); counter = counter.add(new BigDecimal(1)); String password = buider.toString(); String secret = ""; try { secret = encodeECB(plainText, password); BigDecimal finish = counter.subtract(startPos).divide(allPassword, 10, RoundingMode.HALF_UP) .multiply(new BigDecimal(100)); System.out.println(password + " >> " + secret + " >> " + counter + "......" + finish + "%"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } if (secretCode.equals(secret)) { System.out.println("找到密钥:" + password); try { File file = new File("pass.txt"); if (!file.exists()) file.createNewFile(); FileWriter fw = new FileWriter(file, true); PrintWriter pw = new PrintWriter(fw); pw.println(password); pw.flush(); fw.flush(); pw.close(); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } return; } } } /** * DES加密ECB * * @param HexString 字符串(16位16进制字符串) * @param keyStr 密钥 * @param keyENCODED Keybyte转换编码 * @param HexStringENCODED 要加密值的转换byte编码 * @param CipherInstanceType 需要加密类型 * @return * @throws Exception */ public static String encodeECB(String HexString, String keyStr) throws Exception { String jmstr = ""; try { byte[] theKey = null; theKey = keyStr.getBytes("UTF-8"); Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); DESKeySpec desKeySpec = new DESKeySpec(theKey); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); SecretKey secretKey = keyFactory.generateSecret(desKeySpec); cipher.init(Cipher.ENCRYPT_MODE, secretKey); byte[] theCph = cipher.doFinal(HexString.getBytes("UTF-8")); jmstr = toHexString(theCph).toUpperCase(); } catch (Exception e) { e.printStackTrace(); return null; } return jmstr; } public static String toHexString(byte b[]) { StringBuffer hexString = new StringBuffer(); for (int i = 0; i < b.length; i++) { String plainText = Integer.toHexString(0xff & b[i]); if (plainText.length() < 2) plainText = "0" + plainText; hexString.append(plainText); } return hexString.toString(); } }