1.rsa工具类
1.1参考demo:
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import java.security.*;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
/**
Hello RSA!
/
public class RSAUtils
{
private static Map keyMap=new HashMap<>();
public static void main( String[] args ) throws Exception {//生成公钥和私钥 getKeyPair(); //加密字符串 String password111="liupengkun"; System.out.println("随机生成的公钥为:"+keyMap.get(0)); System.out.println("随机生成的私钥为:"+keyMap.get(1)); String passwordEn=encrypt(password,keyMap.get(0)); System.out.println(password+"\t加密后的字符串为:"+passwordEn); String passwordDe=decrypt(passwordEn,keyMap.get(1)); System.out.println("还原后的字符串为:"+passwordDe);
}
/**- 随机生成密钥对
- @throws NoSuchAlgorithmException
/
public static void getKeyPair() throws Exception {
//KeyPairGenerator类用于生成公钥和密钥对,基于RSA算法生成对象
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
//初始化密钥对生成器,密钥大小为96-1024位
keyPairGen.initialize(1024,new SecureRandom());
//生成一个密钥对,保存在keyPair中
KeyPair keyPair = keyPairGen.generateKeyPair();
PrivateKey privateKey = keyPair.getPrivate();//得到私钥
PublicKey publicKey = keyPair.getPublic();//得到公钥
//得到公钥字符串
String publicKeyString=new String(Base64.encodeBase64(publicKey.getEncoded()));
//得到私钥字符串
String privateKeyString=new String(Base64.encodeBase64(privateKey.getEncoded()));
//将公钥和私钥保存到Map
keyMap.put(0,publicKeyString);//0表示公钥
keyMap.put(1,privateKeyString);//1表示私钥
}
/* - RSA公钥加密
* - @param str
- 加密字符串
- @param publicKey
- 公钥
- @return 密文
- @throws Exception
加密过程中的异常信息
*/
public static String encrypt(String str,String publicKey) throws Exception {
//base64编码的公钥
byte[] decoded = Base64.decodeBase64(publicKey);
RSAPublicKey pubKey= (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
//RAS加密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE,pubKey);
String outStr=Base64.encodeBase64String(cipher.doFinal(str.getBytes("UTF-8")));
return outStr;
}/**
- RSA私钥解密
* - @param str
- 加密字符串
- @param privateKey
- 私钥
- @return 铭文
- @throws Exception
解密过程中的异常信息
*/
public static String decrypt(String str,String privateKey) throws Exception {
//Base64解码加密后的字符串
byte[] inputByte = Base64.decodeBase64(str.getBytes("UTF-8"));
//Base64编码的私钥
byte[] decoded = Base64.decodeBase64(privateKey);
PrivateKey priKey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
//RSA解密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE,priKey);
String outStr=new String(cipher.doFinal(inputByte));
return outStr;}
}
1.2 集成实例
package com.AAA.common.utils;
import com.ruoyi.common.exception.user.CustomException;
import org.apache.commons.codec.binary.Base64;
import org.springframework.stereotype.Component;
import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
/**
- RSA!
- wangwei
- rsa加密解密
2023-05-12 09:31
*/
@Component
public class RSAUtils {public static String privateKeys = "";
private static final String publicKeyStr = "1111";
private static final String privateKeyStr = "2222";
// private static final RsaKeyPair rsaKeyPair = new RsaKeyPair();/*
- 公钥加密
password :明文密码
*/
public static String encryptByPublicKey(String password) {
try {String encrypt = encrypt(password, publicKeyStr); return encrypt;
} catch (Exception e) {
e.printStackTrace();
}
throw new CustomException("加密失败!");
}/*
- 私钥解密
- 将加密后的字符串 转换成明文
text:为加密后的字符串
/
public static String encryptByPrivateKey(String text) /throws Exception */ {
try {String password = decryptByPrivateKey(text, privateKeyStr); return password;
} catch (Exception e) {
e.printStackTrace();
}
throw new CustomException("解密失败!");
}public static String encrypt(String str, String publicKey) throws Exception {
//base64编码的公钥
byte[] decoded = Base64.decodeBase64(publicKey);
RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
//RAS加密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
String outStr = Base64.encodeBase64String(cipher.doFinal(str.getBytes("UTF-8")));
return outStr;
}/**
- RSA私钥解密
* - @param str 加密字符串
- @param privateKey 私钥
- @return 铭文
@throws Exception 解密过程中的异常信息
*/
public static String decryptByPrivateKey(String str, String privateKey) throws Exception {
//Base64解码加密后的字符串
byte[] inputByte = Base64.decodeBase64(str.getBytes("UTF-8"));
//Base64编码的私钥
byte[] decoded = Base64.decodeBase64(privateKey);
PrivateKey priKey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
//RSA解密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, priKey);
String outStr = new String(cipher.doFinal(inputByte));
return outStr;
}public static String getPublicKey() {
return publicKeyStr;
}public static String getPrivateKey() {
return privateKeyStr;
}/**
RSA密钥对对象
*/
public static class RsaKeyPair {
private String publicKey;
private String privateKey;public void setPublicKey(String publicKey) {
this.publicKey = publicKey;
}
public void setPrivateKey(String privateKey) {this.privateKey = privateKey;
}
public RsaKeyPair() {
}
public RsaKeyPair(String publicKey, String privateKey) {
this.publicKey = publicKey; this.privateKey = privateKey;
}
public String getPublicKey() {
return publicKey;
}
public String getPrivateKey() {return privateKey;
}
}
}
2.1对用户的密码加密 入数据库
/**
* 新增用户
*/
@PreAuthorize("@ss.hasPermi('system:user:add')")
@Log(title = "用户管理", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@Validated @RequestBody SysUser user) {
if (!userService.checkUserNameUnique(user)) {
return error("新增用户'" + user.getUserName() + "'失败,登录账号已存在");
} else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) {
return error("新增用户'" + user.getUserName() + "'失败,手机号码已存在");
} else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) {
return error("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在");
}
user.setCreateBy(getUsername());
//user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
String password = user.getPassword();
String s = RSAUtils.encryptByPublicKey(password);
user.setPassword(s);
//解密
String aa = "这里是你的私钥";
String s1 = RSAUtils.encryptByPrivateKey(aa);
System.out.printf("解密:明文: " + s1);
return toAjax(userService.insertUser(user));
}
/**
* 修改用户
*/
@PreAuthorize("@ss.hasPermi('system:user:edit')")
@Log(title = "用户管理", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@Validated @RequestBody SysUser user) {
userService.checkUserAllowed(user);
userService.checkUserDataScope(user.getUserId());
if (!userService.checkUserNameUnique(user)) {
return error("修改用户'" + user.getUserName() + "'失败,登录账号已存在");
} else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) {
return error("修改用户'" + user.getUserName() + "'失败,手机号码已存在");
} else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) {
return error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在");
}
user.setUpdateBy(getUsername());
String password = user.getPassword();
String s = RSAUtils.encryptByPublicKey(password);
user.setPassword(s);
return toAjax(userService.updateUser(user));
}
3.1 用户登录接口 改造
/**
* 登录方法
*
* @param loginBody 登录信息
* @return 结果
*/
@PostMapping("/login")
public AjaxResult login(@RequestBody LoginBody loginBody)
{
AjaxResult ajax = AjaxResult.success();
// 生成令牌
String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
loginBody.getUuid());
ajax.put(Constants.TOKEN, token);
return ajax;
}
/**
* 登录验证
*
* @param username 用户名
* @param password 密码
* @param code 验证码
* @param uuid 唯一标识
* @return 结果
*/
public String login(String username, String password, String code, String uuid){
// 验证码校验
// todo validateCaptcha(username, code, uuid);
SysUser sysUser = sysUserMapper.selectUserByUserName(username);
if(StringUtils.isEmpty(sysUser.getUserName())){
throw new CustomException("账号不存在,请仔细检查!");
}
String password1 = sysUser.getPassword();
String s = "";
try {
String s1 = RSAUtils.decryptByPrivateKey(password1, RSAUtils.getPrivateKey());
s = s1;
} catch (Exception e) {
e.printStackTrace();
}
if(!password.equals(s)){
throw new CustomException("密码错误,请仔细检查!");
}
LoginUser loginUser = new LoginUser();
loginUser.setUserId(sysUser.getUserId());
loginUser.setDeptId(sysUser.getDeptId());
loginUser.setUser(sysUser);
Set<String> permissions = permissionService.getMenuPermission(sysUser);
loginUser.setPermissions(permissions);
return tokenService.createToken(loginUser);
}
4.1 加密后的密文
4.2 密文解密:
5.1 单点登录
/**
* 第三方登录
*
* @param loginBody 登录信息
* @return 结果
*/
@ApiOperation(value = "第三方系统登录XXX管理系统")
@PostMapping("/convenient/login")
public AjaxResult convenientLogin(@RequestBody LoginBody loginBody) throws Exception {
AjaxResult ajax = AjaxResult.success();
//TODO 1.校验身份证合法性
//2.校验身份证是否在【XXX系统中】,有没有这个身份证账号的人
String idnumber = loginBody.getIdnumber();
if (StringUtils.isEmpty(idnumber)) {
throw new CustomException("身份证号码不能为空,请仔细检查!");
}
SysUser sysUser = new SysUser();
sysUser.setIdnumber(idnumber);
List<SysUser> sysUserList = sysUserMapper.selectUserList(sysUser);
if (sysUserList.size() < 1) {
throw new CustomException("登录用户的身份证号码不在【XXX管理系统】中,请联系系统管理员处理!");
}
//3.校验单点登录的用户有没有权限
String userName = sysUserList.get(0).getUserName();
String password = sysUserList.get(0).getPassword();
if (null == sysUserList.get(0).getUserId() || 0 == sysUserList.get(0).getUserId()) {
throw new CustomException(idnumber + " :用户在【XXX系统】中没有维护部门/组织 属性,请联系管理员处理");
}
LoginUser loginUser = new LoginUser();
loginUser.setUserId(sysUserList.get(0).getUserId());
loginUser.setDeptId(sysUserList.get(0).getDeptId());
loginUser.setUser(sysUserList.get(0));
Set<String> permissions = permissionService.getMenuPermission(loginUser.getUser());
loginUser.setPermissions(permissions);
String token = tokenService.createToken(loginUser);
ajax.put(Constants.TOKEN, token);
return ajax;
}