2024-09-04 13:08:32
许久未见,写一篇水文。主要说的是如何使用springboot框架连接apollo配置中心,同时也包含了如何进行DES解密,获取密文原文。
问:为什么突然想要连接apollo这么个需求?
答:公司的数据库所在服务器中了勒索病毒了。
没错,你完全可以瞪大双眼,并且张着嘴巴表达不可思议,因为这就是事实,在8月17日那天,刚刚睡醒(啥时候睡醒的?大概中午十二点左右吧),本想着弹着吉他(新手,每天只会弹个破《晴天》,乐此不疲)开始度过难得的 HAPPY WEEKEND!
“嗡嗡嗡~”
突然手机自发的震动起来,无意的扫了一眼:未知来电。呵,估计又是广告,本想着直接划掉不接,但是正好也没什么事,就顺手接一下了。
“喂,请问您是?”我先小声试探着,“我,XX”,“哦,什么事?”,“那个,我们服务器中勒索病毒了,等下要开个会,时间不长”,此时的我,也无法判断自己是因为没睡醒而处于懵的状态,还是突如其来的,宛若仍然在睡梦之中的电话而愣在原地。“嗯,好的。”
当然此时的我心中越过千万想法,比如出事之前的几天,他才对另外一个管服务器的同事说过:我们现在数据库服务器就一台,你心里感觉慌吗,反正我是觉得慌的。事实上,他的这种强烈第六感,还没捂热,就灵验了,虽然大家都不希望这个事情的发生。
也许你会迫不及待的想问:欸,服务器不是在内网吗?欸,数据库没有主从或者备份吗?欸,服务器没有快照吗?欸,那怎么办?但是因为种种原因,在此且容我不做回答。
当然,解决方式来说,聪明的你也应能领悟到了,赎金是不可能交的(这是完全正确的,因为赎金这种东西,本身就是很多诈骗的起点,如果你指望着交了赎金就能重获主动权,那只能说是奢望)。万幸的是,一个离开的前辈,在去年给数据库留下了一份备份记录,保存了大量的有价值的数据,还有一部分是从BI服务器上反推回来,才得以保证核心业务模块的正常运行。
首先需要引入apollo-client的mavaen依赖包,如下:
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-client</artifactId>
<version>2.3.0</version>
</dependency>
接着在配置文件中配置连接,我这里就以yml示例,首先app.id是对于的apollo应用id,必须指定一个当前项目的apollo应用。接着设置meta,即连接的链接,cache-dir 指定缓存存储位置(如果配置中心挂了,本地也依然能够正常访问)。cluster设置集群名称,namespace是所属命名空间,如果要同时应用多个命名空间,则使用英文逗号隔开。
app:
id: "yourAppId"
apollo:
meta: "http://192.168.100.10:10086"
cache-dir: E:\cache\apollo
cluster: cluster1
bootstrap:
enabled: true
namespaces: application,dreamcenter.public
后续如果要使用的话,则使用@Value即可赋值,如:
@Value("${redisAddr}")
private String redisAddr;
比如,我们要依据apollo获取的数据库信息,并且设置datasource连接可以如下:
package top.dreamcenter.dataviewer.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import top.dreamcenter.dataviewer.entity.DBConnModel;
import top.dreamcenter.dataviewer.util.DBConnUtil;
import javax.sql.DataSource;
@Configuration
public class DBConnConfig {
@Value("${uname}")
private String uname;
@Value("${upass}")
private String upass;
@Value("${url}")
private String url;
@Bean
public DBConnModel dbConnModel(){
return new DBConnModel(uname,upass,url);
}
@Bean
public DataSource dataSource() {
DBConnModel model = dbConnModel();
return DataSourceBuilder.create()
.url(model.getUrl())
.username(model.getUsername())
.password(model.getPassword())
.build();
}
}
一开始是用Hutool工具包里集成的des加解密工具类,实际应用非常的简单,只要使用DES类即可实现,实际测试也确实能够正确解密到正确的数据,但是当打包结束后,执行jar包却报了错误,错误的信息大致上是:
JCE cannot authenticate the provider BC,说是打包的问题,要配置打包方式或者配置security等内容,实际操作下来,皆未得预期,所以最终还是用java原生的加密类自己封装工具类。
DES加解密主要步骤:明文/密文->加密/解密函数(DES对称加密,加解密函数一致)->密文/明文。密钥需要为8字节,64位。熟知的加密模式有ECB(Electronic Codebook Book 电码本模式)、CBC(Cipher Block Chaining 密码分组链接模式)。此外还要注意使用对应的填充方式,如NONE无填充,PKCS7补位,ZERO补0等。
我这里示例为DES解密CBC无填充。
package top.dreamcenter.dataviewer.util;
import jakarta.xml.bind.DatatypeConverter;
import top.dreamcenter.dataviewer.entity.DBConnModel;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
public class DBConnUtil {
public static String decode(String text, String key) {
SecretKeySpec myKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "DES");
IvParameterSpec iv = new IvParameterSpec(key.getBytes(StandardCharsets.UTF_8));
Cipher cipher = null;
try {
cipher = Cipher.getInstance("DES/CBC/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, myKey, iv);
byte[] byteArray = DatatypeConverter.parseHexBinary(text);
byte[] bytes = cipher.doFinal(byteArray);
return new String(bytes);
} catch (Exception e) {
e.printStackTrace();
}
throw new RuntimeException("解密失败");
}
}