admin管理员组文章数量:1568557
最近做项目,客户要求,所有的配置文件中,不能出现明文密码,必须要使用 RSA 2048加密。在这里,记录一下,怎么实现这个功能的。
主要是用springboot暴露的EnvironmentPostProcessor扩展接口。
首先我们新建一个类来实现这个扩展接口,用来把配置文件中加密的数据库密码,进行解密,然后将明文密码,替换到spring的参数中去。
@Slf4j
public class SaftEncryptProcessor implements EnvironmentPostProcessor{
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
boolean flag = false;
for(PropertySource<?> ps : environment.getPropertySources()){
if(ps instanceof OriginTrackedMapPropertySource){
Map<String,Object> map = new HashMap<>();
OriginTrackedMapPropertySource source = (OriginTrackedMapPropertySource)ps;
try{
for(String name : source.getPropertyNames()){
Object value = source.getProperty(name);
map.put(name,value);
if(RSADecryptConstants.passWordProperty.equals(name)){
String str = (String) value;
byte[] resultpass = RSAEncryptDecrypt.decrypt(str,RSADecryptConstants.privateRsaKey);
String newpass = new String(resultpass);
map.put(name,newpass);
flag = true;
}
if(RSADecryptConstants.redisPassWordProperty.equals(name)){
flag = true;
String str = (String) value;
byte[] resultpass = RSAEncryptDecrypt.decrypt(str,RSADecryptConstants.privateRsaKey);
String newpass = new String(resultpass);
map.put(name,newpass);
}
}
if(flag){
environment.getPropertySources()
.addLast(new MapPropertySource(ps.getName(), Collections.unmodifiableMap(map)));
}
}catch (Exception e){
throw new RuntimeException("RSA解密出错"+ e);
}
}
}
}
}
在这个类里面,我们会用 RSAEncryptDecrypt.decrypt(str,RSADecryptConstants.privateRsaKey);
方法来解密。
ps: RSADecryptConstants.privateRsaKey 这个是自己用来解密的私钥,str 就是加密的密文了
RSADecryptConstants.redisPassWordProperty 这个是spring配置文件中参数的key 比如
这个就是redis密码的key(spring.redis.password),自己建个常量来记录。
public class RSAEncryptDecrypt {
public static byte[] decrypt(String str,String privateKey) throws Exception{
//Base64 解密秘钥
byte[] prikeydecoded = Base64.getDecoder().decode(privateKey.getBytes());
RSAPrivateCrtKey prikey = (RSAPrivateCrtKey) KeyFactory.getInstance("RSA")
.generatePrivate(new PKCS8EncodedKeySpec(prikeydecoded));
//解密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE,prikey);
return getMaxResultDecrypt(str,cipher);
}
private static byte[] getMaxResultDecrypt(String str,Cipher cipher)throws Exception{
byte[] basestr = Base64.getDecoder().decode(str.getBytes("UTF-8"));
int inputlength = basestr.length;
int MAX_ENCRYPT = 256;
int offset = 0;
byte [] resultBytes = {};
byte [] cache = {};
while(inputlength - offset > 0){
if(inputlength - offset > MAX_ENCRYPT){
cache = cipher.doFinal(basestr,offset,MAX_ENCRYPT);
}else{
cache = cipher.doFinal(basestr,offset,inputlength - offset);
offset = inputlength;
}
resultBytes = Arrays.copyOf(resultBytes,resultBytes.length+cache.length);
System.arraycopy(cache,0,resultBytes,resultBytes.length-cache.length,cache.length);
}
return resultBytes;
}
}
ps:不论是秘钥,还是加密密文,都是经过Base64 加密过的,所以都需要先进性Base64解密
getMaxResultDecrypt 这个方法主要是因为RSA加密,解密都有长度限制,必须分段加密,解密。
到这里就差不多完成了,最后 配置进spring.factories
在resources 下 新建META-INF文件夹并 新建 spring.factories文件,配置org.springframework.boot.env.EnvironmentPostProcessor
org.springframework.boot.env.EnvironmentPostProcessor=com.personal.riskdatabase.config.SaftEncryptProcessor
版权声明:本文标题:spring boot中关于配置文件中,数据库密码需要RSA加密的功能 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dongtai/1726164856a1058111.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论