feat:登录国密sm4改造

dev-sm4
wangxy 4 months ago
parent 11667d7a94
commit d8388e0513

@ -68,6 +68,13 @@
<version>2.1.0</version> <version>2.1.0</version>
</dependency> </dependency>
<!--sm4加密算法依赖-->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.59</version>
</dependency>
<!--单元测试--> <!--单元测试-->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>

@ -4,6 +4,7 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import com.hyp.common.utils.sign.RsaUtils; import com.hyp.common.utils.sign.RsaUtils;
import com.hyp.common.utils.sign.Sm4Util;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -47,7 +48,7 @@ public class SysLoginController
AjaxResult ajax = AjaxResult.success(); AjaxResult ajax = AjaxResult.success();
// 生成令牌 // 生成令牌
String token = loginService.login(loginBody.getUsername(), String token = loginService.login(loginBody.getUsername(),
RsaUtils.decryptByPrivateKey(loginBody.getPassword()), loginBody.getCode()); Sm4Util.decryptEcb(loginBody.getPassword()), loginBody.getCode());
ajax.put(Constants.TOKEN, token); ajax.put(Constants.TOKEN, token);
return ajax; return ajax;
} }
@ -85,4 +86,14 @@ public class SysLoginController
List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId); List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId);
return AjaxResult.success(menuService.buildMenus(menus)); return AjaxResult.success(menuService.buildMenus(menus));
} }
/**
*
*
* @return
*/
@GetMapping("/publicKey")
public String publicKey() throws Exception {
return Sm4Util.hexKey;
}
} }

