增加请求加密 动态获取密钥
This commit is contained in:
parent
659caa1d0e
commit
596cf10a1c
8
DockerFile_admin
Normal file
8
DockerFile_admin
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# 使用官方的 Java 运行时作为父镜像
|
||||||
|
FROM openjdk:8-jdk-alpine
|
||||||
|
|
||||||
|
# 将本地文件复制到容器中
|
||||||
|
COPY target/my-app.jar /app.jar
|
||||||
|
|
||||||
|
# 运行应用
|
||||||
|
ENTRYPOINT ["java","-jar","/app.jar"]
|
@ -5,8 +5,6 @@ import cn.hutool.core.collection.CollUtil;
|
|||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import com.mybatisflex.core.query.QueryWrapper;
|
import com.mybatisflex.core.query.QueryWrapper;
|
||||||
import com.ruoyi.common.core.constant.UserConstants;
|
import com.ruoyi.common.core.constant.UserConstants;
|
||||||
import com.ruoyi.common.core.core.domain.AjaxResult;
|
|
||||||
import com.ruoyi.common.core.core.domain.model.LoginUser;
|
|
||||||
import com.ruoyi.common.core.core.domain.model.SocialLoginBody;
|
import com.ruoyi.common.core.core.domain.model.SocialLoginBody;
|
||||||
import com.ruoyi.common.core.utils.*;
|
import com.ruoyi.common.core.utils.*;
|
||||||
import com.ruoyi.common.encrypt.annotation.ApiEncrypt;
|
import com.ruoyi.common.encrypt.annotation.ApiEncrypt;
|
||||||
@ -15,13 +13,11 @@ import com.ruoyi.common.security.utils.LoginHelper;
|
|||||||
import com.ruoyi.common.social.config.properties.SocialLoginConfigProperties;
|
import com.ruoyi.common.social.config.properties.SocialLoginConfigProperties;
|
||||||
import com.ruoyi.common.social.config.properties.SocialProperties;
|
import com.ruoyi.common.social.config.properties.SocialProperties;
|
||||||
import com.ruoyi.common.social.utils.SocialUtils;
|
import com.ruoyi.common.social.utils.SocialUtils;
|
||||||
import com.ruoyi.common.tenant.helper.TenantHelper;
|
|
||||||
import com.ruoyi.common.websocket.dto.WebSocketMessageDto;
|
import com.ruoyi.common.websocket.dto.WebSocketMessageDto;
|
||||||
import com.ruoyi.common.websocket.utils.WebSocketUtils;
|
import com.ruoyi.common.websocket.utils.WebSocketUtils;
|
||||||
import com.ruoyi.system.domain.bo.SysTenantBo;
|
import com.ruoyi.system.domain.bo.SysTenantBo;
|
||||||
import com.ruoyi.system.domain.vo.SysClientVo;
|
import com.ruoyi.system.domain.vo.SysClientVo;
|
||||||
import com.ruoyi.system.domain.vo.SysTenantVo;
|
import com.ruoyi.system.domain.vo.SysTenantVo;
|
||||||
import com.ruoyi.system.domain.vo.SysUserVo;
|
|
||||||
import com.ruoyi.system.service.*;
|
import com.ruoyi.system.service.*;
|
||||||
import com.ruoyi.web.domain.vo.LoginTenantVo;
|
import com.ruoyi.web.domain.vo.LoginTenantVo;
|
||||||
import com.ruoyi.web.domain.vo.LoginVo;
|
import com.ruoyi.web.domain.vo.LoginVo;
|
||||||
@ -34,7 +30,6 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import com.ruoyi.common.core.core.domain.R;
|
import com.ruoyi.common.core.core.domain.R;
|
||||||
import com.ruoyi.common.core.core.domain.model.LoginBody;
|
import com.ruoyi.common.core.core.domain.model.LoginBody;
|
||||||
import com.ruoyi.common.core.core.domain.model.RegisterBody;
|
import com.ruoyi.common.core.core.domain.model.RegisterBody;
|
||||||
import com.ruoyi.system.domain.SysClient;
|
|
||||||
import com.ruoyi.web.service.IAuthStrategy;
|
import com.ruoyi.web.service.IAuthStrategy;
|
||||||
import com.ruoyi.web.service.SysLoginService;
|
import com.ruoyi.web.service.SysLoginService;
|
||||||
import me.zhyd.oauth.model.AuthResponse;
|
import me.zhyd.oauth.model.AuthResponse;
|
||||||
|
@ -2,7 +2,10 @@ package com.ruoyi.web.controller;
|
|||||||
|
|
||||||
import cn.dev33.satoken.annotation.SaIgnore;
|
import cn.dev33.satoken.annotation.SaIgnore;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import cn.hutool.captcha.AbstractCaptcha;
|
import cn.hutool.captcha.AbstractCaptcha;
|
||||||
import cn.hutool.captcha.generator.CodeGenerator;
|
import cn.hutool.captcha.generator.CodeGenerator;
|
||||||
@ -10,11 +13,13 @@ import cn.hutool.core.util.IdUtil;
|
|||||||
import cn.hutool.core.util.RandomUtil;
|
import cn.hutool.core.util.RandomUtil;
|
||||||
import com.ruoyi.common.core.annotation.RateLimiter;
|
import com.ruoyi.common.core.annotation.RateLimiter;
|
||||||
import com.ruoyi.common.core.constant.GlobalConstants;
|
import com.ruoyi.common.core.constant.GlobalConstants;
|
||||||
|
import com.ruoyi.common.core.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.core.enums.LimitType;
|
import com.ruoyi.common.core.enums.LimitType;
|
||||||
import com.ruoyi.common.core.utils.StringUtils;
|
import com.ruoyi.common.core.utils.StringUtils;
|
||||||
import com.ruoyi.common.core.utils.reflect.ReflectUtils;
|
import com.ruoyi.common.core.utils.reflect.ReflectUtils;
|
||||||
import com.ruoyi.common.core.utils.SpringUtils;
|
import com.ruoyi.common.core.utils.SpringUtils;
|
||||||
import com.ruoyi.common.core.core.domain.R;
|
import com.ruoyi.common.core.core.domain.R;
|
||||||
|
import com.ruoyi.common.encrypt.utils.RSAUtils;
|
||||||
import com.ruoyi.common.mail.config.properties.MailProperties;
|
import com.ruoyi.common.mail.config.properties.MailProperties;
|
||||||
import com.ruoyi.common.mail.utils.MailUtils;
|
import com.ruoyi.common.mail.utils.MailUtils;
|
||||||
import com.ruoyi.common.redis.utils.RedisUtils;
|
import com.ruoyi.common.redis.utils.RedisUtils;
|
||||||
@ -134,4 +139,27 @@ public class CaptchaController
|
|||||||
}
|
}
|
||||||
return R.ok();
|
return R.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/genKeyPair")
|
||||||
|
public R genKeyPair() {
|
||||||
|
Map<String,String> map=new HashMap<>();
|
||||||
|
try {
|
||||||
|
log.info("开始生产rsa秘钥");
|
||||||
|
|
||||||
|
Map<String, Object> keyPair = RSAUtils.genKeyPair();
|
||||||
|
String publicKey = RSAUtils.getPublicKey(keyPair);
|
||||||
|
String privateKey = RSAUtils.getPrivateKey(keyPair);
|
||||||
|
log.info("privateKey:"+privateKey);
|
||||||
|
String uuid="ruoyi_"+ UUID.randomUUID().toString().replace("-","");
|
||||||
|
RedisUtils.setCacheMapValue("loginRsa",uuid,privateKey);
|
||||||
|
RedisUtils.expire("loginRsa",60*60);
|
||||||
|
log.info("写入redis完成");
|
||||||
|
|
||||||
|
map.put("uuidPrivateKey",uuid);
|
||||||
|
map.put("RSA_PUBLIC_KEY",publicKey);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return R.fail("生成RSA秘钥失败,"+e.getMessage());
|
||||||
|
}
|
||||||
|
return R.ok(map);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,8 +36,8 @@ mybatis-flex:
|
|||||||
#postgresql数据库
|
#postgresql数据库
|
||||||
driver-class-name: org.postgresql.Driver
|
driver-class-name: org.postgresql.Driver
|
||||||
url: jdbc:postgresql://localhost:5432/ruoyi-flex?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true
|
url: jdbc:postgresql://localhost:5432/ruoyi-flex?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true
|
||||||
username: postgres
|
username: root
|
||||||
password: postgres@369
|
password: root
|
||||||
|
|
||||||
# redis 单机配置(单机与集群只能开启一个另一个需要注释掉)
|
# redis 单机配置(单机与集群只能开启一个另一个需要注释掉)
|
||||||
spring.data:
|
spring.data:
|
||||||
@ -49,7 +49,7 @@ spring.data:
|
|||||||
# 数据库索引
|
# 数据库索引
|
||||||
database: 0
|
database: 0
|
||||||
# 密码(如没有密码请注释掉)
|
# 密码(如没有密码请注释掉)
|
||||||
# password:
|
password: root
|
||||||
# 连接超时时间
|
# 连接超时时间
|
||||||
timeout: 10s
|
timeout: 10s
|
||||||
# 是否开启ssl
|
# 是否开启ssl
|
||||||
|
@ -35,21 +35,21 @@ mybatis-flex:
|
|||||||
# password: Root@369
|
# password: Root@369
|
||||||
#postgresql数据库
|
#postgresql数据库
|
||||||
driver-class-name: org.postgresql.Driver
|
driver-class-name: org.postgresql.Driver
|
||||||
url: jdbc:postgresql://localhost:5432/ruoyi-flex?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true
|
url: jdbc:postgresql://172.16.0.151:5432/ruoyi-flex?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true
|
||||||
username: postgres
|
username: root
|
||||||
password: postgres@369
|
password: root
|
||||||
|
|
||||||
# redis 单机配置(单机与集群只能开启一个另一个需要注释掉)
|
# redis 单机配置(单机与集群只能开启一个另一个需要注释掉)
|
||||||
spring.data:
|
spring.data:
|
||||||
redis:
|
redis:
|
||||||
# 地址
|
# 地址
|
||||||
host: localhost
|
host: 172.16.0.151
|
||||||
# 端口,默认为6379
|
# 端口,默认为6379
|
||||||
port: 6379
|
port: 6379
|
||||||
# 数据库索引
|
# 数据库索引
|
||||||
database: 0
|
database: 0
|
||||||
# 密码(如没有密码请注释掉)
|
# 密码(如没有密码请注释掉)
|
||||||
# password:
|
password: root
|
||||||
# 连接超时时间
|
# 连接超时时间
|
||||||
timeout: 10s
|
timeout: 10s
|
||||||
# 是否开启ssl
|
# 是否开启ssl
|
||||||
@ -81,7 +81,7 @@ redisson:
|
|||||||
spring.boot.admin.client:
|
spring.boot.admin.client:
|
||||||
# 增加客户端开关
|
# 增加客户端开关
|
||||||
enabled: true
|
enabled: true
|
||||||
url: http://localhost:9090/admin
|
url: http://172.16.0.151:9090/admin
|
||||||
instance:
|
instance:
|
||||||
service-host-type: IP
|
service-host-type: IP
|
||||||
username: ruoyi
|
username: ruoyi
|
||||||
@ -97,7 +97,7 @@ powerjob:
|
|||||||
# 28080 端口 随着主应用端口飘逸 避免集群冲突
|
# 28080 端口 随着主应用端口飘逸 避免集群冲突
|
||||||
port: 2${server.port}
|
port: 2${server.port}
|
||||||
protocol: http
|
protocol: http
|
||||||
server-address: 127.0.0.1:7700
|
server-address: 172.16.0.151:7700
|
||||||
store-strategy: disk
|
store-strategy: disk
|
||||||
allow-lazy-connect-server: false
|
allow-lazy-connect-server: false
|
||||||
max-appended-wf-context-length: 4096
|
max-appended-wf-context-length: 4096
|
||||||
|
@ -9,7 +9,7 @@ ruoyi:
|
|||||||
# 实例演示开关
|
# 实例演示开关
|
||||||
demoEnabled: true
|
demoEnabled: true
|
||||||
# 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
|
# 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
|
||||||
profile: D:/ruoyi/uploadPath
|
profile: /home/ruoyi/uploadPath
|
||||||
# 获取ip地址开关
|
# 获取ip地址开关
|
||||||
addressEnabled: false
|
addressEnabled: false
|
||||||
|
|
||||||
@ -298,6 +298,7 @@ security:
|
|||||||
- /captchaImage
|
- /captchaImage
|
||||||
- /captcha/get
|
- /captcha/get
|
||||||
- /captcha/check
|
- /captcha/check
|
||||||
|
- /genKeyPair
|
||||||
|
|
||||||
--- # Actuator 监控端点的配置项
|
--- # Actuator 监控端点的配置项
|
||||||
management:
|
management:
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<!-- 日志存放路径 -->
|
<!-- 日志存放路径 -->
|
||||||
<property name="log.path" value="/home/ruoyi/logs" />
|
<property name="log.path" value="./home/ruoyi/logs" />
|
||||||
<!-- 日志输出格式 -->
|
<!-- 日志输出格式 -->
|
||||||
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
|
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
|
||||||
|
|
||||||
@ -11,7 +11,7 @@
|
|||||||
<pattern>${log.pattern}</pattern>
|
<pattern>${log.pattern}</pattern>
|
||||||
</encoder>
|
</encoder>
|
||||||
</appender>
|
</appender>
|
||||||
|
|
||||||
<!-- 系统日志输出 -->
|
<!-- 系统日志输出 -->
|
||||||
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
<file>${log.path}/sys-info.log</file>
|
<file>${log.path}/sys-info.log</file>
|
||||||
@ -34,7 +34,7 @@
|
|||||||
<onMismatch>DENY</onMismatch>
|
<onMismatch>DENY</onMismatch>
|
||||||
</filter>
|
</filter>
|
||||||
</appender>
|
</appender>
|
||||||
|
|
||||||
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
<file>${log.path}/sys-error.log</file>
|
<file>${log.path}/sys-error.log</file>
|
||||||
<!-- 循环政策:基于时间创建日志文件 -->
|
<!-- 循环政策:基于时间创建日志文件 -->
|
||||||
@ -56,7 +56,7 @@
|
|||||||
<onMismatch>DENY</onMismatch>
|
<onMismatch>DENY</onMismatch>
|
||||||
</filter>
|
</filter>
|
||||||
</appender>
|
</appender>
|
||||||
|
|
||||||
<!-- 用户访问日志输出 -->
|
<!-- 用户访问日志输出 -->
|
||||||
<appender name="sys-user" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
<appender name="sys-user" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
<file>${log.path}/sys-user.log</file>
|
<file>${log.path}/sys-user.log</file>
|
||||||
@ -70,7 +70,7 @@
|
|||||||
<pattern>${log.pattern}</pattern>
|
<pattern>${log.pattern}</pattern>
|
||||||
</encoder>
|
</encoder>
|
||||||
</appender>
|
</appender>
|
||||||
|
|
||||||
<!-- 系统模块日志级别控制 -->
|
<!-- 系统模块日志级别控制 -->
|
||||||
<logger name="com.ruoyi" level="info" />
|
<logger name="com.ruoyi" level="info" />
|
||||||
<!-- Spring日志级别控制 -->
|
<!-- Spring日志级别控制 -->
|
||||||
@ -79,15 +79,15 @@
|
|||||||
<root level="info">
|
<root level="info">
|
||||||
<appender-ref ref="console" />
|
<appender-ref ref="console" />
|
||||||
</root>
|
</root>
|
||||||
|
|
||||||
<!--系统操作日志-->
|
<!--系统操作日志-->
|
||||||
<root level="info">
|
<root level="info">
|
||||||
<appender-ref ref="file_info" />
|
<appender-ref ref="file_info" />
|
||||||
<appender-ref ref="file_error" />
|
<appender-ref ref="file_error" />
|
||||||
</root>
|
</root>
|
||||||
|
|
||||||
<!--系统用户操作日志-->
|
<!--系统用户操作日志-->
|
||||||
<logger name="sys-user" level="info">
|
<logger name="sys-user" level="info">
|
||||||
<appender-ref ref="sys-user"/>
|
<appender-ref ref="sys-user"/>
|
||||||
</logger>
|
</logger>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
@ -51,7 +51,7 @@ public class CryptoFilter implements Filter {
|
|||||||
String headerValue = servletRequest.getHeader(properties.getHeaderFlag());
|
String headerValue = servletRequest.getHeader(properties.getHeaderFlag());
|
||||||
if (StringUtils.isNotBlank(headerValue)) {
|
if (StringUtils.isNotBlank(headerValue)) {
|
||||||
// 请求解密
|
// 请求解密
|
||||||
requestWrapper = new DecryptRequestBodyWrapper(servletRequest, properties.getPrivateKey(), properties.getHeaderFlag());
|
requestWrapper = new DecryptRequestBodyWrapper(servletRequest, headerValue);
|
||||||
} else {
|
} else {
|
||||||
// 是否有注解,有就报错,没有放行
|
// 是否有注解,有就报错,没有放行
|
||||||
if (ObjectUtil.isNotNull(apiEncrypt)) {
|
if (ObjectUtil.isNotNull(apiEncrypt)) {
|
||||||
|
@ -2,12 +2,14 @@ package com.ruoyi.common.encrypt.filter;
|
|||||||
|
|
||||||
import cn.hutool.core.io.IoUtil;
|
import cn.hutool.core.io.IoUtil;
|
||||||
import com.ruoyi.common.encrypt.utils.EncryptUtils;
|
import com.ruoyi.common.encrypt.utils.EncryptUtils;
|
||||||
|
import com.ruoyi.common.redis.utils.RedisUtils;
|
||||||
import jakarta.servlet.ReadListener;
|
import jakarta.servlet.ReadListener;
|
||||||
import jakarta.servlet.ServletInputStream;
|
import jakarta.servlet.ServletInputStream;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletRequestWrapper;
|
import jakarta.servlet.http.HttpServletRequestWrapper;
|
||||||
import com.ruoyi.common.core.constant.Constants;
|
import com.ruoyi.common.core.constant.Constants;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.web.util.UriUtils;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
@ -24,22 +26,20 @@ public class DecryptRequestBodyWrapper extends HttpServletRequestWrapper {
|
|||||||
|
|
||||||
private final byte[] body;
|
private final byte[] body;
|
||||||
|
|
||||||
public DecryptRequestBodyWrapper(HttpServletRequest request, String privateKey, String headerFlag) throws IOException {
|
public DecryptRequestBodyWrapper(HttpServletRequest request, String privateKey) throws IOException {
|
||||||
super(request);
|
super(request);
|
||||||
// 获取 AES 密码 采用 RSA 加密
|
// 获取 AES 密码 采用 RSA 加密
|
||||||
String headerRsa = request.getHeader(headerFlag);
|
String privateKeyValue = RedisUtils.getCacheMapValue("loginRsa", privateKey);
|
||||||
String decryptAes = EncryptUtils.decryptByRsa(headerRsa, privateKey);
|
|
||||||
// 解密 AES 密码
|
|
||||||
String aesPassword = EncryptUtils.decryptByBase64(decryptAes);
|
|
||||||
request.setCharacterEncoding(Constants.UTF8);
|
|
||||||
byte[] readBytes = IoUtil.readBytes(request.getInputStream(), false);
|
|
||||||
String requestBody = new String(readBytes, StandardCharsets.UTF_8);
|
|
||||||
// 解密 body 采用 AES 加密
|
|
||||||
String decryptBody = EncryptUtils.decryptByAes(requestBody, aesPassword);
|
|
||||||
body = decryptBody.getBytes(StandardCharsets.UTF_8);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
byte[] readBytes = IoUtil.readBytes(request.getInputStream(), false);
|
||||||
|
String requestBody = new String(readBytes, StandardCharsets.UTF_8);
|
||||||
|
// 解密 body 采用 AES 加密
|
||||||
|
String decryptBody = EncryptUtils.decryptByRsa(requestBody, privateKeyValue);
|
||||||
|
body = UriUtils.decode(decryptBody, StandardCharsets.UTF_8).getBytes(StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
public BufferedReader getReader() {
|
public BufferedReader getReader() {
|
||||||
return new BufferedReader(new InputStreamReader(getInputStream()));
|
return new BufferedReader(new InputStreamReader(getInputStream()));
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,363 @@
|
|||||||
|
package com.ruoyi.common.encrypt.utils;
|
||||||
|
|
||||||
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.security.*;
|
||||||
|
import java.security.interfaces.RSAPrivateKey;
|
||||||
|
import java.security.interfaces.RSAPublicKey;
|
||||||
|
import java.security.spec.PKCS8EncodedKeySpec;
|
||||||
|
import java.security.spec.X509EncodedKeySpec;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @NAME: RSAEncryptUtils
|
||||||
|
* @AUTHOR: gaoly
|
||||||
|
* @DATE: 2021/1/26 15:15
|
||||||
|
* @DES:
|
||||||
|
**/
|
||||||
|
public class RSAUtils {
|
||||||
|
/** */
|
||||||
|
/**
|
||||||
|
* 加密算法RSA
|
||||||
|
*/
|
||||||
|
public static final String KEY_ALGORITHM = "RSA";
|
||||||
|
|
||||||
|
/** */
|
||||||
|
/**
|
||||||
|
* 签名算法
|
||||||
|
*/
|
||||||
|
public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
|
||||||
|
|
||||||
|
/** */
|
||||||
|
/**
|
||||||
|
* 获取公钥的key
|
||||||
|
*/
|
||||||
|
private static final String PUBLIC_KEY = "RSAPublicKey";
|
||||||
|
|
||||||
|
/** */
|
||||||
|
/**
|
||||||
|
* 获取私钥的key
|
||||||
|
*/
|
||||||
|
private static final String PRIVATE_KEY = "RSAPrivateKey";
|
||||||
|
|
||||||
|
/** */
|
||||||
|
/**
|
||||||
|
* RSA最大加密明文大小
|
||||||
|
*/
|
||||||
|
private static final int MAX_ENCRYPT_BLOCK = 117;
|
||||||
|
|
||||||
|
/** */
|
||||||
|
/**
|
||||||
|
* RSA最大解密密文大小
|
||||||
|
*/
|
||||||
|
private static final int MAX_DECRYPT_BLOCK = 128;
|
||||||
|
|
||||||
|
/** */
|
||||||
|
/**
|
||||||
|
* RSA 位数 如果采用2048 上面最大加密和最大解密则须填写: 245 256
|
||||||
|
*/
|
||||||
|
private static final int INITIALIZE_LENGTH = 1024;
|
||||||
|
|
||||||
|
/** */
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 生成密钥对(公钥和私钥)
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static Map<String, Object> genKeyPair() throws Exception {
|
||||||
|
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
|
||||||
|
keyPairGen.initialize(INITIALIZE_LENGTH);
|
||||||
|
KeyPair keyPair = keyPairGen.generateKeyPair();
|
||||||
|
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
|
||||||
|
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
|
||||||
|
Map<String, Object> keyMap = new HashMap<String, Object>(2);
|
||||||
|
keyMap.put(PUBLIC_KEY, publicKey);
|
||||||
|
keyMap.put(PRIVATE_KEY, privateKey);
|
||||||
|
return keyMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** */
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 用私钥对信息生成数字签名
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
* 已加密数据
|
||||||
|
* @param privateKey
|
||||||
|
* 私钥(BASE64编码)
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static String sign(byte[] data, String privateKey) throws Exception {
|
||||||
|
byte[] keyBytes = Base64.decodeBase64(privateKey);
|
||||||
|
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
|
||||||
|
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
||||||
|
PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
|
||||||
|
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
|
||||||
|
signature.initSign(privateK);
|
||||||
|
signature.update(data);
|
||||||
|
return Base64.encodeBase64String(signature.sign());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** */
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 校验数字签名
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
* 已加密数据
|
||||||
|
* @param publicKey
|
||||||
|
* 公钥(BASE64编码)
|
||||||
|
* @param sign
|
||||||
|
* 数字签名
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static boolean verify(byte[] data, String publicKey, String sign) throws Exception {
|
||||||
|
byte[] keyBytes = Base64.decodeBase64(publicKey);
|
||||||
|
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
|
||||||
|
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
||||||
|
PublicKey publicK = keyFactory.generatePublic(keySpec);
|
||||||
|
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
|
||||||
|
signature.initVerify(publicK);
|
||||||
|
signature.update(data);
|
||||||
|
return signature.verify(Base64.decodeBase64(sign));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** */
|
||||||
|
/**
|
||||||
|
* <P>
|
||||||
|
* 私钥解密
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param encryptedData
|
||||||
|
* 已加密数据
|
||||||
|
* @param privateKey
|
||||||
|
* 私钥(BASE64编码)
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey) throws Exception {
|
||||||
|
byte[] keyBytes = Base64.decodeBase64(privateKey);
|
||||||
|
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
|
||||||
|
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
||||||
|
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
|
||||||
|
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
|
||||||
|
cipher.init(Cipher.DECRYPT_MODE, privateK);
|
||||||
|
int inputLen = encryptedData.length;
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
int offSet = 0;
|
||||||
|
byte[] cache;
|
||||||
|
int i = 0;
|
||||||
|
// 对数据分段解密
|
||||||
|
while (inputLen - offSet > 0) {
|
||||||
|
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
|
||||||
|
cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
|
||||||
|
} else {
|
||||||
|
cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
|
||||||
|
}
|
||||||
|
out.write(cache, 0, cache.length);
|
||||||
|
i++;
|
||||||
|
offSet = i * MAX_DECRYPT_BLOCK;
|
||||||
|
}
|
||||||
|
byte[] decryptedData = out.toByteArray();
|
||||||
|
out.close();
|
||||||
|
return decryptedData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** */
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 公钥解密
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param encryptedData
|
||||||
|
* 已加密数据
|
||||||
|
* @param publicKey
|
||||||
|
* 公钥(BASE64编码)
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey) throws Exception {
|
||||||
|
byte[] keyBytes = Base64.decodeBase64(publicKey);
|
||||||
|
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
|
||||||
|
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
||||||
|
Key publicK = keyFactory.generatePublic(x509KeySpec);
|
||||||
|
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
|
||||||
|
cipher.init(Cipher.DECRYPT_MODE, publicK);
|
||||||
|
int inputLen = encryptedData.length;
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
int offSet = 0;
|
||||||
|
byte[] cache;
|
||||||
|
int i = 0;
|
||||||
|
// 对数据分段解密
|
||||||
|
while (inputLen - offSet > 0) {
|
||||||
|
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
|
||||||
|
cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
|
||||||
|
} else {
|
||||||
|
cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
|
||||||
|
}
|
||||||
|
out.write(cache, 0, cache.length);
|
||||||
|
i++;
|
||||||
|
offSet = i * MAX_DECRYPT_BLOCK;
|
||||||
|
}
|
||||||
|
byte[] decryptedData = out.toByteArray();
|
||||||
|
out.close();
|
||||||
|
return decryptedData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** */
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 公钥加密
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
* 源数据
|
||||||
|
* @param publicKey
|
||||||
|
* 公钥(BASE64编码)
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception {
|
||||||
|
byte[] keyBytes = Base64.decodeBase64(publicKey);
|
||||||
|
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
|
||||||
|
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
||||||
|
Key publicK = keyFactory.generatePublic(x509KeySpec);
|
||||||
|
// 对数据加密
|
||||||
|
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
|
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, publicK);
|
||||||
|
int inputLen = data.length;
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
int offSet = 0;
|
||||||
|
byte[] cache;
|
||||||
|
int i = 0;
|
||||||
|
// 对数据分段加密
|
||||||
|
while (inputLen - offSet > 0) {
|
||||||
|
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
|
||||||
|
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
|
||||||
|
} else {
|
||||||
|
cache = cipher.doFinal(data, offSet, inputLen - offSet);
|
||||||
|
}
|
||||||
|
out.write(cache, 0, cache.length);
|
||||||
|
i++;
|
||||||
|
offSet = i * MAX_ENCRYPT_BLOCK;
|
||||||
|
}
|
||||||
|
byte[] encryptedData = out.toByteArray();
|
||||||
|
out.close();
|
||||||
|
return encryptedData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** */
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 私钥加密
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
* 源数据
|
||||||
|
* @param privateKey
|
||||||
|
* 私钥(BASE64编码)
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static byte[] encryptByPrivateKey(byte[] data, String privateKey) throws Exception {
|
||||||
|
byte[] keyBytes = Base64.decodeBase64(privateKey);
|
||||||
|
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
|
||||||
|
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
||||||
|
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
|
||||||
|
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
|
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, privateK);
|
||||||
|
int inputLen = data.length;
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
int offSet = 0;
|
||||||
|
byte[] cache;
|
||||||
|
int i = 0;
|
||||||
|
// 对数据分段加密
|
||||||
|
while (inputLen - offSet > 0) {
|
||||||
|
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
|
||||||
|
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
|
||||||
|
} else {
|
||||||
|
cache = cipher.doFinal(data, offSet, inputLen - offSet);
|
||||||
|
}
|
||||||
|
out.write(cache, 0, cache.length);
|
||||||
|
i++;
|
||||||
|
offSet = i * MAX_ENCRYPT_BLOCK;
|
||||||
|
}
|
||||||
|
byte[] encryptedData = out.toByteArray();
|
||||||
|
out.close();
|
||||||
|
return encryptedData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** */
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 获取私钥
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param keyMap
|
||||||
|
* 密钥对
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static String getPrivateKey(Map<String, Object> keyMap) throws Exception {
|
||||||
|
Key key = (Key) keyMap.get(PRIVATE_KEY);
|
||||||
|
return Base64.encodeBase64String(key.getEncoded());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** */
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 获取公钥
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param keyMap
|
||||||
|
* 密钥对
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static String getPublicKey(Map<String, Object> keyMap) throws Exception {
|
||||||
|
Key key = (Key) keyMap.get(PUBLIC_KEY);
|
||||||
|
return Base64.encodeBase64String(key.getEncoded());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* java端公钥加密
|
||||||
|
*/
|
||||||
|
public static String encryptedDataOnJava(String data, String PUBLICKEY) {
|
||||||
|
try {
|
||||||
|
data = Base64.encodeBase64String(encryptByPublicKey(data.getBytes(), PUBLICKEY));
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* java端私钥解密
|
||||||
|
*/
|
||||||
|
public static String decryptDataOnJava(String data, String PRIVATEKEY) {
|
||||||
|
String temp = "";
|
||||||
|
try {
|
||||||
|
byte[] rs = Base64.decodeBase64(data);
|
||||||
|
temp = new String(RSAUtils.decryptByPrivateKey(rs, PRIVATEKEY),"UTF-8");
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -4,8 +4,8 @@ oms.env=dev
|
|||||||
spring.datasource.remote.hibernate.properties.hibernate.dialect=tech.powerjob.server.persistence.config.dialect.PowerJobPGDialect
|
spring.datasource.remote.hibernate.properties.hibernate.dialect=tech.powerjob.server.persistence.config.dialect.PowerJobPGDialect
|
||||||
spring.datasource.core.driver-class-name=org.postgresql.Driver
|
spring.datasource.core.driver-class-name=org.postgresql.Driver
|
||||||
spring.datasource.core.jdbc-url=jdbc:postgresql://localhost:5432/ruoyi-flex?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
|
spring.datasource.core.jdbc-url=jdbc:postgresql://localhost:5432/ruoyi-flex?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
|
||||||
spring.datasource.core.username=postgres
|
spring.datasource.core.username=root
|
||||||
spring.datasource.core.password=postgres@369
|
spring.datasource.core.password=root
|
||||||
## MySQL数据库连接参数
|
## MySQL数据库连接参数
|
||||||
#spring.datasource.core.driver-class-name=com.mysql.cj.jdbc.Driver
|
#spring.datasource.core.driver-class-name=com.mysql.cj.jdbc.Driver
|
||||||
#spring.datasource.core.jdbc-url=jdbc:mysql://localhost:3306/ruoyi-flex?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
|
#spring.datasource.core.jdbc-url=jdbc:mysql://localhost:3306/ruoyi-flex?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
|
||||||
|
Loading…
Reference in New Issue
Block a user