现在的开发习惯,无论是公司的项目还是个人的项目,都会选择将源码上传到Git服务器(GitHub、Gitee或是自建服务器),但只要将源码提交到公网服务器就会存在源码泄漏的风险,而数据库配置信息作为源码的一部分,一旦出现源码泄漏,那么数据库中的所有数据都会公之于众,其产生的不良后果无法预期(比如某某酒店的信息)。
于是为了避免这种问题的产生,我们至少要对数据库的密码进行加密操作,这样即使得到了源码,也不会造成数据的泄露,也算保住了最后一块遮羞布。
如何加密?对于Java项目来说,要想快速实现数据库的加密,最简单可行的方案就是使用阿里巴巴提供的Druid来实现加密。
什么是Druid?Druid(中文译为“德鲁伊”)是阿里巴巴开源的一款Java语言中最好的数据库连接池。Druid提供了强大的监控和扩展功能,当然也包含了数据库的加密功能。
Druid开源地址:
Druid可以做什么?Druid可以监控数据库访问性能,Druid内置提供了一个功能强大的StatFilter插件,能够详细统计SQL的执行性能,这对于线上分析数据库访问性能有帮助。
替换数据库连接池DBCP和C3P0,Druid提供了一个高效、功能强大、可扩展性好的数据库连接池。
数据库密码加密,直接把数据库密码写在配置文件中,这是不好的行为,容易导致安全问题。DruidDruiver和DruidDataSource都支持PasswordCallback。
SQL执行日志,Druid提供了不同的LogFilter,能够支持Common-Logging、Log4j和JdkLog,你可以按需要选择相应的LogFilter,监控你应用的数据库访问情况。
扩展JDBC,如果你要对JDBC层有编程的需求,可以通过Druid提供的Filter-Chain机制,很方便编写JDBC层的扩展插件。
对于本文来说,我们重点来看它的第3个特性,也就是使用Druid来实现数据库密码加密。
加密执行流程在没有进行密码加密之前,项目的交互流程是这样的:

在使用了密码加密之后,项目的交互流程就变成了这样:

本示例运行环境:
1.添加Druid依赖Maven项目:
/groupIdartifactIddruid-spring-boot-starter//version/depency
Gradle项目:
compile':druid-spring-boot-starter:1.2.5'
获取Druid最新版本:
2.生成密文Druid添加完成之后就可以借助Druid中提供的ConfigTools类来加密密码了,实现代码如下:
;classMyTests{publicstaticvoidmain(String[]args)throwsException{//需要加密的明文命名Stringpassword="youPassword";//【注意:这里要改为你自己的密码】//调用druid生成私钥、公钥、密文(newString[]{password});}}以上代码执行的结果如下:
从上述结果可以看出,使用ConfigTools类会生成3部分的内容:
privateKey:私钥,暂时不会用到,用于密码的加密;
publicKey:公钥,用于密码的解密;
password:加密之后的密码。
3.添加配置完成了以上操作之后,只需要将上一步生成的公钥和密文添加到项目的配置文件(或)中就实现了加密操作了,具体配置信息如下:
spring:encryptconfigfilters:configconnect-properties:::MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKTo3DFkg8yYilRprXAQaED7TPbVVth9nJ0usWSuza280F2Fi0A9s3nyK68fbzL6kSBxKpJgB07lHFFx4AsbtHMCAwEAAQ==
其中password对应的是上一步生成的password(密文),而对应的是上一步生成的publicKey(公钥),如下图所示:

这里提供一个原始的配置文件,以便和加密后的配置文件进行比对:

经过前面3步的配置之后,我们的程序就可以正常运行了,但这远没有结束!
在第3步配置时,我们将密文和公钥都写入配置文件,这就会造成当有人拿到密文和公钥之后,就可以使用Druid将加密的密码还原出来了,这就好比一把插着钥匙的锁是极不安全的。
因此我们正确的使用姿势:是将公钥找一个安全的地方保存起来,每次在项目启动时动态的将公钥设置到项目中,这样就可以有效的保证密码的安全了。
正确的配置文件接下来我们将SpringBoot的公钥设置为配置项,在项目运行时再替换为具体的值,最终的安全配置信息如下:
spring:encryptconfigfilters:configconnect-properties:::${}可以看出公钥被修改成“${}”了,这就相当于使用占位符先把坑给占上,等项目启动时再更换上具体的值。
开发环境替换公钥开发环境只需要在Idea的启动参数中配置公钥的值即可,如下图所示:

当我们输入正确的公钥值时程序可以正常运行,当输入一个错误的公钥值时就会提示解码失败,如下图所示:

生产环境在启动jar包时只需要动态设置公钥的值即可,参考以下命令:
Druid运行原理经过上述步骤之后,我们就完成MySQL密码的加密了,这样当SpringBoot项目启动时,Druid的拦截器会使用密文和公钥将密码还原成真实的密码以供项目使用,当然这一切都无需人工干预(无需编写任何代码),Druid已经帮我封装好了,我们只需要通过以上配置即可。
什么?你想知道Druid是如何通过密文和公钥还原出真实的密码的?
没问题,满足你,其实ConfigTools类中已经提供了相应实现,代码如下:
//密文Stringpassword="VwH1mu2IUpqjfKTd+gSikiZgJTi+3Y5zFIFRfxYnH1UqHzm1K8TIHnMaV3TErBaGsVEaGV0e63pb0Ys3Wdm7Kg==";//公钥StringpublicKey="MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALWIEp19IM04sB+vQXnEOH9gFNFdL5TFGSEhORgHj4MnfTfBSNaOoSgCaM8BOpjiHmwuEb7LpvmXI1x/ymUvNzECAwEAAQ==";//还原成真实的密码Stringresult=(publicKey,password);("最终结果:"+result);总结本文我们使用阿里巴巴开源的Druid实现了MySQL的密码加密,Druid的加密过程非常方便,无需编写任何代码,只需要添加Druid依赖,再通过Druid的工具类生成密文,最后将密文配置到文件即可。项目在运行时会通过拦截器将密文转换成真正的密码,从而实现了MySQL密码的加密和解码的过程。
最后原创不易,如果觉得本文对你有帮助,请点个赞再走呗。