Springboot項(xiàng)目中應(yīng)用jasypt進(jìn)行加解密

前言

對(duì)于大部分項(xiàng)目來(lái)說(shuō)轻绞,為了運(yùn)維方便和項(xiàng)目解耦采记,往往會(huì)將一些和代碼無(wú)關(guān)的配置抽離出來(lái),單獨(dú)放在一個(gè)配置文件中進(jìn)行維護(hù)政勃。但這類配置文件中常常含有密碼等比較敏感的信息唧龄。為了避免出現(xiàn)敏感信息泄露等問(wèn)題,采用加密等手段來(lái)增強(qiáng)項(xiàng)目的安全性是比較有必要的奸远。本篇文章將以jasypt這個(gè)應(yīng)用較為廣泛的第三方依賴來(lái)進(jìn)行講解既棺,主要基于Springboot進(jìn)行應(yīng)用。

一懒叛、基于Springboot項(xiàng)目使用jasypt進(jìn)行加解密

(一)引入依賴

jasypt對(duì)應(yīng)Springboot項(xiàng)目有著良好的支持丸冕,可以省略我們對(duì)工具類的封裝芍瑞。使用jasypt需要在項(xiàng)目中引入如下依賴:

<!-- spring-boot項(xiàng)目的依賴 -->
<dependency>
    <groupId>com.github.ulisesbocchio</groupId>
    <artifactId>jasypt-spring-boot-starter</artifactId>
    <version>3.0.3</version>
</dependency>
(二)配置jasypt響應(yīng)的加密配置

對(duì)于加密秘鑰的話,最好是不要寫在配置文件中妥凳,不然別人根據(jù)你的配置就可以輕而易舉地進(jìn)行反推答捕,敏感信息的加密程度就大大降低了拱镐。

jasypt:
  encryptor:
    #默認(rèn)加密算法:PBEWITHHMACSHA512ANDAES_256,sha512+AES算法哗咆,安全性更高晌柬,但是需要 Java JDK 1.9+
    #本服務(wù)使用jdk1.8年碘,所以使用 PBEWithMD5AndDES md5+des算法
    #默認(rèn)使用 com.ulisesbocchio.jasyptspringboot.encryptor.DefaultLazyEncryptor 進(jìn)行加解密 展鸡,PooledPBEStringEncryptor可以對(duì)其加密的內(nèi)容進(jìn)行解密
    algorithm: PBEWithMD5AndDES
    # 加密密鑰,使用方式 spring.datasource.password=ENC(密文)涤久,不要設(shè)置在配置文件中箱硕,建議使用環(huán)境變量或者啟動(dòng)參數(shù): --jasypt.encryptor.password=123456
    password: 123456
    #設(shè)置密文前綴和后綴
    property:
      prefix: ENC(
      suffix: )
    iv-generator-classname: org.jasypt.iv.RandomIvGenerator

除了上面的配置項(xiàng)之外剧罩,還有如下配置項(xiàng)可選

Key Required Default Value
jasypt.encryptor.password True -
jasypt.encryptor.algorithm False PBEWITHHMACSHA512ANDAES_256
jasypt.encryptor.key-obtention-iterations False 1000
jasypt.encryptor.pool-size False 1
jasypt.encryptor.provider-name False SunJCE
jasypt.encryptor.provider-class-name False null
jasypt.encryptor.salt-generator-classname False org.jasypt.salt.RandomSaltGenerator
jasypt.encryptor.iv-generator-classname False org.jasypt.iv.RandomIvGenerator
jasypt.encryptor.string-output-type False base64
jasypt.encryptor.proxy-property-sources False false
jasypt.encryptor.skip-property-sources False empty list
(三)在代碼中進(jìn)行測(cè)試

注意幕与,在代碼測(cè)試之前啦鸣,需要保證springboot項(xiàng)目中有正常使用@SpringBootApplication 或者@EnableAutoConfiguration注解
我們可以項(xiàng)目中使用@Value注解來(lái)直接獲取解密后的配置值

步驟一:在配置文件中新增一個(gè)加密的配置

注意来氧,需要在密文外面使用我們前面定義的前綴和后綴進(jìn)行包裹,這樣jasypt才會(huì)識(shí)別到這個(gè)配置屬于需要加密的配置中狂。我們上面配置的jasypt.property.prefixjasypt.property.suffix分別是ENC() (也是默認(rèn)的前后綴)胃榕。至于加密后的值是怎么來(lái)的,后文會(huì)介紹一個(gè)工具類苦掘。

test:
  myvalue: ENC(zRDyVMf2i8Ek8nYJKBzHv2oG3oOgPlYw)
步驟二:在代碼中使用@Value注解來(lái)獲取解密后的值
@SpringBootTest(classes = DemoApplication.class)
class DemoApplicationTests {

    @Value("${test.myvalue}")
    private String value;

