Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
H
hphy
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
向怀芳
hphy
Commits
c6fc236d
Commit
c6fc236d
authored
Jun 01, 2023
by
gaozhaochen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add: 敏感数据加密解密处理
parent
bc0056a2
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
316 additions
and
14 deletions
+316
-14
SecurityParameter.java
...va/cn/sh/stc/sict/theme/annotation/SecurityParameter.java
+25
-0
EncryptionRequest.java
...cn/sh/stc/sict/theme/common/crypto/EncryptionRequest.java
+21
-0
EncryptionResponse.java
...n/sh/stc/sict/theme/common/crypto/EncryptionResponse.java
+8
-0
EncryptionUtil.java
...va/cn/sh/stc/sict/theme/common/crypto/EncryptionUtil.java
+68
-0
RSADecodeData.java
...n/java/cn/sh/stc/sict/theme/common/rsa/RSADecodeData.java
+27
-0
DecodeRequestAdvice.java
...java/cn/sh/stc/sict/theme/config/DecodeRequestAdvice.java
+70
-0
EncodeResponseAdvice.java
...ava/cn/sh/stc/sict/theme/config/EncodeResponseAdvice.java
+52
-0
HphyPatientBaseController.java
...t/theme/hphy/controller/mp/HphyPatientBaseController.java
+4
-0
HpSecurityController.java
.../sict/theme/hphy/controller/web/HpSecurityController.java
+31
-0
HpStatisticsController.java
...ict/theme/hphy/controller/web/HpStatisticsController.java
+10
-14
No files found.
smart-health-modules/theme-schema/src/main/java/cn/sh/stc/sict/theme/annotation/SecurityParameter.java
0 → 100644
View file @
c6fc236d
package
cn
.
sh
.
stc
.
sict
.
theme
.
annotation
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
/**
* @author gao
* @date 2023/05/30 13:50
*/
@Target
({
ElementType
.
METHOD
,
ElementType
.
TYPE
})
@Retention
(
RetentionPolicy
.
RUNTIME
)
public
@interface
SecurityParameter
{
/**
* 入参是否解密,默认解密
*/
boolean
inDecode
()
default
true
;
/**
* 出参是否加密,默认加密
*/
boolean
outEncode
()
default
true
;
}
smart-health-modules/theme-schema/src/main/java/cn/sh/stc/sict/theme/common/crypto/EncryptionRequest.java
0 → 100644
View file @
c6fc236d
package
cn
.
sh
.
stc
.
sict
.
theme
.
common
.
crypto
;
import
lombok.Data
;
/**
* @author gao
* @date 2023/05/30 13:49
*/
@Data
public
class
EncryptionRequest
{
/**
* rsa加密后的aes秘钥
*/
private
String
encryptionKey
;
/**
*aes加密后的数据内容
*/
private
String
encryptionData
;
}
smart-health-modules/theme-schema/src/main/java/cn/sh/stc/sict/theme/common/crypto/EncryptionResponse.java
0 → 100644
View file @
c6fc236d
package
cn
.
sh
.
stc
.
sict
.
theme
.
common
.
crypto
;
/**
* @author gao
* @date 2023/05/30 13:59
*/
public
class
EncryptionResponse
{
}
smart-health-modules/theme-schema/src/main/java/cn/sh/stc/sict/theme/common/crypto/EncryptionUtil.java
0 → 100644
View file @
c6fc236d
package
cn
.
sh
.
stc
.
sict
.
theme
.
common
.
crypto
;
import
cn.hutool.core.codec.Base64
;
import
cn.hutool.core.io.IoUtil
;
import
cn.hutool.crypto.SecureUtil
;
import
cn.hutool.crypto.asymmetric.KeyType
;
import
cn.hutool.crypto.asymmetric.RSA
;
import
cn.hutool.crypto.symmetric.AES
;
import
sun.misc.BASE64Encoder
;
import
java.io.InputStream
;
import
java.security.KeyPair
;
import
java.security.PrivateKey
;
import
java.security.PublicKey
;
import
java.util.HashMap
;
import
java.util.Map
;
/**
* @author gao
* @date 2023/05/30 13:48
*/
public
class
EncryptionUtil
{
private
static
final
String
SIGN_TYPE_RSA
=
"RSA"
;
private
static
final
int
DEFAULT_RSA_KEY_SIZE
=
1024
;
public
static
final
String
PRIVATE_KEY
=
"MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEAjQnqX7O3S6eDLzw4tw9K2IsWUuS9WCptg32AmaNMN+1YawmqDVOtrnkOyECZleuir62Y6ptw8yN0cyYzMFezDQIDAQABAkB9c5Jr6flia+/+Nfzkp8+VabJDrX7WS3b5/MpE3sHPBBQ/9HhAyg7k/MHTFZ8wScziFLPQ/wb6+szacNvA1RrpAiEA2Ei7JY6L/dv9hQ+YKYblCeGIQG8FUi4Uy7xheg1M/ZMCIQCm7/xBJCMubyyKHgRXr6MonqPdu2IE51IqmerXQV/w3wIgZ9jMGuVNrC8zk+7/5XiCgnMKg72KtYGwtH4X4419WQcCIExumHpix1DdSfE66RYUrolMiQ5eWvSPzMkAi8tefUTVAiB6F4fXbtKbqpJxW5dQttJl0RsEB39HGgOjy4mLaYZgvg=="
;
public
static
final
String
PUBLIC_KEY
=
"MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAI0J6l+zt0ungy88OLcPStiLFlLkvVgqbYN9gJmjTDftWGsJqg1Tra55DshAmZXroq+tmOqbcPMjdHMmMzBXsw0CAwEAAQ=="
;
// 创建rsa加密对象 服务端公钥是不需要的,公钥提供给前端就行
private
final
static
cn
.
hutool
.
crypto
.
asymmetric
.
RSA
RSA
=
new
RSA
(
PRIVATE_KEY
,
PUBLIC_KEY
);
/**
* 获取加密返回
*/
public
static
String
getEncodeResponse
(
String
encryptionData
)
{
return
Base64
.
encode
(
encryptionData
);
}
/**
* 获取解密返回流
*/
public
static
InputStream
getDecodeInputStream
(
EncryptionRequest
request
)
{
String
encryptionKey
=
request
.
getEncryptionKey
();
// rsa解密 获取aes秘钥
byte
[]
decryptKey
=
RSA
.
decrypt
(
encryptionKey
,
KeyType
.
PrivateKey
);
// aes进行解密内容 获取输入流(方便整合springMVC)
AES
aes
=
SecureUtil
.
aes
(
decryptKey
);
byte
[]
decryptData
=
aes
.
decrypt
(
request
.
getEncryptionData
());
return
IoUtil
.
toStream
(
decryptData
);
}
public
static
void
main
(
String
[]
args
)
{
KeyPair
kp
=
SecureUtil
.
generateKeyPair
(
SIGN_TYPE_RSA
,
DEFAULT_RSA_KEY_SIZE
);
PublicKey
pbkey
=
kp
.
getPublic
();
PrivateKey
prkey
=
kp
.
getPrivate
();
String
pubkey
=
(
new
BASE64Encoder
()).
encode
(
pbkey
.
getEncoded
());
String
prikey
=
(
new
BASE64Encoder
()).
encode
(
prkey
.
getEncoded
());
//logger.info("{}生成秘钥成功,公钥:{},私钥:{}",appkey,pubkey,prikey);
Map
map
=
new
HashMap
();
map
.
put
(
"pub"
,
pubkey
);
map
.
put
(
"pri"
,
prikey
);
}
}
smart-health-modules/theme-schema/src/main/java/cn/sh/stc/sict/theme/common/rsa/RSADecodeData.java
0 → 100644
View file @
c6fc236d
package
cn
.
sh
.
stc
.
sict
.
theme
.
common
.
rsa
;
import
lombok.Data
;
/**
* @author gao
* @date 2023/05/30 11:16
*/
@Data
public
class
RSADecodeData
{
/**
* Aes密钥
*/
private
String
key
;
/**
* 偏移量
*/
private
String
keyVI
;
/**
* 时间
*/
private
String
time
;
}
smart-health-modules/theme-schema/src/main/java/cn/sh/stc/sict/theme/config/DecodeRequestAdvice.java
0 → 100644
View file @
c6fc236d
package
cn
.
sh
.
stc
.
sict
.
theme
.
config
;
import
cn.sh.stc.sict.theme.annotation.SecurityParameter
;
import
cn.sh.stc.sict.theme.common.crypto.EncryptionRequest
;
import
cn.sh.stc.sict.theme.common.crypto.EncryptionUtil
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
lombok.RequiredArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.core.MethodParameter
;
import
org.springframework.http.HttpHeaders
;
import
org.springframework.http.HttpInputMessage
;
import
org.springframework.http.converter.HttpMessageConverter
;
import
org.springframework.web.bind.annotation.ControllerAdvice
;
import
org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.lang.reflect.Type
;
/**
* @author gao
* @date 2023/05/30 13:55
*/
@Slf4j
@ControllerAdvice
@RequiredArgsConstructor
public
class
DecodeRequestAdvice
implements
RequestBodyAdvice
{
private
final
ObjectMapper
objectMapper
;
@Override
public
boolean
supports
(
MethodParameter
methodParameter
,
Type
type
,
Class
<?
extends
HttpMessageConverter
<?>>
aClass
)
{
// 判断方法是否需要进行解密
return
methodParameter
.
hasMethodAnnotation
(
SecurityParameter
.
class
)
&&
methodParameter
.
getMethodAnnotation
(
SecurityParameter
.
class
).
inDecode
();
}
@Override
public
HttpInputMessage
beforeBodyRead
(
HttpInputMessage
httpInputMessage
,
MethodParameter
methodParameter
,
Type
type
,
Class
<?
extends
HttpMessageConverter
<?>>
aClass
)
throws
IOException
{
// 读取body对象,获取EncryptionRequest对象
InputStream
body
=
httpInputMessage
.
getBody
();
EncryptionRequest
encryptionRequest
=
objectMapper
.
readValue
(
body
,
EncryptionRequest
.
class
);
if
(
encryptionRequest
.
getEncryptionKey
()
==
null
)
{
throw
new
IllegalArgumentException
(
"encryption error,request is null"
);
}
// 转换成解密后的HttpInputMessage对象
return
new
HttpInputMessage
()
{
@Override
public
HttpHeaders
getHeaders
()
{
return
httpInputMessage
.
getHeaders
();
}
// 解密后的输入流
@Override
public
InputStream
getBody
()
{
return
EncryptionUtil
.
getDecodeInputStream
(
encryptionRequest
);
}
};
}
@Override
public
Object
afterBodyRead
(
Object
o
,
HttpInputMessage
httpInputMessage
,
MethodParameter
methodParameter
,
Type
type
,
Class
<?
extends
HttpMessageConverter
<?>>
aClass
)
{
return
o
;
}
@Override
public
Object
handleEmptyBody
(
Object
o
,
HttpInputMessage
httpInputMessage
,
MethodParameter
methodParameter
,
Type
type
,
Class
<?
extends
HttpMessageConverter
<?>>
aClass
)
{
return
o
;
}
}
smart-health-modules/theme-schema/src/main/java/cn/sh/stc/sict/theme/config/EncodeResponseAdvice.java
0 → 100644
View file @
c6fc236d
package
cn
.
sh
.
stc
.
sict
.
theme
.
config
;
import
cn.sh.stc.sict.theme.annotation.SecurityParameter
;
import
cn.sh.stc.sict.theme.common.crypto.EncryptionUtil
;
import
com.fasterxml.jackson.core.JsonProcessingException
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.core.MethodParameter
;
import
org.springframework.http.MediaType
;
import
org.springframework.http.server.ServerHttpRequest
;
import
org.springframework.http.server.ServerHttpResponse
;
import
org.springframework.web.bind.annotation.ControllerAdvice
;
import
org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice
;
/**
* @author gao
* @date 2023/05/30 13:52
*/
@Slf4j
@ControllerAdvice
public
class
EncodeResponseAdvice
implements
ResponseBodyAdvice
{
@Autowired
private
ObjectMapper
objectMapper
;
@Override
public
boolean
supports
(
MethodParameter
methodParameter
,
Class
aClass
)
{
// 方法上有SecurityParameter注解的进行加密 根据需求可以在判断SecurityParameter注解中的outEncode是否为true
return
methodParameter
.
hasMethodAnnotation
(
SecurityParameter
.
class
)
&&
methodParameter
.
getMethodAnnotation
(
SecurityParameter
.
class
).
outEncode
();
}
@Override
public
Object
beforeBodyWrite
(
Object
o
,
MethodParameter
methodParameter
,
MediaType
mediaType
,
Class
aClass
,
ServerHttpRequest
serverHttpRequest
,
ServerHttpResponse
serverHttpResponse
)
{
try
{
// 要支持接口返回string的话,response需要序列化成string对象,因为接口返回string和对象使用消息转换器不是一样的
// 把返回结果序列化成json
String
dataJson
=
objectMapper
.
writeValueAsString
(
o
);
// 进行加密返回
return
EncryptionUtil
.
getEncodeResponse
(
dataJson
);
}
catch
(
JsonProcessingException
e
)
{
log
.
error
(
"json processing error"
,
e
);
}
return
o
;
}
}
smart-health-modules/theme-schema/src/main/java/cn/sh/stc/sict/theme/hphy/controller/mp/HphyPatientBaseController.java
View file @
c6fc236d
...
...
@@ -14,6 +14,7 @@ import cn.sh.stc.sict.cloud.common.core.util.WoaUtil;
import
cn.sh.stc.sict.cloud.common.log.annotation.SysLog
;
import
cn.sh.stc.sict.cloud.common.security.util.SecurityUtils
;
import
cn.sh.stc.sict.cloud.upms.dto.CurrentUser
;
import
cn.sh.stc.sict.theme.annotation.SecurityParameter
;
import
cn.sh.stc.sict.theme.hphy.constant.PatientConstant
;
import
cn.sh.stc.sict.theme.hphy.model.HpPatientCard
;
import
cn.sh.stc.sict.theme.hphy.model.HphyPatientBase
;
...
...
@@ -56,6 +57,7 @@ public class HphyPatientBaseController {
@SysLog
@ApiOperation
(
"注册"
)
@PostMapping
(
"/register"
)
@SecurityParameter
(
outEncode
=
false
)
public
R
register
(
@RequestBody
HphyPatientBase
patient
)
{
CurrentUser
current
=
SecurityUtils
.
getCurrentUser
();
HphyPatientBase
base
=
hphyPatientBaseService
.
getCurrentBase
();
...
...
@@ -108,6 +110,7 @@ public class HphyPatientBaseController {
* @return
*/
@GetMapping
@SecurityParameter
(
inDecode
=
false
)
public
R
getInfo
()
{
log
.
error
(
"获取患者信息1"
);
CurrentUser
current
=
SecurityUtils
.
getCurrentUser
();
...
...
@@ -130,6 +133,7 @@ public class HphyPatientBaseController {
@ApiOperation
(
"第三方公众号进入系统时,获取患者信息"
)
@GetMapping
(
"/third-party"
)
@SecurityParameter
(
inDecode
=
false
)
public
R
getInfoByToken
(
@RequestParam
(
"source"
)
String
source
,
@RequestParam
(
"token"
)
String
token
)
{
log
.
error
(
"source = {}, token = {}"
,
source
,
token
);
...
...
smart-health-modules/theme-schema/src/main/java/cn/sh/stc/sict/theme/hphy/controller/web/HpSecurityController.java
0 → 100644
View file @
c6fc236d
package
cn
.
sh
.
stc
.
sict
.
theme
.
hphy
.
controller
.
web
;
import
cn.sh.stc.sict.cloud.common.core.util.R
;
import
cn.sh.stc.sict.theme.common.crypto.EncryptionUtil
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiOperation
;
import
lombok.AllArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
/**
* @author gao
* @date 2023/05/30 14:30
*/
@Api
(
value
=
"[黄浦]安全密钥"
,
tags
=
"[黄浦]安全密钥"
)
@RestController
@RequestMapping
(
"hpSecurity"
)
@AllArgsConstructor
@Slf4j
public
class
HpSecurityController
{
@ApiOperation
(
"获取公钥"
)
@GetMapping
(
"/public-key"
)
public
R
<
String
>
getPublicKey
()
{
log
.
info
(
"获取公钥"
);
return
new
R
<>(
EncryptionUtil
.
PUBLIC_KEY
);
}
}
smart-health-modules/theme-schema/src/main/java/cn/sh/stc/sict/theme/hphy/controller/web/HpStatisticsController.java
View file @
c6fc236d
package
cn
.
sh
.
stc
.
sict
.
theme
.
hphy
.
controller
.
web
;
import
cn.hutool.core.util.ObjectUtil
;
import
cn.hutool.core.util.StrUtil
;
import
cn.hutool.json.JSONUtil
;
import
cn.sh.stc.sict.cloud.common.core.constant.enums.LoginTypeEnum
;
import
cn.sh.stc.sict.cloud.common.core.dto.WDUserCardInfo
;
import
cn.sh.stc.sict.cloud.common.core.dto.WDUserInfo
;
import
cn.sh.stc.sict.cloud.common.core.dto.XSZYUserInfo
;
import
cn.sh.stc.sict.cloud.common.core.util.NumberUtil
;
import
cn.sh.stc.sict.cloud.common.core.util.R
;
import
cn.sh.stc.sict.cloud.common.core.util.SsbUtil
;
import
cn.sh.stc.sict.cloud.common.security.util.SecurityUtils
;
import
cn.sh.stc.sict.theme.hphy.constant.PatientConstant
;
import
cn.sh.stc.sict.theme.hphy.model.HphyPatientBase
;
import
cn.sh.stc.sict.theme.annotation.SecurityParameter
;
import
cn.sh.stc.sict.theme.common.crypto.EncryptionUtil
;
import
cn.sh.stc.sict.theme.hphy.service.HpStatisticsService
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiOperation
;
...
...
@@ -23,8 +13,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
import
org.springframework.web.bind.annotation.RequestParam
;
import
org.springframework.web.bind.annotation.RestController
;
import
java.util.List
;
/**
* 黄埔医导统计
*
...
...
@@ -42,10 +30,18 @@ public class HpStatisticsController {
@ApiOperation
(
"统计用户使用情况"
)
@GetMapping
(
"/usage-overview"
)
@SecurityParameter
(
inDecode
=
false
)
public
R
statisticsUsage
(
@RequestParam
(
"startTime"
)
String
startTime
,
@RequestParam
(
"endTime"
)
String
endTime
)
{
log
.
error
(
"统计用户使用情况:startTime = {}, token = {}"
,
startTime
,
endTime
);
return
new
R
(
hpStatisticsService
.
getUsageOverviewStatistics
(
startTime
,
endTime
));
}
@ApiOperation
(
"获取公钥"
)
@GetMapping
(
"/public-key"
)
public
R
<
String
>
getPublicKey
()
{
log
.
info
(
"获取公钥"
);
return
new
R
<>(
EncryptionUtil
.
PUBLIC_KEY
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment