用户加密漏洞

This commit is contained in:
mashuai 2024-05-23 19:26:58 +08:00
parent 2dc4b86384
commit 513ac105c8
8 changed files with 125 additions and 21 deletions

View File

@ -4,16 +4,26 @@ import java.io.Serializable;
import java.util.Set; import java.util.Set;
import com.bonus.sgzb.system.api.domain.SysUser; import com.bonus.sgzb.system.api.domain.SysUser;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/** /**
* 用户信息 * 用户信息
* *
* @author ruoyi * @author ruoyi
*/ */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class LoginUser implements Serializable public class LoginUser implements Serializable
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/**
* 初级唯一标识 1
*/
private Integer code;
/** /**
* 用户唯一标识 * 用户唯一标识
*/ */

View File

@ -45,6 +45,8 @@ import java.util.Map;
@Slf4j @Slf4j
public class TokenController { public class TokenController {
private final String USER_PASSWORD = "NwCc@2024*";
@Autowired @Autowired
private TokenService tokenService; private TokenService tokenService;
@ -83,15 +85,24 @@ public class TokenController {
String decryptedData = new String(decryptedBytes, StandardCharsets.UTF_8); String decryptedData = new String(decryptedBytes, StandardCharsets.UTF_8);
// 用户登录 // 用户登录
LoginUser userInfo = sysLoginService.login(form.getUsername(), decryptedData); LoginUser userInfo = sysLoginService.login(form.getUsername(), decryptedData);
if (decryptedData.equals(USER_PASSWORD)) {
userInfo.setCode(1);
}
String uuid = form.getUuid(); String uuid = form.getUuid();
String captcha = redisService.getCacheObject(CacheConstants.CAPTCHA_CODE_KEY + uuid).toString(); String captcha = redisService.getCacheObject(CacheConstants.CAPTCHA_CODE_KEY + uuid).toString();
if (StringUtils.isBlank(captcha)) { if (StringUtils.isBlank(captcha)) {
// 删除验证码缓存
redisService.deleteObject(CacheConstants.CAPTCHA_CODE_KEY + uuid);
return R.fail("验证码超时,请重新刷新"); return R.fail("验证码超时,请重新刷新");
} }
if (form.getCode() != null && form.getCode().equals(captcha)) { if (form.getCode() != null && form.getCode().equals(captcha)) {
// 删除验证码缓存
redisService.deleteObject(CacheConstants.CAPTCHA_CODE_KEY + uuid);
// 获取登录token // 获取登录token
return R.ok(tokenService.createToken(userInfo)); return R.ok(tokenService.createToken(userInfo));
} else { } else {
// 删除验证码缓存
redisService.deleteObject(CacheConstants.CAPTCHA_CODE_KEY + uuid);
return R.fail("验证码错误"); return R.fail("验证码错误");
} }
} }

View File

@ -75,7 +75,7 @@ public class SysLoginService {
if (StringUtils.isNull(userResult) || StringUtils.isNull(userResult.getData())) { if (StringUtils.isNull(userResult) || StringUtils.isNull(userResult.getData())) {
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "登录用户不存在"); recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "登录用户不存在");
throw new ServiceException("登录用户:" + username + " 不存在"); throw new ServiceException("用户名不存在/密码错误");
} }
if (R.FAIL == userResult.getCode()) { if (R.FAIL == userResult.getCode()) {

View File

@ -57,6 +57,9 @@ public class TokenService
loginUser.setUserid(userId); loginUser.setUserid(userId);
loginUser.setUsername(userName); loginUser.setUsername(userName);
loginUser.setIpaddr(IpUtils.getIpAddr()); loginUser.setIpaddr(IpUtils.getIpAddr());
if (StringUtils.isNotBlank(loginUser.getSysUser().getPassword())) {
loginUser.getSysUser().setPassword(null);
}
refreshToken(loginUser); refreshToken(loginUser);
// Jwt存储信息 // Jwt存储信息
@ -77,6 +80,7 @@ public class TokenService
loginUser.getSysUser().setPassword(""); loginUser.getSysUser().setPassword("");
rspMap.put("login_user", loginUser); rspMap.put("login_user", loginUser);
rspMap.put("status", "0"); rspMap.put("status", "0");
rspMap.put("code", loginUser.getCode());
return rspMap; return rspMap;
} }