    @Test
    public void utilsTest(){
       System.out.println("value:"+value);
    }
}
步驟三:運(yùn)行代碼鹤啡,觀察結(jié)果
image.png

我們可以看到挺邀,配置被成功的解密了出來(lái)端铛。當(dāng)然禾蚕,在解密之前狂丝,我們需要先對(duì)配置文件進(jìn)行加密一下才可以几颜,在springboot項(xiàng)目中,我們可以十分簡(jiǎn)單地引用一個(gè)工具類StringEncryptor來(lái)進(jìn)行加解密县习。
我們可以簡(jiǎn)單使用這個(gè)工具類來(lái)進(jìn)行一些測(cè)試:

@Component
public class EncryptorBootUtils {
    @Autowired
    private StringEncryptor stringEncryptor;

    public void testEncryptor(String msg) {
        System.out.println("原始的信息為"+ msg);
        // 下面的方法是加密
        String encryptStr = stringEncryptor.encrypt(msg);
        System.out.println("加密后的信息為"+encryptStr);
        // 下面的方法是解密
        String decrypt = stringEncryptor.decrypt("解密后的信息為"+encryptStr);
        System.out.println(decrypt);
    }

}

@SpringBootTest(classes = DemoApplication.class)
class DemoApplicationTests {

    @Autowired
    private EncryptorBootUtils bootUtils;

    @Test
    public void utilsTest(){
       //System.out.println("value:"+value);
        bootUtils.testEncryptor("AABBCCD");
    }

}

工具類測(cè)試結(jié)果如下:
image.png

二躁愿、非Springboot項(xiàng)目使用jasypt進(jìn)行加解密

(一)引入依賴

需要注意的是彤钟,非Springboot項(xiàng)目使用jasypt依賴和Springboot項(xiàng)目的不同逸雹。

<dependency>
    <groupId>org.jasypt</groupId>
    <artifactId>jasypt</artifactId>
    <version>1.9.3</version>
 </dependency>
(二)定義一個(gè)加解密的工具類

項(xiàng)目中可能有很多地方需要用到加解密,所以我們最好把它封裝成一個(gè)工具類:

public class JasyptUtils {
    /**
     * 通過(guò)秘鑰和字符串剧防,獲取加密后的字符串
     * @param secretKey
     * @param message
     * @return
     */
    public static String encrypt(String secretKey,String message){
        return stringEncryptor(secretKey,message,true);
    }

    /**
     * 通過(guò)秘鑰和字符串峭拘,獲取加密后的字符串
     * @param secretKey
     * @param message
     * @return
     */
    public static String decrypt(String secretKey,String message){
        return stringEncryptor(secretKey,message,false);
    }
    /**
     * {@link EncryptorBootUtils} 加解密鸡挠。
     * 同一個(gè)密鑰(secretKey)對(duì)同一個(gè)內(nèi)容執(zhí)行加密搬男,生成的密文都是不一樣的缔逛,但是根據(jù)根據(jù)這些密文解密成明文都是可以.
     * 1、Jasypt 默認(rèn)使用 {@link EncryptorBootUtils} 來(lái)解密全局配置文件中的屬性按脚,所以提供密文時(shí)辅搬,也需要提供 {@link EncryptorBootUtils} 加密的密文
     * 2脖旱、{@link EncryptorBootUtils} 接口有很多的實(shí)現(xiàn)類萌庆,比如常用的 {@link PooledPBEStringEncryptor}
     * 3践险、setConfig(final PBEConfig config):為對(duì)象設(shè)置 {@link PBEConfig} 配置對(duì)象
     * 4、encrypt(final String message):加密內(nèi)容
     * 5于游、decrypt(final String encryptedMessage):解密內(nèi)容
     *
     * @param secretKey :密鑰贰剥。加/解密必須使用同一個(gè)密鑰
     * @param message   :加/解密的內(nèi)容
     * @param isEncrypt :true 表示加密筷频、false 表示解密
     * @return
     */
    private static String stringEncryptor(String secretKey, String message, boolean isEncrypt) {
        PooledPBEStringEncryptor pooledPBEStringEncryptor = new PooledPBEStringEncryptor();
        pooledPBEStringEncryptor.setConfig(getSimpleStringPBEConfig(secretKey));
        String result = isEncrypt ? pooledPBEStringEncryptor.encrypt(message) : pooledPBEStringEncryptor.decrypt(message);
        return result;
    }