@ -1,5 +1,6 @@
package com.hyp.web.controller.system; package com.hyp.web.controller.system;
import com.hyp.common.utils.sign.Sm4Util;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -30,8 +31,7 @@ import com.hyp.system.service.ISysUserService;
*/ */
@RestController @RestController
@RequestMapping("/system/user/profile") @RequestMapping("/system/user/profile")
public class SysProfileController extends BaseController public class SysProfileController extends BaseController {
{
@Autowired @Autowired
private ISysUserService userService; private ISysUserService userService;
@ -42,8 +42,7 @@ public class SysProfileController extends BaseController
* *
*/ */
@GetMapping @GetMapping
public AjaxResult profile() public AjaxResult profile() {
{
LoginUser loginUser = getLoginUser(); LoginUser loginUser = getLoginUser();
SysUser user = loginUser.getUser(); SysUser user = loginUser.getUser();
AjaxResult ajax = AjaxResult.success(user); AjaxResult ajax = AjaxResult.success(user);
@ -57,24 +56,20 @@ public class SysProfileController extends BaseController
*/ */
@Log(title = "个人信息", businessType = BusinessType.UPDATE) @Log(title = "个人信息", businessType = BusinessType.UPDATE)
@PutMapping @PutMapping
public AjaxResult updateProfile(@RequestBody SysUser user) public AjaxResult updateProfile(@RequestBody SysUser user) {
{
LoginUser loginUser = getLoginUser(); LoginUser loginUser = getLoginUser();
SysUser currentUser = loginUser.getUser(); SysUser currentUser = loginUser.getUser();
currentUser.setNickName(user.getNickName()); currentUser.setNickName(user.getNickName());
currentUser.setEmail(user.getEmail()); currentUser.setEmail(user.getEmail());
currentUser.setPhonenumber(user.getPhonenumber()); currentUser.setPhonenumber(user.getPhonenumber());
currentUser.setSex(user.getSex()); currentUser.setSex(user.getSex());
if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(currentUser)) if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(currentUser)) {
{
return error("修改用户'" + loginUser.getUsername() + "'失败,手机号码已存在"); return error("修改用户'" + loginUser.getUsername() + "'失败,手机号码已存在");
} }
if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(currentUser)) if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(currentUser)) {
{
return error("修改用户'" + loginUser.getUsername() + "'失败,邮箱账号已存在"); return error("修改用户'" + loginUser.getUsername() + "'失败,邮箱账号已存在");
} }
if (userService.updateUserProfile(currentUser) > 0) if (userService.updateUserProfile(currentUser) > 0) {
{
// 更新缓存用户信息 // 更新缓存用户信息
tokenService.setLoginUser(loginUser); tokenService.setLoginUser(loginUser);
return success(); return success();
@ -87,24 +82,22 @@ public class SysProfileController extends BaseController
*/ */
@Log(title = "个人信息", businessType = BusinessType.UPDATE) @Log(title = "个人信息", businessType = BusinessType.UPDATE)
@PutMapping("/updatePwd") @PutMapping("/updatePwd")
public AjaxResult updatePwd(String oldPassword, String newPassword) public AjaxResult updatePwd(String oldPassword, String newPassword) throws Exception {
{
LoginUser loginUser = getLoginUser(); LoginUser loginUser = getLoginUser();
String userName = loginUser.getUsername(); String userName = loginUser.getUsername();
String password = loginUser.getPassword(); String password = loginUser.getPassword();
if (!SecurityUtils.matchesPassword(oldPassword, password)) //解密
{ oldPassword = Sm4Util.decryptEcb(oldPassword);
newPassword = Sm4Util.decryptEcb(newPassword);
if (!SecurityUtils.matchesPassword(oldPassword, password)) {
return error("修改密码失败,旧密码错误"); return error("修改密码失败,旧密码错误");
} }
if (SecurityUtils.matchesPassword(newPassword, password)) if (SecurityUtils.matchesPassword(newPassword, password)) {
{
return error("新密码不能与旧密码相同"); return error("新密码不能与旧密码相同");
} }
newPassword = SecurityUtils.encryptPassword(newPassword); if (userService.resetUserPwd(userName, SecurityUtils.encryptPassword(newPassword)) > 0) {
if (userService.resetUserPwd(userName, newPassword) > 0)
{
// 更新缓存用户密码 // 更新缓存用户密码
loginUser.getUser().setPassword(newPassword); loginUser.getUser().setPassword(SecurityUtils.encryptPassword(newPassword));
tokenService.setLoginUser(loginUser); tokenService.setLoginUser(loginUser);
return success(); return success();
} }
@ -116,14 +109,11 @@ public class SysProfileController extends BaseController
*/ */
@Log(title = "用户头像", businessType = BusinessType.UPDATE) @Log(title = "用户头像", businessType = BusinessType.UPDATE)
@PostMapping("/avatar") @PostMapping("/avatar")
public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file) throws Exception public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file) throws Exception {
{ if (!file.isEmpty()) {
if (!file.isEmpty())
{
LoginUser loginUser = getLoginUser(); LoginUser loginUser = getLoginUser();
String avatar = FileUploadUtils.upload(HypConfig.getAvatarPath(), file, MimeTypeUtils.IMAGE_EXTENSION); String avatar = FileUploadUtils.upload(HypConfig.getAvatarPath(), file, MimeTypeUtils.IMAGE_EXTENSION);
if (userService.updateUserAvatar(loginUser.getUsername(), avatar)) if (userService.updateUserAvatar(loginUser.getUsername(), avatar)) {
{
AjaxResult ajax = AjaxResult.success(); AjaxResult ajax = AjaxResult.success();
ajax.put("imgUrl", avatar); ajax.put("imgUrl", avatar);
// 更新缓存用户头像 // 更新缓存用户头像

@ -17,8 +17,7 @@ import com.hyp.system.service.ISysConfigService;
* @author ruoyi * @author ruoyi
*/ */
@RestController @RestController
public class SysRegisterController extends BaseController public class SysRegisterController extends BaseController {
{
@Autowired @Autowired
private SysRegisterService registerService; private SysRegisterService registerService;
@ -26,10 +25,8 @@ public class SysRegisterController extends BaseController
private ISysConfigService configService; private ISysConfigService configService;
@PostMapping("/register") @PostMapping("/register")
public AjaxResult register(@RequestBody RegisterBody user) public AjaxResult register(@RequestBody RegisterBody user) throws Exception {
{ if (!("true".equals(configService.selectConfigByKey("sys.account.registerUser")))) {
if (!("true".equals(configService.selectConfigByKey("sys.account.registerUser"))))
{
return error("当前系统没有开启注册功能!"); return error("当前系统没有开启注册功能!");
} }
String msg = registerService.register(user); String msg = registerService.register(user);

@ -143,6 +143,13 @@
<version>2.5.1</version> <version>2.5.1</version>
</dependency> </dependency>
<!--sm4加密算法依赖-->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.59</version>
</dependency>
<dependency> <dependency>
<groupId>org.projectlombok</groupId> <groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId> <artifactId>lombok</artifactId>

@ -74,5 +74,5 @@ public class UserConstants
* *
*/ */
public static final int PASSWORD_MIN_LENGTH = 5; public static final int PASSWORD_MIN_LENGTH = 5;
public static final int PASSWORD_MAX_LENGTH = 20; public static final int PASSWORD_MAX_LENGTH = 20000;
} }

@ -0,0 +1,175 @@
package com.hyp.common.utils.sign;
import java.security.*;
import java.util.Arrays;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.SecretKeySpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
/**
* ClassName: Sm4Util
* Package: com.hyp.common.utils.sign
* sm4
* @explain sm4
*
* @Author wangxy
* @Create 2024/11/28 14:44
* @Version 1.0
*/
public class Sm4Util {
static {
Security.addProvider(new BouncyCastleProvider());
}
private static final String ENCODING = "UTF-8";
public static final String ALGORITHM_NAME = "SM4";
// 加密算法/分组加密模式/分组填充方式
// PKCS5Padding-以8个字节为一组进行分组加密
// 定义分组加密模式使用PKCS5Padding
public static final String ALGORITHM_NAME_ECB_PADDING = "SM4/ECB/PKCS5Padding";
// 128-32位16进制256-64位16进制
public static final int DEFAULT_KEY_SIZE = 128;
/**
* ECBkey
*/
public static final String hexKey = "6fb7b3dcaa041c798c3798abe6f9575c";
/**
* ECB
* @explain ECBElectronic codebook
* @param algorithmName
* @param mode
* @param key
* @return
* @throws Exception
*/
private static Cipher generateEcbCipher(String algorithmName, int mode, byte[] key) throws Exception {
Cipher cipher = Cipher.getInstance(algorithmName, BouncyCastleProvider.PROVIDER_NAME);
Key sm4Key = new SecretKeySpec(key, ALGORITHM_NAME);
cipher.init(mode, sm4Key);
return cipher;
}
/**
*
* @explain
* @return
* @throws NoSuchAlgorithmException
* @throws NoSuchProviderException
*/
public static byte[] generateKey() throws Exception {
return generateKey(DEFAULT_KEY_SIZE);
}
//加密******************************************
/**
* @explain
* @param keySize
* @return
* @throws Exception
*/
public static byte[] generateKey(int keySize) throws Exception {
KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM_NAME, BouncyCastleProvider.PROVIDER_NAME);
kg.init(keySize, new SecureRandom());
return kg.generateKey().getEncoded();
}
/**
* sm4
* @explain ECB
* @param
* @param paramStr
* @return 16
* @throws Exception
*/
public static String encryptEcb(String paramStr) throws Exception {
String cipherText = "";
// 16进制字符串-->byte[]
byte[] keyData = ByteUtils.fromHexString(hexKey);
// String-->byte[]
byte[] srcData = paramStr.getBytes(ENCODING);
// 加密后的数组
byte[] cipherArray = encrypt_Ecb_Padding(keyData, srcData);
// byte[]-->hexString
cipherText = ByteUtils.toHexString(cipherArray);
return cipherText;
}
/**
* Ecb
* @param key
* @param data
* @return
* @throws Exception
*/
public static byte[] encrypt_Ecb_Padding(byte[] key, byte[] data) throws Exception {
Cipher cipher = generateEcbCipher(ALGORITHM_NAME_ECB_PADDING, Cipher.ENCRYPT_MODE, key);//声称Ecb暗号,通过第二个参数判断加密还是解密
return cipher.doFinal(data);
}
//解密****************************************
/**
* sm4
* @explain ECB
* @param
* @param cipherText 16
* @return
* @throws Exception
*/
public static String decryptEcb(String cipherText) throws Exception {
// 用于接收解密后的字符串
String decryptStr = "";
// hexString-->byte[]
byte[] keyData = ByteUtils.fromHexString(hexKey);
// hexString-->byte[]
byte[] cipherData = ByteUtils.fromHexString(cipherText);
// 解密
byte[] srcData = decrypt_Ecb_Padding(keyData, cipherData);
// byte[]-->String
decryptStr = new String(srcData, ENCODING);
return decryptStr;
}
/**
*
* @explain
* @param key
* @param cipherText
* @return
* @throws Exception
*/
public static byte[] decrypt_Ecb_Padding(byte[] key, byte[] cipherText) throws Exception {
Cipher cipher = generateEcbCipher(ALGORITHM_NAME_ECB_PADDING, Cipher.DECRYPT_MODE, key);//生成Ecb暗号,通过第二个参数判断加密还是解密
return cipher.doFinal(cipherText);
}
/**
*
* @explain
* @param
* @param cipherText 16
* @param paramStr
* @return
* @throws Exception
*/
public static boolean verifyEcb(String cipherText, String paramStr) throws Exception {
// 用于接收校验结果
boolean flag = false;
// hexString-->byte[]
byte[] keyData = ByteUtils.fromHexString(hexKey);
// 将16进制字符串转换成数组
byte[] cipherData = ByteUtils.fromHexString(cipherText);
// 解密
byte[] decryptData = decrypt_Ecb_Padding(keyData, cipherData);
// 将原字符串转换成byte[]
byte[] srcData = paramStr.getBytes(ENCODING);
// 判断2个数组是否一致
flag = Arrays.equals(decryptData, srcData);
return flag;
}
}

@ -111,7 +111,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
// 过滤请求 // 过滤请求
.authorizeRequests() .authorizeRequests()
// 对于登录login 注册register 滑块验证码/captcha/get /captcha/check 获取验证码开关 /captchaEnabled 允许匿名访问 // 对于登录login 注册register 滑块验证码/captcha/get /captcha/check 获取验证码开关 /captchaEnabled 允许匿名访问
.antMatchers("/login", "/register", "/captcha/get", "/captcha/check", "/captchaEnabled","/system/dict/data/type/**").permitAll() .antMatchers("/login", "/register", "/captcha/get", "/captcha/check", "/captchaEnabled","/publicKey","/system/dict/data/type/**").permitAll()
// 静态资源,可匿名访问 // 静态资源,可匿名访问
.antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll() .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
.antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll() .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()

@ -1,6 +1,7 @@
package com.hyp.framework.web.service; package com.hyp.framework.web.service;
import com.hyp.common.core.domain.entity.SysRole; import com.hyp.common.core.domain.entity.SysRole;
import com.hyp.common.utils.sign.Sm4Util;
import com.hyp.system.domain.SysUserRole; import com.hyp.system.domain.SysUserRole;
import com.hyp.system.mapper.SysUserRoleMapper; import com.hyp.system.mapper.SysUserRoleMapper;
import com.hyp.system.service.ISysRoleService; import com.hyp.system.service.ISysRoleService;
@ -55,8 +56,8 @@ public class SysRegisterService
* *
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public String register(RegisterBody registerBody) { public String register(RegisterBody registerBody) throws Exception {
String msg = "", username = registerBody.getUsername(), password = registerBody.getPassword(); String msg = "", username = registerBody.getUsername(), password = Sm4Util.decryptEcb(registerBody.getPassword());
SysUser sysUser = new SysUser(); SysUser sysUser = new SysUser();
sysUser.setUserName(username); sysUser.setUserName(username);

Loading…
Cancel
Save