大家好,我是風箏,微信搜「古時的風箏」,更多干貨
當項目中用了 Nacos 做配置中心,是不是所有的配置都放到里面呢,大部分時候為了省事和統一,系統所有的配置都直接放在里面了,有時候,會包括一些賬號、密碼、秘鑰等信息。
這時候你們的項目是怎么處理的呢?
一種方式,不管它,反正 Nacos 有密碼,如果 Nacos 都被攻破了,那也沒辦法。
還有一種方式,這些涉及到密碼、秘鑰的信息放到本地環境變量中,這種方式雖然也還算方便,但是管理起來就不是很統一了。
那有沒有什么一舉兩得的方式呢?
Nacos2.0本身的插件功能
Nacos 本身提供了一種加密實現,是基于SPI的插件機制實現的。
要使用插件,需要Nacos版本是2.x版本,如果你正在使用1.x版本,需要進行升級。
引入插件包。
<dependency><groupId>com.alibaba.nacos</groupId><artifactId>nacos-aes-encryption-plugin</artifactId><version>${nacos-aes-encryption-plugin.version}</version>
</dependency>
之后如果想對配置加密,需要創建名稱為 cipher-[加密算法名稱]-dataId
這種規則的配置文件,例如cipher-aes-application-dev.yml
。
之后不管你在配置中寫上什么內容,都會被加密。
例如:
password: 123456
那在程序中讀出來的都是被加密過的,需要你調用插件提供的解密方法解密,或者自定義加解密方法。
但實話說這種方式有點粗暴了。不加密則已,一加密那就是整個配置文件啊,這好像也不太符合只有部分字段需要加密的場景。
而且你還必須得升級到2.x的版本才行,都做成插件了,還要區分版本。
而且官方文檔相當敷衍了,實在不像是誠意之作啊。
我選擇放棄這種方式。
我選擇 Jasypt
Jasypt 其實是一個專門用于加解密的庫,對于像 Nacos 配置文件、本地配置文件等配置信息的加解密就是一個順手的事兒。
加解密就不用多說了,有很多的開源包,甚至你自己寫一個工具類都是輕而易舉的事兒。
如果我們使用 Spring Boot 的話,一般讀取配置的時候用下面這種方式,不管是本地配置文件、環境變量或者Nacos都可以通用。
@Value("${aestest.appKey}")
private String appKey;
如果改成加密的配置后,上面的 appKey 讀出來的內容可能就變成了0cxddfjjgglllsff000s
這種一串看不懂的內容了。當然了,我們可以在使用這個變量的地方調用解密方法進行解密,但是這樣一來,就變得很麻煩了。
開始我還打算自己寫一個來著,后來發現 jasypt-spring-boot-starter
正好完美的實現了,直接用它就好了。
1、首先引入jasypt
專門為 Spring Boot 開發的包
<dependency><groupId>com.github.ulisesbocchio</groupId><artifactId>jasypt-spring-boot-starter</artifactId><version>3.0.5</version>
</dependency>
2、在配置文件中進行相關配置
jasypt:encryptor:password: helloalgorithm: PBEWithMD5AndDES
algorithm
是加密算法,官方默認的加密算法是 PBEWITHHMACSHA512ANDAES_256
,但是如果你用的是 JDK1.8,還用不了這個算法,JDK9以上才支持,所以可以把這個算法改成PBEWithMD5AndDES
。
password
是加解密的時候用到的密碼,這個配置是不建議放到Nacos的,可以放到環境變量中,這樣一來,就只有這一個參數放到環境變量了。
3、生成加密字符串
Jasypt 默認用 Enc(內容)
這樣的格式來表示這是加密的配置,當然你可以通過配置來修改前綴和后綴,比如改成 JASYPT[內容]
這種形式,其中內容
部分是加密后的。
加密串可以這樣生成。
引入加密類
@Autowired
private StringEncryptor encryptor;
生成加密內容
@GetMapping("/encrypt")
public String encrypt(String content) {return "ENC(" + encryptor.encrypt(content) + ")";
}
4、最后將生成的加密串保存到 Nacos 或本地配置中,例如下面這樣
aestest:appKey: ENC(GT2vTn1+SdeFu90xH/vgw3uYTNyV5PGp)
5、直接使用@Value
注解獲取就行,和不加密的用法一模一樣
@Value("${aestest.appKey}")
private String appKey;
原理
加密的原理沒啥好說的,上面用的PBEWithMD5AndDES
就是DES加密算法。
而@Value
注解直接拿到解密后的值,其實是實現了BeanFactoryPostProcessor
接口,相當于利用 Spring Boot 的加載機制做了一個filter,在filter中查找 @Value
注解,并且內容是以 Jasypt
指定的前后綴的配置項(例如ENC()
),將找到的內容進行解密,再賦值解密后的值。
更詳細的用法可在官方GitHub倉庫中查看,地址:https://github.com/ulisesbocchio/jasypt-spring-boot
不如點個贊
推薦閱讀
? 劍走偏鋒,無頭瀏覽器是什么神奇的家伙
? 新項目決定用 JDK 17了
? 5000字,10張圖,完全掌握 MySQL 事務隔離級別