這篇文章主要講解了“Java中如何給數(shù)據(jù)庫(kù)加密配置項(xiàng)”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“Java中如何給數(shù)據(jù)庫(kù)加密配置項(xiàng)”吧!
在鎮(zhèn)賚等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場(chǎng)前瞻性、產(chǎn)品創(chuàng)新能力,以專(zhuān)注、極致的服務(wù)理念,為客戶(hù)提供成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作、外貿(mào)網(wǎng)站建設(shè) 網(wǎng)站設(shè)計(jì)制作按需求定制網(wǎng)站,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),品牌網(wǎng)站制作,網(wǎng)絡(luò)營(yíng)銷(xiāo)推廣,外貿(mào)網(wǎng)站建設(shè),鎮(zhèn)賚網(wǎng)站建設(shè)費(fèi)用合理。
... 省略 ...
## 配置MySQL數(shù)據(jù)庫(kù)連接
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://121.196.xxx.xxx:3306/user?useUnicode=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=123456
## 配置redis緩存連接
redis.host=121.196.xxx.xxx
redis.port=6379
redis.password=111111
## 配置SMS短信服務(wù)連接
ali.sms.access_key_id=2zHmLdxAes7Bbe2w
ali.sms.access_key_secret=bImWdv6iy0him8ly
... 省略 ...
這是節(jié)選自某個(gè)典型的Spring Boot項(xiàng)目的application.properties配置文件。
噓… 偷偷告訴我,是不是很多小伙伴也都是這么寫(xiě)的?
這乍一看沒(méi)啥問(wèn)題,很多人會(huì)覺(jué)得理所當(dāng)然。包括我自己也看到過(guò)很多的項(xiàng)目(包括很多開(kāi)源項(xiàng)目)是這么寫(xiě)的。
但仔細(xì)一琢磨,發(fā)現(xiàn):
是的! 很多項(xiàng)目的配置文件里,包括數(shù)據(jù)庫(kù)密碼、緩存密碼、亦或是一些第三方服務(wù)的Key都是直接配在里面,沒(méi)有做任何加密處理!
有人會(huì)說(shuō)這個(gè)配置文件反正是我自己的,有啥風(fēng)險(xiǎn)?
這個(gè)嘛,之前倒是看到過(guò)一個(gè)例子,一個(gè)程序員把自己公司的項(xiàng)目代碼上傳到了自己的GitHub倉(cāng)庫(kù)里了,結(jié)果配置文件忘了處理,導(dǎo)致公司數(shù)據(jù)庫(kù)泄露,關(guān)鍵問(wèn)題是,這個(gè)公司還是個(gè)酒店管理公司,因此后果可想而知了…
換個(gè)角度想,假如當(dāng)時(shí)那個(gè)項(xiàng)目的配置文件里,所有重要信息都經(jīng)過(guò)了加密,那這一幕大概率就不會(huì)發(fā)生了。所以,即使是項(xiàng)目的配置文件,重要的信息也得加密!
一般來(lái)說(shuō),項(xiàng)目配置文件里,所有涉及信息安全的配置項(xiàng)(或字段)都應(yīng)該做處理,典型的比如:
用到的數(shù)據(jù)庫(kù)、緩存的密碼
用到的中間件、消息隊(duì)列的密碼
用到的各種第三方服務(wù)的Access_Key
其他第三方服務(wù)的通信信息
…等等
總而言之,關(guān)鍵字段都應(yīng)該保護(hù)起來(lái),最起碼不能用明文直接寫(xiě)在配置文件里!
方法非常簡(jiǎn)單,幾個(gè)步驟即可完成,先來(lái)演示一個(gè)最簡(jiǎn)版本:
1、首先建立一個(gè)基礎(chǔ)的Spring Boot工程
這就不再贅述了
2、引入jasypt-spring-boot加密組件
通過(guò)jasypt-spring-boot這個(gè)開(kāi)箱即用的加密組件來(lái)引入Jasypt這個(gè)強(qiáng)大的加密庫(kù)
com.github.ulisesbocchio
jasypt-spring-boot-starter
3.0.2
3、配置加密密鑰
在Spring Boot的項(xiàng)目配置文件application.properties里新增如下配置:
jasypt.encryptor.password=CodeSheep
可以理解為jasypt會(huì)使用這個(gè)自定義加密密鑰,對(duì)配置文件里的重要項(xiàng)進(jìn)行加密。
4、加密測(cè)試
為了便于測(cè)試,我們直接擴(kuò)展Spring Boot項(xiàng)目的啟動(dòng)類(lèi),項(xiàng)目啟動(dòng)時(shí)執(zhí)行加密測(cè)試代碼,直接看效果
@SpringBootApplication
public class SpringBootConfigEncryptApplication implements CommandLineRunner {
@Autowired
private ApplicationContext appCtx;
@Autowired
private StringEncryptor codeSheepEncryptorBean;
public static void main(String[] args) {
SpringApplication.run(SpringBootConfigEncryptApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
Environment environment = appCtx.getBean(Environment.class);
// 首先獲取配置文件里的原始明文信息
String mysqlOriginPswd = environment.getProperty("spring.datasource.password");
String redisOriginPswd = environment.getProperty("redis.password");
String aliSmsOriginAk = environment.getProperty("ali.sms.access_key_secret");
// 加密
String mysqlEncryptedPswd = encrypt( mysqlOriginPswd );
String redisEncryptedPswd = encrypt( redisOriginPswd );
String aliSmsEncryptedAk = encrypt( aliSmsOriginAk );
// 打印加密前后的結(jié)果對(duì)比
System.out.println( "MySQL原始明文密碼為:" + mysqlOriginPswd );
System.out.println( "Redis原始明文密碼為:" + redisOriginPswd );
System.out.println( "阿里云SMS原始AccessKey密碼為:" + aliSmsOriginAk );
System.out.println( "====================================" );
System.out.println( "MySQL原始明文密碼加密后的結(jié)果為:" + mysqlEncryptedPswd );
System.out.println( "Redis原始明文密碼加密后的結(jié)果為:" + redisEncryptedPswd );
System.out.println( "阿里云SMS原始AccessKey密碼加密后的結(jié)果為:" + aliSmsEncryptedAk );
}
private String encrypt( String originPassord ) {
String encryptStr = codeSheepEncryptorBean.encrypt( originPassord );
return encryptStr;
}
private String decrypt( String encryptedPassword ) {
String decryptStr = codeSheepEncryptorBean.decrypt( encryptedPassword );
return decryptStr;
}
}
運(yùn)行項(xiàng)目,控制臺(tái)打印:
MySQL原始明文密碼為:123456
Redis原始明文密碼為:111111
阿里云SMS原始AccessKey密碼為:bImWdv13da894mly
====================================
MySQL原始明文密碼加密后的結(jié)果為:IV7SyeQOfG4GhiXeGLboVgOLPDO+dJMDoOdmEOQp3KyVjruI+dKKeehsTriWPKbo
Redis原始明文密碼加密后的結(jié)果為:litUkxJ3fN6+//Emq3vZ+y4o7ZOnZ8doOy7NrgJIDLoNWGG0m3ygGeQh/dEroKvv
阿里云SMS原始AccessKey密碼加密后的結(jié)果為:MAhrOs20DY0RU/c1IKyLCt6dWZqLLOO4wUcK9GBgSxNII3C+y+SRptors+FyNz55xNDslhDnpWllhcYPwZsO5A==
5、修改配置文件,替換待加密配置項(xiàng)
我們拿到上一步得到的加密結(jié)果,將配置文件中的原始明文密碼替換成上一步對(duì)應(yīng)的結(jié)果即可,就像這樣:
所以墻裂建議配置文件里的所有重要信息都這樣處理!
6、查看密碼解密結(jié)果
@SpringBootApplication
public class SpringBootConfigEncryptApplication implements CommandLineRunner {
@Autowired
private ApplicationContext appCtx;
@Autowired
private StringEncryptor codeSheepEncryptorBean;
public static void main(String[] args) {
SpringApplication.run(SpringBootConfigEncryptApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
Environment environment = appCtx.getBean(Environment.class);
// 首先獲取配置文件里的配置項(xiàng)
String mysqlOriginPswd = environment.getProperty("spring.datasource.password");
String redisOriginPswd = environment.getProperty("redis.password");
String aliSmsOriginAk = environment.getProperty("ali.sms.access_key_secret");
// 打印解密后的結(jié)果
System.out.println( "MySQL原始明文密碼為:" + mysqlOriginPswd );
System.out.println( "Redis原始明文密碼為:" + redisOriginPswd );
System.out.println( "阿里云SMS原始AccessKey密碼為:" + aliSmsOriginAk );
}
}
打印結(jié)果:
MySQL原始明文密碼為:123456
Redis原始明文密碼為:111111
阿里云SMS原始AccessKey密碼為:bImWdv13da894mly
很明顯,在代碼中使用時(shí),jasypt-spring-boot組件會(huì)自動(dòng)將ENC()語(yǔ)法包裹的配置項(xiàng)加密字段自動(dòng)解密,數(shù)據(jù)得以還原。
這時(shí)候我想肯定很多小伙伴表示疑惑,典型的比如:
1、加密密鑰必須放在ENC()中?為什么是ENC?
2、雖然說(shuō)原始涉及信息安全的配置項(xiàng)被加密,但是自定義的加密密鑰jasypt.encryptor.password=CodeSheep假如泄露了,別人不還是有幾率可以解密的嗎?
針對(duì)這些問(wèn)題,繼續(xù)往下看。
如果不愿意使用jasypt默認(rèn)提供的ENC來(lái)標(biāo)記加密字段,完全可以換成自定義的前后綴標(biāo)記,比如我想換成CodeSheep()來(lái)標(biāo)記加密字段,此時(shí)只需要在配置文件里配置一下前后綴即可:
jasypt.encryptor.property.prefix=CodeSheep(
jasypt.encryptor.property.suffix=)
這時(shí)候加密字段就可以放在CodeSheep()標(biāo)記的字段中:
雖然經(jīng)過(guò)上文的加密,涉及信息安全的配置項(xiàng)肯定會(huì)變得更安全,這個(gè)毋庸置疑!
但是假如配置文件里的自定義加密密鑰jasypt.encryptor.password=CodeSheep泄露了,那我們的加密字段也還是有可能被別人解密,為此,有幾項(xiàng)工作可以讓加密變得更加安全。
1、使用自定義加密器
上文實(shí)驗(yàn)加密時(shí),使用的是默認(rèn)的加密規(guī)則,這一點(diǎn)會(huì)讓當(dāng)自定義加密密鑰泄漏時(shí)可能變得不安全。為此我們可以自定義加密規(guī)則。
自定義加密規(guī)則非常簡(jiǎn)單,只需要提供自定義的加密器配置類(lèi)即可,比如我這里自定義一個(gè)名為 codeSheepEncryptorBean類(lèi)型的加密器:
@Configuration
public class CodeSheepEncryptorCfg {
@Bean( name = "codeSheepEncryptorBean" )
public StringEncryptor codesheepStringEncryptor() {
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
config.setPassword("CodeSheep");
config.setAlgorithm("PBEWITHHMACSHA512ANDAES_256");
config.setKeyObtentionIterations("1000");
config.setPoolSize("1");
config.setProviderName("SunJCE");
config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator");
config.setStringOutputType("base64");
encryptor.setConfig(config);
return encryptor;
}
}
注意這里Bean的名字name是需要顯式指定的(默認(rèn)的名字是jasyptStringEncryptor),如果像這里一樣用的自定義名字,則還需要在Spring Boot的application.properties配置文件中來(lái)指定bean的名字,就像這樣:
jasypt.encryptor.bean=codeSheepEncryptorBean
2、加密密鑰不要寫(xiě)在配置文件中
如果覺(jué)得上面這種方式還是可能會(huì)導(dǎo)致加密密鑰泄露的話(huà)(畢竟還是寫(xiě)在了配置文件中),那我們干脆可以直接將加密密鑰從配置文件中拿掉,取而代之的有三種方式:
方式一:直接作為程序啟動(dòng)時(shí)的命令行參數(shù)來(lái)帶入
java -jar yourproject.jar --jasypt.encryptor.password=CodeSheep
方式二:直接作為程序啟動(dòng)時(shí)的應(yīng)用環(huán)境變量來(lái)帶入
java -Djasypt.encryptor.password=CodeSheep -jar yourproject.jar
方式三:甚至可以作為系統(tǒng)環(huán)境變量的方式來(lái)帶入
比方說(shuō),我們提前設(shè)置好系統(tǒng)環(huán)境變量JASYPT_ENCRYPTOR_PASSWORD = CodeSheep,則直接在Spring Boot的項(xiàng)目配置文件中做如下配置即可:
jasypt.encryptor.password=${JASYPT_ENCRYPTOR_PASSWORD:}
感謝各位的閱讀,以上就是“Java中如何給數(shù)據(jù)庫(kù)加密配置項(xiàng)”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)Java中如何給數(shù)據(jù)庫(kù)加密配置項(xiàng)這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!