配置加密_数据库密码配置项都不加密?心也太大了!
先看一份典型的配置文件
... 省略 ...## 配置MySQL數據庫連接
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短信服務連接
ali.sms.access_key_id=2zHmLdxAes7Bbe2w
ali.sms.access_key_secret=bImWdv6iy0him8ly
... 省略 ...
這是節選自某個典型的Spring Boot項目的application.properties配置文件。
噓...?偷偷告訴我,是不是很多小伙伴也都是這么寫的?
”這乍一看沒啥問題,很多人會覺得理所當然。包括我自己也看到過很多的項目(包括很多開源項目)是這么寫的。
但仔細一琢磨,發現:
是的!?很多項目的配置文件里,包括數據庫密碼、緩存密碼、亦或是一些第三方服務的Key都是直接配在里面,沒有做任何加密處理!
有人會說這個配置文件反正是我自己的,有啥風險?
這個嘛,之前倒是看到過一個例子,一個程序員把自己公司的項目代碼上傳到了自己的GitHub倉庫里了,結果配置文件忘了處理,導致公司數據庫泄露,關鍵問題是,這個公司還是個酒店管理公司,因此后果可想而知了...
換個角度想,假如當時那個項目的配置文件里,所有重要信息都經過了加密,那這一幕大概率就不會發生了。所以,即使是項目的配置文件,重要的信息也得加密!
哪些信息要加密呢?
一般來說,項目配置文件里,所有涉及信息安全的配置項(或字段)都應該做處理,典型的比如:
- 用到的數據庫、緩存的密碼
- 用到的中間件、消息隊列的密碼
- 用到的各種第三方服務的Access_Key
- 其他第三方服務的通信信息
- ......等等
總而言之,關鍵字段都應該保護起來,最起碼不能用明文直接寫在配置文件里!
如何加密配置項呢?
方法非常簡單,幾個步驟即可完成,先來演示一個最簡版本:
1、首先建立一個基礎的Spring Boot工程
這就不再贅述了
2、引入jasypt-spring-boot加密組件
通過jasypt-spring-boot這個開箱即用的加密組件來引入Jasypt這個強大的加密庫
<dependency>????<groupId>com.github.ulisesbocchiogroupId>
????<artifactId>jasypt-spring-boot-starterartifactId>
????<version>3.0.2version>
dependency>
3、配置加密密鑰
在Spring Boot的項目配置文件application.properties里新增如下配置:
jasypt.encryptor.password=CodeSheep可以理解為jasypt會使用這個自定義加密密鑰,對配置文件里的重要項進行加密。
4、加密測試
為了便于測試,我們直接擴展Spring Boot項目的啟動類,項目啟動時執行加密測試代碼,直接看效果
@SpringBootApplicationpublic?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?);
????????//?打印加密前后的結果對比
????????System.out.println(?"MySQL原始明文密碼為:"?+?mysqlOriginPswd?);
????????System.out.println(?"Redis原始明文密碼為:"?+?redisOriginPswd?);
????????System.out.println(?"阿里云SMS原始AccessKey密碼為:"?+?aliSmsOriginAk?);
????????System.out.println(?"===================================="?);
????????System.out.println(?"MySQL原始明文密碼加密后的結果為:"?+?mysqlEncryptedPswd?);
????????System.out.println(?"Redis原始明文密碼加密后的結果為:"?+?redisEncryptedPswd?);
????????System.out.println(?"阿里云SMS原始AccessKey密碼加密后的結果為:"?+?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;
????}
}
運行項目,控制臺打印:
MySQL原始明文密碼為:123456Redis原始明文密碼為:111111
阿里云SMS原始AccessKey密碼為:bImWdv13da894mly
====================================
MySQL原始明文密碼加密后的結果為:IV7SyeQOfG4GhiXeGLboVgOLPDO+dJMDoOdmEOQp3KyVjruI+dKKeehsTriWPKbo
Redis原始明文密碼加密后的結果為:litUkxJ3fN6+//Emq3vZ+y4o7ZOnZ8doOy7NrgJIDLoNWGG0m3ygGeQh/dEroKvv
阿里云SMS原始AccessKey密碼加密后的結果為:MAhrOs20DY0RU/c1IKyLCt6dWZqLLOO4wUcK9GBgSxNII3C+y+SRptors+FyNz55xNDslhDnpWllhcYPwZsO5A==
5、修改配置文件,替換待加密配置項
我們拿到上一步得到的加密結果,將配置文件中的原始明文密碼替換成上一步對應的結果即可,就像這樣:
所以墻裂建議配置文件里的所有重要信息都這樣處理!
6、查看密碼解密結果
@SpringBootApplicationpublic?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");
????????//?打印解密后的結果
????????System.out.println(?"MySQL原始明文密碼為:"?+?mysqlOriginPswd?);
????????System.out.println(?"Redis原始明文密碼為:"?+?redisOriginPswd?);
????????System.out.println(?"阿里云SMS原始AccessKey密碼為:"?+?aliSmsOriginAk?);
????}
}????
打印結果:
MySQL原始明文密碼為:123456Redis原始明文密碼為:111111
阿里云SMS原始AccessKey密碼為:bImWdv13da894mly
很明顯,在代碼中使用時,jasypt-spring-boot組件會自動將ENC()語法包裹的配置項加密字段自動解密,數據得以還原。
小朋友,你是否有很多問號?
這時候我想肯定很多小伙伴表示疑惑,典型的比如:
1、加密密鑰必須放在ENC()中?為什么是ENC?
2、雖然說原始涉及信息安全的配置項被加密,但是自定義的加密密鑰jasypt.encryptor.password=CodeSheep假如泄露了,別人不還是有幾率可以解密的嗎?
針對這些問題,繼續往下看。
自定義加密前后綴
如果不愿意使用jasypt默認提供的ENC來標記加密字段,完全可以換成自定義的前后綴標記,比如我想換成CodeSheep()來標記加密字段,此時只需要在配置文件里配置一下前后綴即可:
jasypt.encryptor.property.prefix=CodeSheep(jasypt.encryptor.property.suffix=)
這時候加密字段就可以放在CodeSheep()標記的字段中:
讓加密更安全
雖然經過上文的加密,涉及信息安全的配置項肯定會變得更安全,這個毋庸置疑!
但是假如配置文件里的自定義加密密鑰jasypt.encryptor.password=CodeSheep泄露了,那我們的加密字段也還是有可能被別人解密,為此,有幾項工作可以讓加密變得更加安全。
1、使用自定義加密器
上文實驗加密時,使用的是默認的加密規則,這一點會讓當自定義加密密鑰泄漏時可能變得不安全。為此我們可以自定義加密規則。
自定義加密規則非常簡單,只需要提供自定義的加密器配置類即可,比如我這里自定義一個名為?codeSheepEncryptorBean類型的加密器:
@Configurationpublic?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是需要顯式指定的(默認的名字是jasyptStringEncryptor),如果像這里一樣用的自定義名字,則還需要在Spring Boot的application.properties配置文件中來指定bean的名字,就像這樣:
jasypt.encryptor.bean=codeSheepEncryptorBean2、加密密鑰不要寫在配置文件中
如果覺得上面這種方式還是可能會導致加密密鑰泄露的話(畢竟還是寫在了配置文件中),那我們干脆可以直接將加密密鑰從配置文件中拿掉,取而代之的有三種方式:
- 方式一:直接作為程序啟動時的命令行參數來帶入
- 方式二:直接作為程序啟動時的應用環境變量來帶入
- 方式三:甚至可以作為系統環境變量的方式來帶入
比方說,我們提前設置好系統環境變量JASYPT_ENCRYPTOR_PASSWORD = CodeSheep,則直接在Spring Boot的項目配置文件中做如下配置即可:
jasypt.encryptor.password=${JASYPT_ENCRYPTOR_PASSWORD:}這時候也會安全得多。
噓...
好了,說了這么多,如果你項目的配置文件中的重要信息沒有加密的話,答應我,二話別說,趕快全部偷偷去改掉,快!速度!跑步前進!
每天進步一點點,Peace!
2020.04.24 晚
給個[在看],是對程序羊最大的支持總結
以上是生活随笔為你收集整理的配置加密_数据库密码配置项都不加密?心也太大了!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何给页面加上loding_怎么做404
- 下一篇: 小白重装系统教程_重装系统教程,小编教你