SpringBoot項目使用jasypt-spring-boot加密數(shù)據(jù)庫密碼和配置文件

Jasypt是一個加密庫,Github上有一個集成了JasyptSpring Boot庫葛虐,叫jasypt-spring-boot,可以加密我們在源碼配置文件里面的有段的敏感信息鲤竹,如用戶名密碼等箫老,本文演示了如何使用該庫對配置文件進(jìn)行加密。

一彩库、先看一份典型的配置文件

... 
## 配置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短信服務(wù)連接
aliyun.sms.access_key_id=3zHmLddxAes7Bbe21
aliyun.sms.access_key_secret=b3mWd36iy0him8tr
...  

這是節(jié)選自某個典型的Spring Boot項目的application.properties配置文件肤无。這乍一看沒啥問題先蒋,很多人會覺得理所當(dāng)然骇钦。初期我的開源項目也是這樣寫的,直到某天我突然想到竞漾,如果大家拿項目里面的配置信息直接連接我的數(shù)據(jù)庫眯搭,然后刪除掉我數(shù)據(jù)庫的所有數(shù)據(jù),那世界上不就又多了一個傷心的人了业岁。


所以鳞仙,為了保證項目的安全,我們通用做法是將SpringBoot的配置文件中敏感并且重要的信息進(jìn)行加密處理笔时。

二棍好、使用jasypt-spring-boot加密配置文件

1、引入jasypt-spring-boot加密組件

maven:在項目pom中添加如下代碼

<dependency>
    <groupId>com.github.ulisesbocchio</groupId>
    <artifactId>jasypt-spring-boot-starter</artifactId>
    <version>3.0.2</version>
</dependency>

Gradle

implementation("com.github.ulisesbocchio:jasypt-spring-boot-starter:3.0.4")
2允耿、配置加密密鑰

在Spring Boot的項目配置文件application.properties里新增如下配置:

jasypt.encryptor.password=CodeSheep
3借笙、加密測試

為了便于測試,我們直接擴(kuò)展Spring Boot項目的啟動類较锡,項目啟動時執(zhí)行加密測試代碼业稼,直接看效果

@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é)果對比
        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)行項目,控制臺打勇煸獭:

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==
4低散、修改配置文件,替換待加密配置項

我們拿到上一步得到的加密結(jié)果骡楼,將配置文件中的原始明文密碼替換成上一步對應(yīng)的結(jié)果即可熔号,就像這樣:



所以強(qiáng)烈建議配置文件里的所有重要信息都這樣處理!

5鸟整、查看密碼解密結(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);
 
        // 首先獲取配置文件里的配置項
        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

很明顯引镊,在代碼中使用時,jasypt-spring-boot組件會自動將ENC()語法包裹的配置項加密字段自動解密,數(shù)據(jù)得以還原祠乃。

這時候我想肯定很多小伙伴表示疑惑梦重,典型的比如:
1、加密密鑰必須放在ENC()中亮瓷?為什么是ENC琴拧?
2、雖然說原始涉及信息安全的配置項被加密嘱支,但是自定義的加密密鑰jasypt.encryptor.password=CodeSheep假如泄露了蚓胸,別人不還是有幾率可以解密的嗎?
針對這些問題除师,繼續(xù)往下看沛膳。

三、自定義加密前后綴

如果不愿意使用jasypt默認(rèn)提供的ENC來標(biāo)記加密字段汛聚,完全可以換成自定義的前后綴標(biāo)記锹安,比如我想換成CodeSheep()來標(biāo)記加密字段,此時只需要在配置文件里配置一下前后綴即可:

jasypt.encryptor.property.prefix=CodeSheep(
jasypt.encryptor.property.suffix=)

四倚舀、讓加密更安全

雖然經(jīng)過上文的加密叹哭,涉及信息安全的配置項肯定會變得更安全,這個毋庸置疑痕貌!

但是假如配置文件里的自定義加密密鑰jasypt.encryptor.password=CodeSheep泄露了风罩,那我們的加密字段也還是有可能被別人解密,為此舵稠,有幾項工作可以讓加密變得更加安全超升。

