feat:登录国密sm4改造

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

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

@ -4,6 +4,7 @@ import java.util.List;
import java.util.Set;
import com.hyp.common.utils.sign.RsaUtils;
import com.hyp.common.utils.sign.Sm4Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@ -47,7 +48,7 @@ public class SysLoginController
AjaxResult ajax = AjaxResult.success();
// 生成令牌
String token = loginService.login(loginBody.getUsername(),
RsaUtils.decryptByPrivateKey(loginBody.getPassword()), loginBody.getCode());
Sm4Util.decryptEcb(loginBody.getPassword()), loginBody.getCode());
ajax.put(Constants.TOKEN, token);
return ajax;
}
@ -85,4 +86,14 @@ public class SysLoginController
List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId);
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;
import com.hyp.common.utils.sign.Sm4Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@ -25,13 +26,12 @@ import com.hyp.system.service.ISysUserService;
/**
*
*
*
* @author ruoyi
*/
@RestController
@RequestMapping("/system/user/profile")
public class SysProfileController extends BaseController
{
public class SysProfileController extends BaseController {
@Autowired
private ISysUserService userService;
@ -42,8 +42,7 @@ public class SysProfileController extends BaseController
*
*/
@GetMapping
public AjaxResult profile()
{
public AjaxResult profile() {
LoginUser loginUser = getLoginUser();
SysUser user = loginUser.getUser();
AjaxResult ajax = AjaxResult.success(user);
@ -57,24 +56,20 @@ public class SysProfileController extends BaseController
*/
@Log(title = "个人信息", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult updateProfile(@RequestBody SysUser user)
{
public AjaxResult updateProfile(@RequestBody SysUser user) {
LoginUser loginUser = getLoginUser();
SysUser currentUser = loginUser.getUser();
currentUser.setNickName(user.getNickName());
currentUser.setEmail(user.getEmail());
currentUser.setPhonenumber(user.getPhonenumber());
currentUser.setSex(user.getSex());
if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(currentUser))
{
if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(currentUser)) {
return error("修改用户'" + loginUser.getUsername() + "'失败,手机号码已存在");
}
if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(currentUser))
{
if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(currentUser)) {
return error("修改用户'" + loginUser.getUsername() + "'失败,邮箱账号已存在");
}
if (userService.updateUserProfile(currentUser) > 0)
{
if (userService.updateUserProfile(currentUser) > 0) {
// 更新缓存用户信息
tokenService.setLoginUser(loginUser);
return success();
@ -87,24 +82,22 @@ public class SysProfileController extends BaseController
*/
@Log(title = "个人信息", businessType = BusinessType.UPDATE)
@PutMapping("/updatePwd")
public AjaxResult updatePwd(String oldPassword, String newPassword)
{
public AjaxResult updatePwd(String oldPassword, String newPassword) throws Exception {
LoginUser loginUser = getLoginUser();
String userName = loginUser.getUsername();
String password = loginUser.getPassword();
if (!SecurityUtils.matchesPassword(oldPassword, password))
{
//解密
oldPassword = Sm4Util.decryptEcb(oldPassword);
newPassword = Sm4Util.decryptEcb(newPassword);
if (!SecurityUtils.matchesPassword(oldPassword, password)) {
return error("修改密码失败,旧密码错误");
}
if (SecurityUtils.matchesPassword(newPassword, password))
{
if (SecurityUtils.matchesPassword(newPassword, password)) {
return error("新密码不能与旧密码相同");
}
newPassword = SecurityUtils.encryptPassword(newPassword);
if (userService.resetUserPwd(userName, newPassword) > 0)
{
if (userService.resetUserPwd(userName, SecurityUtils.encryptPassword(newPassword)) > 0) {
// 更新缓存用户密码
loginUser.getUser().setPassword(newPassword);
loginUser.getUser().setPassword(SecurityUtils.encryptPassword(newPassword));
tokenService.setLoginUser(loginUser);
return success();
}
@ -116,14 +109,11 @@ public class SysProfileController extends BaseController
*/
@Log(title = "用户头像", businessType = BusinessType.UPDATE)
@PostMapping("/avatar")
public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file) throws Exception
{
if (!file.isEmpty())
{
public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file) throws Exception {
if (!file.isEmpty()) {
LoginUser loginUser = getLoginUser();
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();
ajax.put("imgUrl", avatar);
// 更新缓存用户头像

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

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

@ -74,5 +74,5 @@ public class UserConstants
*
*/
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()
// 对于登录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("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()

@ -1,6 +1,7 @@
package com.hyp.framework.web.service;
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.mapper.SysUserRoleMapper;
import com.hyp.system.service.ISysRoleService;
@ -55,8 +56,8 @@ public class SysRegisterService
*
*/
@Transactional(rollbackFor = Exception.class)
public String register(RegisterBody registerBody) {
String msg = "", username = registerBody.getUsername(), password = registerBody.getPassword();
public String register(RegisterBody registerBody) throws Exception {
String msg = "", username = registerBody.getUsername(), password = Sm4Util.decryptEcb(registerBody.getPassword());
SysUser sysUser = new SysUser();
sysUser.setUserName(username);

Loading…
Cancel
Save