为什么加密?目前的开发习惯,无论是公司项目还是个人项目,都会选择将源码上传到Git服务器(GitHub、Gitee或者自建服务器),但是只要源码是公开提交的网络服务器会有源码泄露的风险,数据库配置信息是源码的一部分。一旦源代码泄露,数据库中的所有数据都将被公开,其不良后果难以预料(如某酒店的信息)。所以为了避免这种问题,我们至少要对数据库的密码进行加密,这样即使拿到源码也不会造成数据泄露,也算是保住了最后一块无花果叶子。如何加密?对于Java项目,如果想快速实现数据库加密,最简单可行的方案就是使用阿里巴巴提供的Druid来实现加密。什么是德鲁伊?Druid(中文翻译为“Druid”)是阿里巴巴开源的Java语言中最好的数据库连接池。Druid提供了强大的监控和伸缩功能,当然也包含了数据库加密功能。Druid开源地址:https://github.com/alibaba/druid/Druid可以做什么?Druid可以监控数据库访问性能。Druid内置了一个强大的StatFilter插件,可以对SQL执行性能进行详细的统计。有助于分析数据库访问性能。Druid取代了数据库连接池DBCP和C3P0,提供了一个高效、强大、可扩展的数据库连接池。数据库密码加密,数据库密码直接写在配置文件中。这是一种不良行为,很容易导致安全问题。DruidDruiver和DruidDataSource都支持PasswordCallback。对于SQL执行日志,Druid提供了不同的LogFilters,可以支持Common-Logging、Log4j、JdkLog。您可以根据需要选择相应的LogFilter来监控您的应用程序的数据库访问。扩展JDBC,如果需要对JDBC层进行编程,可以使用Druid提供的Filter-Chain机制,轻松编写JDBC层的扩展。对于本文,我们重点介绍它的第三个特点,即使用Druid实现数据库密码加密。加密执行过程在密码加密之前,项目的交互过程如下:使用密码加密后,项目的交互过程变成这样:使用Druid实现加密本例运行环境:SpringBoot2.4.3MySQL5。7Java1.8Idea2020.1.31。添加Druid依赖的Maven工程:com.alibabadruid-spring-boot-starter1.2.5Gradle工程:compile'com.alibaba:druid-spring-boot-starter:1.2.5'获取最新版本的Druid:https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter2。生成密文添加Druid后,可以使用Druid中提供的ConfigTools类对密码进行加密。实现代码如下:importcom.alibaba.druid.filter.config.ConfigTools;classMyTests{publicstaticvoidmain(String[]args)throwsException{//命名需要加密的明文Stringpassword="youPassword";//[注:这里改成你自己的密码]//调用druid生成私钥、公钥、密文ConfigTools.main(newString[]{password});}}以上代码执行的结果如下:privateKey:MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEApOjcMWSDzJiKVGmtcBBoQPtM9tVW2H2cnS6xZK7NrbzQXYWLQD2zefIrrx9vMvqRIHEqkmAHTuUcUXHgCxu0cwIDAQABAkAlqo5ItdWo0Jqf5zdXJlg5p2yP4HCiqCYyfKzF+2s9KEmgWZJWTctZDsgQ0iYUohORR59I+J4nabhel1x5/INpAiEA6jwSyFqMUPOh1XlrzNFek+RthOQ5n4+ALPo+vULayO0CIQC0O7JM9sIq+tg+jCGv+ypk6vbuRKY9m5W2rSRXapGm3wIgRHul3jAjIDPrF/f1HaAFL+Y0Yws7Ebyp8/yCRWF7iA0CIALbe20q8FMcHPeI4zPWCIsHCpkmb3hEkjAOOKhGIT8DAiAqiUuz92NqKeyjmOfons1ka65EzVwA3NDhZ6+IQcnuig==publicKey:MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKTo3DFkg8yYilRprXAQaED7TPbVVth9nJ0usWSuza280F2Fi0A9s3nyK68fbzL6kSBxKpJgB07lHFFx4AsbtHMCAwEAAQ==password:IMgKm27bOHok3/+5aDL4jGBoVVZkpicbbM6pIXQppi3dI7h3jngSAqhqwqYnfuYpyVJ0k++q9xWWnHtd6sAWnQ==从上述结果可以看out,使用ConfigTools类会生成三部分:privateKey:私钥,暂时不用,用于密码加密;publicKey:公钥,用于密码解密;password:加密后的密码PS:待实现数据库的加密主要使用publicKey(公钥)和password(密文),将明文转化为密文。3、添加配置完成以上操作后,只需要将上一步生成的公钥和密文添加到项目配置文件application.yml(或application.xml)中,即可实现加密操作。具体配置信息如下:spring:#MySQL配置datasource:driver-class-name:com.mysql.cj.jdbc.Drivertype:com.alibaba.druid.pool.DruidDataSourcedruid:url:jdbc:mysql://127.0.0.1:3306/testdb?serverTimezone=Asia/Shanghai&characterEncoding=UTF-8&useSSL=falseusername:rootpassword:IMgKm27bOHok3/+5aDL4jGBoVVZkpicbbM6pIXQppi3dI7h3jngSAqhqwqYnfuYpyVJ0k++q9xWWnHtd6sAWnQ==#encryptconfigfilters:configconnect-properties:config.decrypt:trueconfig.decrypt.key:MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKTo3DFkg8yYilRprXAQaED7TPbVVth9nJ0usWSuza280F2Fi0A9s3nyK68fbzL6kSBxKpJgB07lHFFx4AsbtHMCAwEAAQ==其中password对应的是上一步生成password(密文),config.decrypt.key对应上一步生成的publicKey(公钥),如下图:加密配置文件:4.注意事项-插入钥匙的锁的前3步配置完成后,我们的程序就可以正常运行了,b但这远未结束!在第三步配置中,我们把密文和公钥都写在了配置文件中,这会导致有人在拿到密文和公钥后,使用Druid来恢复加密后的密码。这就好比一把插了钥匙的锁,极不安全。所以,我们正确的使用姿势是找一个安全的地方保存公钥,在每次项目启动的时候动态的给项目设置公钥,这样才能有效的保证密码的安全。正确的配置文件接下来我们将SpringBoot的公钥设置为配置项,然后在项目运行时将其替换为具体的值。最终的安全配置信息如下:spring:#MySQL配置datasource:driver-class-name:com.mysql.cj.jdbc.Drivertype:com.alibaba.druid.pool.DruidDataSourcedruid:url:jdbc:mysql://127.0.0.1:3306/testdb?serverTimezone=Asia/Shanghai&characterEncoding=UTF-8&useSSL=falseusername:rootpassword:IMgKm27bOHok3/+5aDL4jGBoVVZkpicbbM6pIXQppi3dI7h3jngSAqhqwqYnfuYpyVJ0k++q9xWWnHtd6sAWnQ==#encryptconfigfilters:configconnect-properties:config.decrypt:trueconfig.decrypt.key:${spring.datasource.druid.publickey}可以看出,$publickey改成了“.dataspring.datasource.druid.publickey}druid.publickey}”,相当于用占位符先占坑,然后在项目启动时替换特定值。PS:“spring.datasource.druid.publickey”不是一个固定不变的key,这个key的值可以由用户自己定义。开发环境替换公钥开发环境只需要在Idea的启动参数中配置公钥的值,如下图所示:当我们输入正确的公钥值时,程序就可以正常运行,并且当我们输入错误的公钥值时会提示解码失败,如下图所示:生产环境替换公钥。生产环境只需要在启动jar包的时候动态设置公钥的值即可。参考如下命令:java-jarxxx.jar--spring.datasource。druid.publickey=你的公钥Druid运行原理经过以上步骤,我们就完成了对MySQL密码的加密,这样当SpringBoot项目启动时,Druid的拦截器会使用密文和公钥将密码还原为真实的一个是项目使用的密码,当然这一切不需要人工干预(不需要写任何代码),Druid已经帮我打包好了,我们只需要通过上面的配置即可。什么?想知道Druid是如何通过密文和公钥还原出真实密码的吗?Noproblem,satisfyyou,infact,thecorrespondingimplementationhasbeenprovidedintheConfigToolsclass,thecodeisasfollows://ciphertextStringpassword="VwH1mu2IUpqjfKTd+gSikiZgJTi+3Y5zFIFRfxYnH1UqHzm1K8TIHnMaV3TErBaGsVEaGV0e63pb0Ys3Wdm7Kg==";//公钥StringpublicKey="MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALWIEp19IM04sB+vQXnEOH9gFNFdL5TFGSEhORgHj4MnfTfBSNaOoSgCaM8BOpjiHmwuEb7LpvmXI1x/ymUvNzECAwEAAQ==";//还原真实的密码Stringresult=ConfigTools.decrypt(publicKey,password);System.out+println("最后结果:"小结本文使用阿里巴巴开源的Druid实现MySQL密码加密。Druid的加密过程非常方便。您不需要编写任何代码。只需要添加Druid依赖,然后通过Druid工具生成密文即可。最后,将密文配置到application.yml文件即可。项目运行时,拦截器会将密文转换成真正的密码,从而实现对MySQL密码加解密的过程。