1、使用自定義加密器

上文實驗加密時哺徊,使用的是默認(rèn)的加密規(guī)則室琢,這一點會讓當(dāng)自定義加密密鑰泄漏時可能變得不安全。為此我們可以自定義加密規(guī)則唉工。

自定義加密規(guī)則非常簡單研乒,只需要提供自定義的加密器配置類即可,比如我這里自定義一個名為 codeSheepEncryptorBean類型的加密器:

@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配置文件中來指定bean的名字,就像這樣:

jasypt.encryptor.bean=codeSheepEncryptorBean
2谣膳、加密密鑰不要寫在配置文件中

如果覺得上面這種方式還是可能會導(dǎo)致加密密鑰泄露的話(畢竟還是寫在了配置文件中)竿报,那我們干脆可以直接將加密密鑰從配置文件中拿掉,取而代之的有三種方式:

  • 方式一:直接作為程序啟動時的命令行參數(shù)來帶入
java -jar yourproject.jar --jasypt.encryptor.password=CodeSheep
  • 方式二:直接作為程序啟動時的應(yīng)用環(huán)境變量來帶入
java -Djasypt.encryptor.password=CodeSheep -jar yourproject.jar
  • 方式三:甚至可以作為系統(tǒng)環(huán)境變量的方式來帶入
    比方說继谚,我們提前設(shè)置好系統(tǒng)環(huán)境變量JASYPT_ENCRYPTOR_PASSWORD = CodeSheep烈菌,則直接在Spring Boot的項目配置文件中做如下配置即可:
jasypt.encryptor.password=${JASYPT_ENCRYPTOR_PASSWORD:}

這時候也會安全得多。噓…好了,說了這么多芽世,如果你項目的配置文件中的重要信息沒有加密的話挚赊,答應(yīng)我,二話別說济瓢,趕快全部偷偷去改掉荠割,快!速度旺矾!跑步前進(jìn)蔑鹦!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市箕宙,隨后出現(xiàn)的幾起案子嚎朽,更是在濱河造成了極大的恐慌,老刑警劉巖柬帕,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件哟忍,死亡現(xiàn)場離奇詭異,居然都是意外死亡雕崩,警方通過查閱死者的電腦和手機(jī)魁索,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來盼铁,“玉大人,你說我怎么就攤上這事尝偎∪幕穑” “怎么了?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵致扯,是天一觀的道長肤寝。 經(jīng)常有香客問我,道長抖僵,這世上最難降的妖魔是什么鲤看? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮耍群,結(jié)果婚禮上义桂,老公的妹妹穿的比我還像新娘。我一直安慰自己蹈垢,他們只是感情好慷吊,可當(dāng)我...
    茶點故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著曹抬,像睡著了一般溉瓶。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天堰酿,我揣著相機(jī)與錄音疾宏,去河邊找鬼。 笑死触创,一個胖子當(dāng)著我的面吹牛灾锯,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播嗅榕,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼顺饮,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了凌那?” 一聲冷哼從身側(cè)響起兼雄,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎帽蝶,沒想到半個月后赦肋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡励稳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年佃乘,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片驹尼。...
    茶點故事閱讀 38,100評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡趣避,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出新翎,到底是詐尸還是另有隱情程帕,我是刑警寧澤,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布地啰,位于F島的核電站愁拭,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏亏吝。R本人自食惡果不足惜岭埠,卻給世界環(huán)境...
    茶點故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蔚鸥。 院中可真熱鬧惜论,春花似錦、人聲如沸株茶。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽启盛。三九已至蹦掐,卻和暖如春技羔,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背卧抗。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工藤滥, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人社裆。 一個月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓拙绊,卻偏偏與公主長得像,于是被迫代替她去往敵國和親泳秀。 傳聞我的和親對象是個殘疾皇子标沪,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,834評論 2 345

推薦閱讀更多精彩內(nèi)容