天天看點

Nacos 配置加密功能也太雞肋了吧,還是用Jasypt 吧

當項目中用了 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: hello
    algorithm: 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()),将找到的内容進行解密,再指派解密後的值。

來源:https://mp.weixin.qq.com/s?__biz=MzAxMjA0MDk2OA==&mid

繼續閱讀