    /**
     * 設(shè)置 {@link PBEConfig} 配置對(duì)象,SimpleStringPBEConfig 是它的實(shí)現(xiàn)類
     * 1芹缔、所有的配置項(xiàng)建議與全局配置文件中的配置項(xiàng)保持一致,特別是 password最欠、algorithm 等等選項(xiàng)惩猫,如果不一致轧房,則應(yīng)用啟動(dòng)時(shí)解密失敗而報(bào)錯(cuò).
     * 2、setPassword(final String password):設(shè)置加密密鑰迟赃,必須與全局配置文件中配置的保存一致纤壁,否則應(yīng)用啟動(dòng)時(shí)會(huì)解密失敗而報(bào)錯(cuò).
     * 3剪撬、setPoolSize(final String poolSize):設(shè)置要?jiǎng)?chuàng)建的加密程序池的大小.
     * 4残黑、setAlgorithm(final String algorithm): 設(shè)置加密算法的值梨水, 此算法必須由 JCE 提供程序支持
     * 5疫诽、setKeyObtentionIterations: 設(shè)置應(yīng)用于獲取加密密鑰的哈希迭代次數(shù)奇徒。
     * 6摩钙、setProviderName(final String providerName):設(shè)置要請(qǐng)求加密算法的安全提供程序的名稱
     * 7查辩、setSaltGeneratorClassName:設(shè)置 Sal 發(fā)生器
     * 8、setIvGeneratorClassName:設(shè)置 IV 發(fā)生器
     * 9长踊、setStringOutputType:設(shè)置字符串輸出的編碼形式身弊。可用的編碼類型有 base64阱佛、hexadecimal
     *
     * @param secretKey
     * @return
     */
    private static SimpleStringPBEConfig getSimpleStringPBEConfig(String secretKey) {
        SimpleStringPBEConfig config = new SimpleStringPBEConfig();
        config.setPassword(secretKey);
        config.setAlgorithm("PBEWithMD5AndDES");
        //以下都是默認(rèn)值
        config.setPoolSize("1");
        config.setKeyObtentionIterations("1000");
        config.setProviderName("SunJCE");
        config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
        //命令行執(zhí)行時(shí)要指定這個(gè)參數(shù)
        config.setIvGeneratorClassName("org.jasypt.iv.NoIvGenerator");
        config.setStringOutputType("base64");
        return config;
    }

}

當(dāng)我們需要使用時(shí)涨冀,只需要傳入秘鑰麦萤,調(diào)用工具類中對(duì)應(yīng)加解密方法即可壮莹。

本篇文章到此就介紹完了,希望可以讓各位讀者快速入門命满。需要注意的是胶台,jasypt這個(gè)第三方組件內(nèi)還包含著相當(dāng)豐富的功能(諸如插件、命令行加解密)韩脏,有興趣想要更深入了解的話赡矢,可以訪問(wèn)jasypt的GitHub官方網(wǎng)址:https://github.com/ulisesbocchio/jasypt-spring-boot

參考文章:
SpringBoot配置文件屬性加密:http://www.reibang.com/p/7eed4e4fb3ba

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末吹散,一起剝皮案震驚了整個(gè)濱河市空民,隨后出現(xiàn)的幾起案子丘跌,更是在濱河造成了極大的恐慌,老刑警劉巖荒澡,帶你破解...
    沈念sama閱讀 221,430評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件与殃,死亡現(xiàn)場(chǎng)離奇詭異单山,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)幅疼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,406評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門米奸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人爽篷,你說(shuō)我怎么就攤上這事悴晰。” “怎么了逐工?”我有些...
    開(kāi)封第一講書人閱讀 167,834評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵铡溪,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我泪喊,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 59,543評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘膳犹。我一直安慰自己豺旬,他們只是感情好族阅,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,547評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布沐寺。 她就那樣靜靜地躺著钢坦,像睡著了一般蚊俺。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 52,196評(píng)論 1 308
  • 那天疫粥,我揣著相機(jī)與錄音,去河邊找鬼慷彤。 笑死,一個(gè)胖子當(dāng)著我的面吹牛涕癣,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,776評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼明肮,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼陷猫!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,671評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤狠毯,失蹤者是張志新(化名)和其女友劉穎锰扶,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體颜及,經(jīng)...
    沈念sama閱讀 46,221評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡肄扎,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,303評(píng)論 3 340
  • 正文 我和宋清朗相戀三年衡载,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了藤乙。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片而姐。...
    茶點(diǎn)故事閱讀 40,444評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡万搔,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情胖缤,我是刑警寧澤,帶...
    沈念sama閱讀 36,134評(píng)論 5 350
  • 正文 年R本政府宣布剧劝,位于F島的核電站抓歼,受9級(jí)特大地震影響蹋半,放射性物質(zhì)發(fā)生泄漏减江。R本人自食惡果不足惜份企,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,810評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望唠雕。 院中可真熱鬧阎毅,春花似錦捡絮、人聲如沸熬芜。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,285評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)涎拉。三九已至,卻和暖如春灵寺,著一層夾襖步出監(jiān)牢的瞬間曼库,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,399評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工略板, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留毁枯,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,837評(píng)論 3 376
  • 正文 我出身青樓叮称,卻偏偏與公主長(zhǎng)得像种玛,于是被迫代替她去往敵國(guó)和親藐鹤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,455評(píng)論 2 359

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