View File

@ -0,0 +1,36 @@
package com.bonus.sgzb.system.config;
/**
* @Author ma_sh
* @create 2024/5/23 10:50
*/
public enum ErrorCode {
ATTACHMENT_UPLOAD_FAILED("4135", "上传文件字数超出限制字数!"),
FAILURE_TO_UPLOAD_FILE("4136", "文件上传失败!"),
COMMISSION_BILL_ATTACHMENT_NOT_SUPPORT("4140", "上传文件格式不支持!");
private String code;
private String message;
ErrorCode(String code, String message) {
this.code = code;
this.message = message;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

@ -1,7 +1,13 @@
package com.bonus.sgzb.system.controller; package com.bonus.sgzb.system.controller;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.List; import java.util.List;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import com.bonus.sgzb.common.core.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.DeleteMapping;
@ -32,6 +38,7 @@ import com.bonus.sgzb.system.service.ISysConfigService;
@RequestMapping("/config") @RequestMapping("/config")
public class SysConfigController extends BaseController public class SysConfigController extends BaseController
{ {
private final String CONFIG_KEY = "sys.user.initPassword";
@Autowired @Autowired
private ISysConfigService configService; private ISysConfigService configService;
@ -40,10 +47,23 @@ public class SysConfigController extends BaseController
*/ */
@RequiresPermissions("system:config:list") @RequiresPermissions("system:config:list")
@GetMapping("/list") @GetMapping("/list")
public TableDataInfo list(SysConfig config) public TableDataInfo list(SysConfig config) throws Exception {
{
startPage(); startPage();
List<SysConfig> list = configService.selectConfigList(config); List<SysConfig> list = configService.selectConfigList(config);
for (SysConfig sysConfig : list) {
if (CONFIG_KEY.equals(sysConfig.getConfigKey()) && StringUtils.isNotBlank(sysConfig.getConfigValue())) {
// 定义密钥
String key = "CCNWrpassWordKey";
SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");
// 使用ECB模式简化示例实际推荐CBC
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
String data = sysConfig.getConfigValue();
byte[] encryptedBytes = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
String configValue = Base64.getEncoder().encodeToString(encryptedBytes);
sysConfig.setConfigValue(configValue);
}
}
return getDataTable(list); return getDataTable(list);
} }
@ -70,9 +90,21 @@ public class SysConfigController extends BaseController
* 根据参数键名查询参数值 * 根据参数键名查询参数值
*/ */
@GetMapping(value = "/configKey/{configKey}") @GetMapping(value = "/configKey/{configKey}")
public AjaxResult getConfigKey(@PathVariable String configKey) public AjaxResult getConfigKey(@PathVariable String configKey) throws Exception
{ {
return success(configService.selectConfigByKey(configKey)); String configByKey = configService.selectConfigByKey(configKey);
if (CONFIG_KEY.equals(configKey) && StringUtils.isNotBlank(configByKey)) {
// 定义密钥
String key = "CCNWrpassWordKey";
SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");
// 使用ECB模式简化示例实际推荐CBC
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
byte[] encryptedBytes = cipher.doFinal(configByKey.getBytes(StandardCharsets.UTF_8));
String configValue = Base64.getEncoder().encodeToString(encryptedBytes);
return AjaxResult.success(configValue);
}
return AjaxResult.success(configByKey);
} }
/** /**

View File

@ -1,7 +1,7 @@
package com.bonus.sgzb.system.controller; package com.bonus.sgzb.system.controller;
import com.bonus.sgzb.common.core.utils.StringHelper;
import com.bonus.sgzb.common.core.web.domain.AjaxResult; import com.bonus.sgzb.common.core.web.domain.AjaxResult;
import com.bonus.sgzb.system.config.ErrorCode;
import com.bonus.sgzb.system.domain.FileInfo; import com.bonus.sgzb.system.domain.FileInfo;
import com.bonus.sgzb.system.service.SysFileService; import com.bonus.sgzb.system.service.SysFileService;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
@ -19,6 +19,8 @@ import javax.servlet.http.HttpServletResponse;
import java.io.InputStream; import java.io.InputStream;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
/** /**
* @author bns * @author bns
@ -30,6 +32,10 @@ public class SysFileController {
@Resource @Resource
private SysFileService service; private SysFileService service;
public final static List<String> ATTACHMENT_FILE_SUFFIX = Arrays.asList("doc","txt","docx","pdf","rft","rar","xlsx","xls");
public final static List<String> COST_FILE_SUFFIX = Arrays.asList("jpg", "png", "pdf");
@Resource @Resource
private ResourceLoader resourceLoader; private ResourceLoader resourceLoader;
@ -41,8 +47,14 @@ public class SysFileController {
FileInfo file = new FileInfo(); FileInfo file = new FileInfo();
try { try {
file = service.uploadFile(request); file = service.uploadFile(request);
String suffix = file.getFileName().substring(file.getFileName().lastIndexOf(".") + 1);
if (! ATTACHMENT_FILE_SUFFIX.contains(suffix) || ! COST_FILE_SUFFIX.contains(suffix)) {
return AjaxResult.error(ErrorCode.COMMISSION_BILL_ATTACHMENT_NOT_SUPPORT.getCode(),
ErrorCode.COMMISSION_BILL_ATTACHMENT_NOT_SUPPORT.getMessage());
}
if (limitWords != null && file.getWords() > Integer.parseInt(limitWords)){ if (limitWords != null && file.getWords() > Integer.parseInt(limitWords)){
return AjaxResult.error("上传文件字数超出限制字数!"); return AjaxResult.error(ErrorCode.ATTACHMENT_UPLOAD_FAILED.getCode(),
ErrorCode.ATTACHMENT_UPLOAD_FAILED.getMessage());
} }
}catch (Exception e){ }catch (Exception e){
e.printStackTrace(); e.printStackTrace();
@ -50,7 +62,8 @@ public class SysFileController {
if (file != null && file.getId() != 0){ if (file != null && file.getId() != 0){
return AjaxResult.success(file); return AjaxResult.success(file);
}else { }else {
return AjaxResult.error("文件上传失败!"); return AjaxResult.error(ErrorCode.FAILURE_TO_UPLOAD_FILE.getCode(),
ErrorCode.FAILURE_TO_UPLOAD_FILE.getMessage());
} }
} }

View File

@ -63,19 +63,17 @@ public class SysConfigServiceImpl implements ISysConfigService
@Override @Override
public String selectConfigByKey(String configKey) public String selectConfigByKey(String configKey)
{ {
String configValue = Convert.toStr(redisService.getCacheObject(getCacheKey(configKey))); String configValue = Convert.toStr(redisService.getCacheObject(getCacheKey(configKey)));
if (StringUtils.isNotEmpty(configValue)) if (StringUtils.isNotEmpty(configValue)) {
{ return configValue;
return configValue; }
} SysConfig config = new SysConfig();
SysConfig config = new SysConfig(); config.setConfigKey(configKey);
config.setConfigKey(configKey); SysConfig retConfig = configMapper.selectConfig(config);
SysConfig retConfig = configMapper.selectConfig(config); if (StringUtils.isNotNull(retConfig)) {
if (StringUtils.isNotNull(retConfig)) redisService.setCacheObject(getCacheKey(configKey), retConfig.getConfigValue());
{ return retConfig.getConfigValue();
redisService.setCacheObject(getCacheKey(configKey), retConfig.getConfigValue()); }
return retConfig.getConfigValue();
}
return StringUtils.EMPTY; return StringUtils.EMPTY;
} }