前言
對(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.prefix
和jasypt.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é)果
我們可以看到挺邀,配置被成功的解密了出來(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é)果如下:
二躁愿、非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