本文转载自微信公众号《程序新视野》,作者为二哥。转载本文请联系程序新视界公众号。在实践中,需要对项目的一些配置信息进行加密,以降低敏感信息泄露的风险。比如在使用Druid时,可以根据它提供的公私钥加密方式对数据库密码进行加密。但更多时候,Redis密码、MQ密码等敏感信息也需要加密,这时候就没那么方便了。本文介绍Java类库Jasypt,并演示如何基于SpringBoot项目对配置文件信息进行加密。一个简单的SpringBoot项目让我们首先创建一个简单的SpringBoot项目来构建加密数据使用的场景。无论是通过Idea还是官网等,首先创建一个SpringBoot项目,核心依赖为:org.springframework.bootspring-boot-starter-weborg.projectlomboklombok创建配置文件类ConfigProperties:@Data@ComponentpublicclassConfigProperties{@Value("${conf.url}")privateStringurl;@Value("${conf.password}")privateStringpassword;}将配置文件中的配置属性注入到该类中,供后续使用使用。创建一个Controller类,测试能否正常运行:@RestController@RequestMapping("/")(configProperties.getPassword());}}对应ConfigProperties类,application.properties中的配置如下:conf.url=127.0.0.1conf.password=admin123此时,启动项目,访问Controller,并正常打印出配置信息,说明程序可以正常运行。但是密码项在配置文件中是直接明文显示的。如果其他人看到配置文件,密码可能会泄露。基于Jasypt的加密就是针对上述情况的。通常,我们对敏感信息进行加密,避免明文密码信息外泄,提高安全级别。加密的基本思想是:将加密后的内容存放在配置文件中,在解析配置文件的注入时解密。但是如果你拿到了项目的源码,知道了加密算法和秘钥,那肯定是可以解密的。这里的加密只是多了一层安全保护,但并不是万能的。让我们看看如何基于Jasypt进行加密。下面的集成步骤将在上述SpringBoot项目的基础上进行改造升级。环境准备不同版本的Jasypt有不同的使用方法。下面是基于3.0.4版本、JDK8、SpringBoot2.5.5的演示。使用前先检查JDK8的JRE中是否安装了不限长的JCE版本,否则在进行加密操作时会抛出解密失败的异常。进入$JAVA_HOME/jre/lib/security目录查看是否包含local_policy.jar和US_export_policy.jar两个jar包。如果没有,通过Oracle官网下载,下载地址:https://www.oracle.com/java/technologies/javase-jce8-downloads.html。下载文件为:jce_policy-8.zip文件包含三个文件:README.txtlocal_policy.jarUS_export_policy.jar查看$JAVA_HOME/jre/lib/security目录下是否有这两个jar包文件,如果没有,复制进去,如果有一些覆盖需要考虑。引入依赖在SpringBoot中集成Jasypt比较简单,直接引入如下依赖即可:version>3.0.4此时Jasypt组件的自动配置已经生效,只需要处理需要加密的数据。为了方便加密密码,还可以在pom.xml中的build元素中引入对应的插件,后面会用到:com.github.ulisesbocchiojasypt-maven-plugin3.0.4至此,所有准备工作已经完成。内容加密加密内容的方法有很多种。这里选择两种方法进行介绍。方法一:单元测试类生成密文;构建以下单元测试类并使用默认实例化的StringEncryptor来加密密码:@SpringBootTestclassSpringBootJasyptApplicationTests{@AutowiredprivateStringEncryptorstringEncryptor;@TestvoidcontextLoads(){Stringqwerty1234=stringEncryptor.encrypt("admin123");System.out.println(qwerty1234);}}其中,“admin123”为需要加密的内容。执行以上步骤后,就可以打印加密内容了。本表所有加密内容均采用默认值。方法二:通过Maven插件生成密文。上面介绍了Jasypt的Maven插件,可以通过相应的命令生成密码。第一步:在配置文件中添加加密密码:jasypt.encryptor.password=afx11然后修改配置文件中需要加密的数据,在数据前添加“DEC(”,末尾添加“)”数据,修改如下:conf.password=DEC(admin123)这里添加的DEC()是告诉插件这部分内容需要加密。请注意,这里的关键字是DEC。第二步:执行Maven命令加密以上数据在命令中执行如下命令:mvnjasypt:encrypt-Djasypt.encryptor.password=afx11现在看配置文件中的conf.password数据已经改为:jasypt.encryptor.password=afx11conf.url=127.0.0.1conf.password=ENC(209eBdF3+jsV2f8kDjs4NOCzgBxnVgETlR5q2KfhYo5DW2jqvLknv0TndEkXOXm0)注意原来的DEC变成了ENC,原来的明文密码变成了加密后的密文。此时如果想查看明文,执行如下命令:mvnjasypt:decrypt-Djasypt.encryptor.password=afx11该命令不会将配置文件中的密文修改为明文,只会输出明文结果到控制台。jasypt.encryptor.password=afx11conf.url=127.0.0.1conf.password=DEC(admin123)经过以上操作,所有改造步骤都已经完成,只需启动系统进行验证即可。密码转移方法完成以上步骤,直接启动系统,访问对应的request,会发现原来的密码已经成功打印出来了。在上面的例子中,我们将加密后的密码放在application.properties文件中,这样是不安全的。如果你看代码,你就会知道如何解密它。通常,还有另一种传递参数的方式:在启动命令中传递密码。例如:java-jarjasypt-spring-boot-demo-0.0.1-SNAPSHOT.jar--jasypt.encryptor.password=password这样代码中就不需要保存密码了,增加了安全性一定程度。当然也可以通过环境变量传递,这样即使是开发者也无法获取到生产密码。总结以上就是Jasypt的使用以及与SpringBoot的集成。有关详细信息,请参阅官方文档。如果你的项目中还有很多明文存储的密码,确实需要考虑使用类似的框架进行加密。示例源码地址:https://github.com/secbr/springboot-all/tree/master/springboot-jasypt官方源码地址:https://github.com/ulisesbocchio/jasypt-spring-boot