RSA加密登录时账号和密码

This commit is contained in:
WrV
2022-02-09 16:50:22 +08:00
parent 612c4293d1
commit 94c81296d0
11 changed files with 560 additions and 375 deletions

View File

@ -0,0 +1,61 @@
package com.ruoyi.framework.aspectj;
import com.ruoyi.common.annotation.DecryptLogin;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.model.LoginBody;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.user.UserException;
import com.ruoyi.common.utils.StringUtils;
import org.apache.commons.codec.binary.Base64;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
/**
* RSA解密
*
* @author wrw
*/
@Aspect
@Component
public class DecryptParameters {
@Autowired
private RedisCache redisCache;
@Before("@annotation(decrypt)")
public void doBefore(JoinPoint point, DecryptLogin decrypt) throws IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, NoSuchPaddingException {
LoginBody pointArg = (LoginBody) point.getArgs()[0];
//从缓存里获取私钥
String loginPrivateKey = redisCache.getCacheObject(Constants.PRE_LOGIN_KEY + pointArg.getPublicKey());
if (StringUtils.isEmpty(loginPrivateKey)) {
throw new UserException("RSA密钥对已过期", point.getArgs());
}
//初始化解密密钥
PKCS8EncodedKeySpec pkcs8EncodedKeySpec5 = new PKCS8EncodedKeySpec(Base64.decodeBase64(loginPrivateKey));
//创建密钥工厂
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
//解析密钥
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec5);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
//解密
byte[] username = cipher.doFinal(Base64.decodeBase64(pointArg.getUsername()));
byte[] password = cipher.doFinal(Base64.decodeBase64(pointArg.getPassword()));
pointArg.setUsername(new String(username));
pointArg.setPassword(new String(password));
}
}

View File

@ -97,7 +97,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
// 过滤请求
.authorizeRequests()
// 对于登录login 注册register 验证码captchaImage 允许匿名访问
.antMatchers("/login", "/register", "/captchaImage").anonymous()
.antMatchers("/preLogin", "/login", "/register", "/captchaImage").anonymous()
.antMatchers(
HttpMethod.GET,
"/",

View File

@ -1,6 +1,8 @@
package com.ruoyi.framework.web.service;
import javax.annotation.Resource;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
@ -24,6 +26,9 @@ import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysUserService;
import java.security.*;
import java.util.concurrent.TimeUnit;
/**
* 登录校验方法
*
@ -130,4 +135,25 @@ public class SysLoginService
sysUser.setLoginDate(DateUtils.getNowDate());
userService.updateUserProfile(sysUser);
}
/**
* 生成RSA密钥对
* @return 公钥
*/
public String generateRSA() throws NoSuchAlgorithmException, NoSuchProviderException {
KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA", "SunRsaSign");
gen.initialize(512, new SecureRandom());
KeyPair pair = gen.generateKeyPair();
byte[] privateKey = pair.getPrivate().getEncoded();
byte[] publicKey = pair.getPublic().getEncoded();
privateKey = Base64.encodeBase64(privateKey);
publicKey = Base64.encodeBase64(publicKey);
//私钥存入缓存
redisCache.setCacheObject(Constants.PRE_LOGIN_KEY + new String(publicKey), new String(privateKey), 30, TimeUnit.SECONDS);
//返回公钥
return new String(publicKey);
}
}