用户加密漏洞

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 com.bonus.sgzb.system.api.domain.SysUser;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 用户信息
*
* @author ruoyi
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class LoginUser implements Serializable
{
private static final long serialVersionUID = 1L;
/**
* 初级唯一标识 1
*/
private Integer code;
/**
* 用户唯一标识
*/

View File

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

View File

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

View File

@ -57,6 +57,9 @@ public class TokenService
loginUser.setUserid(userId);
loginUser.setUsername(userName);
loginUser.setIpaddr(IpUtils.getIpAddr());
if (StringUtils.isNotBlank(loginUser.getSysUser().getPassword())) {
loginUser.getSysUser().setPassword(null);
}
refreshToken(loginUser);
// Jwt存储信息
@ -77,6 +80,7 @@ public class TokenService
loginUser.getSysUser().setPassword("");
rspMap.put("login_user", loginUser);
rspMap.put("status", "0");
rspMap.put("code", loginUser.getCode());
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;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.List;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletResponse;
import com.bonus.sgzb.common.core.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
@ -32,6 +38,7 @@ import com.bonus.sgzb.system.service.ISysConfigService;
@RequestMapping("/config")
public class SysConfigController extends BaseController
{
private final String CONFIG_KEY = "sys.user.initPassword";
@Autowired
private ISysConfigService configService;
@ -40,10 +47,23 @@ public class SysConfigController extends BaseController
*/
@RequiresPermissions("system:config:list")
@GetMapping("/list")
public TableDataInfo list(SysConfig config)
{
public TableDataInfo list(SysConfig config) throws Exception {
startPage();
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);
}
@ -70,9 +90,21 @@ public class SysConfigController extends BaseController
* 根据参数键名查询参数值
*/
@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;
import com.bonus.sgzb.common.core.utils.StringHelper;
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.service.SysFileService;
import io.swagger.annotations.ApiOperation;
@ -19,6 +19,8 @@ import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
/**
* @author bns
@ -30,6 +32,10 @@ public class SysFileController {
@Resource
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
private ResourceLoader resourceLoader;
@ -41,8 +47,14 @@ public class SysFileController {
FileInfo file = new FileInfo();
try {
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)){
return AjaxResult.error("上传文件字数超出限制字数!");
return AjaxResult.error(ErrorCode.ATTACHMENT_UPLOAD_FAILED.getCode(),
ErrorCode.ATTACHMENT_UPLOAD_FAILED.getMessage());
}
}catch (Exception e){
e.printStackTrace();
@ -50,7 +62,8 @@ public class SysFileController {
if (file != null && file.getId() != 0){
return AjaxResult.success(file);
}else {
return AjaxResult.error("文件上传失败!");
return AjaxResult.error(ErrorCode.FAILURE_TO_UPLOAD_FILE.getCode(),
ErrorCode.FAILURE_TO_UPLOAD_FILE.getMessage());
}
}

View File

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