问题:
项目中含有配置文件,而配置文件中含有数据库的用户名和密码。而团队猪队友不论三七二十一玩git时全都上传git。git上开放给外部用户。外部用户获得数据库ip地址,用户名,密码。如果运维猪队友数据库为方便直接对外网开放。那后果会怎样可想而知。
如果防护呢?
我们可以用jasypt进行解决。引入其依赖,cmd执行加盐加密获得密码,在application.yml中的数据库密码就是要ENC(加密后密码)
1、jasypt
Jasypt也即Java Simplified Encryption是Sourceforge.net上的一个开源项目。
Jasypt这个Java类包为开发人员提供一种简单的方式来为项目增加加密功能,包括:密码Digest认证,文本和对象加密。
为何使用它,厉害之处
注意哦,下面每次执行的加密结果是不一样的哦(腻害),如MD5,key相同结果相同,即使其它加密算法加上盐,破解难度大,但结果固定就可以通过字典表暴力破解。
而Jasypt 内部会创建一个随机 IV,这样每次即使相同的内容和盐得到的结果却不同。
2、基础概念
对称加密(Symmetric encryption):
加密和解密用同一个密钥的方法,即为对称加密算法。
哈希算法(Hash):
也叫散列、杂凑、摘要,或音译为哈希,是把任意长度的输入(又叫做预映射pre-image)通过散列算法变换成固定长度的输出,该输出就是散列值,哈希算法是单向算法,即无法通过哈希值倒推原始数据。
口令散列(Password Hashing):
是将用户输入的密码通过一系列算法处理后,生成一个固定长度的散列值。口令散列常用语口令存储和密钥生成。在软件系统中,出于安全需求,用户密码不允许直接在数据库中明文存储的,通过对口令做哈希在入库,这样即是数据库泄露了,用户密码依然不会泄露。对于密钥生成的场景,需区分口令和密钥的区别,密钥是指加密过程中实际作用于加密算法的数据串,也叫key,key一般长度较长(16或32字节以上),实际场景中不太可能让用户去设置和记住这么长的密码,因此一般使用用户设置的短密码(也叫口令),用hash算法对口令做散列,用散列出的key加密数据。由于用户口令普遍较短,密码空间较小,重复率比较高,如果数据库发生泄漏,攻击者通过密码和散列值的映射表(又称彩虹表)用于多个用户口令的碰撞,于是在实际散列的时候需加入其它“值”合并计算。该值又称盐或salt,且每个用户的salt都不一样。如果攻击者试图通过彩虹表对口令做碰撞,需要针对每个用户生成口令长度(散列值隐去了实际口令长度)不同的彩虹表,大大增加了破解的难度。口令散列可简化为:hash(口令+salt)。
3、实战:SpringBoot整合jasypt
第一步:pom.xml依赖
<!-- git,对敏感信息进行ENC加密 -->
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jasypt/jasypt -->
<dependency>
<groupId>org.jasypt</groupId>
<artifactId>jasypt</artifactId>
<version>1.9.3</version>
</dependency>
第二步:cmd执行命令获取加密后的密码
1、jar包目录
利用第二个依赖下载加密的程序
D:\workspace\env\mvnrepo\org\jasypt\jasypt\1.9.3
2、执行命令
java -cp jasypt-1.9.3.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input="root" password=chenchen algorithm=PBEWithMD5AndDES
- cp:classpath参数
- input:需要加密的,如数据库的密码
- password:加密的盐,提升加密个性化,增加破解难度,自定义值如:chenchen
- algorithm:加密算法,默认:PBEWithMD5AndDES
3、执行结果:
第三步:application.yml
下面数据库密码进行加密,ENC代表其使用了加密。
同时也必须告诉SpringBoot加密的盐:jasypt.encryptor.password
server:
port: 8060
jasypt:
encryptor:
password: chenchen
spring:
application:
name: bank-cif
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/bank-cif?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
username: root
password: ENC(hoPuXXMfIMRIJBk4a2kgsw==)
hikari:
minimum-idle: 5
maximum-pool-size: 15
auto-commit: true
idle-timeout: 30000
pool-name: DatebookHikariCP
max-lifetime: 1800000
connection-timeout: 30000
connection-test-query: SELECT 1
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
mapper-locations: classpath:/mapper/*.xml
type-aliases-package: com.bank.cif.entity
第四步:加密了,使用时就需要解密
启动类上加注解即可:@EnableEncryptableProperties
package com.bank.cif;
import com.ulisesbocchio.jasyptspringboot.annotation.EnableEncryptableProperties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScans;
//新版SpringBoot2.7.14它和之前版本配置包扫码方式不同
//加一个注解@ComponentScans,然后里面配置即可
@SpringBootApplication
@ComponentScans(@ComponentScan("com.bank.config"))
@EnableEncryptableProperties //对数据库密码进行加密,防止明码上传到git,造成问题
public class BankCifRunApp {
public static void main(String[] args) {
SpringApplication.run(BankCifRunApp.class, args);
}
}