1. 程式人生 > >【Springboot】Springboot整合Jasypt,讓配置資訊保安最優雅方便的方式

【Springboot】Springboot整合Jasypt,讓配置資訊保安最優雅方便的方式

1 簡介

在上一篇文章中,介紹了Jasypt及其用法,具體細節可以檢視【Java庫】如何使用優秀的加密庫Jasypt來保護你的敏感資訊?。如此利器,用之得當,那將事半功倍。本文將介紹Springboot整合Jasypt,實現配置資訊的安全,如資料庫連線、賬號和密碼、介面憑證資訊等。

Jasypt可以為Springboot加密的資訊很多,主要有:

  • System Property 系統變數
  • Envirnment Property 環境變數
  • Command Line argument 命令列引數
  • Application.properties 應用配置檔案
  • Yaml properties 應用配置檔案
  • other custom property sources 其它配置檔案

經測試,Springboot 2.1.9版本與jasypt-spring-boot最新版本的3.0.0和2.1.2均有問題,本文使用2.1.1成功。

2 如何加入依賴

Jasypt整合到Springboot是另一個開源專案jasypt-spring-boot,主要有三種整合方式:

2.1 jasypt-spring-boot-starter

如果專案使用@SpringBootApplication@EnableAutoConfiguration註解,在pom中加入以下依賴即可對整個Spring的環境的配置資訊進行加密解密。

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

2.2 jasypt-spring-boot

如果專案不使用@SpringBootApplication@EnableAutoConfiguration註解,我們就使用下面的依賴,然後在配置Java類中加上註解@EnableEncryptableProperties

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

配置類如下:

@Configuration
@EnableEncryptableProperties
public class MyApplication {
 
}

2.3 只對特定配置加密解密

如果不想使用以上兩種方式對所有配置資訊都進行加密解密的話,可以使用註解@EncryptablePropertySource指定配置檔案,依賴如下:

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

配置類如下:

@Configuration
@EncryptablePropertySource(name = "EncryptedProperties", value = "classpath:encrypted.properties")
public class MyApplication {
    
}

3 生成加密字元

生成加密字元有多種方式,在實踐中使用過以下幾種方式。

3.1 Java命令列

Jasypt提供了一個類專門用於加密解密,提供了main方法,呼叫如下:

java -cp ./jasypt-1.9.3.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI password=pkslow algorithm=PBEWithMD5AndTripleDES input=larry

輸出為:

----ENVIRONMENT-----------------
Runtime: Oracle Corporation Java HotSpot(TM) 64-Bit Server VM 25.212-b10 

----ARGUMENTS-------------------
input: larry
algorithm: PBEWithMD5AndTripleDES
password: pkslow

----OUTPUT----------------------
SUfiOs8MvmAUjg+oWl/6dQ==

3.2 指令碼命令

Jasypt為我們提供了指令碼,可以直接用於加密解密,從http://www.jasypt.org/download.html可以下載。下載解壓後的檔案有:

# 解壓後文件
LICENSE.txt NOTICE.txt  README.txt  apidocs     bin         lib
# bin資料夾的檔案
decrypt.bat    decrypt.sh
digest.bat    digest.sh
encrypt.bat    encrypt.sh
listAlgorithms.bat listAlgorithms.sh

在bin目錄下面,我們可以根據自己的系統選擇使用什麼指令碼來生成密文,使用引數與Java命令一樣。其實這些指令碼就是封裝了一個呼叫Java類的工具。使用如下:

$ sh encrypt.sh password=pkslow algorithm=PBEWithMD5AndTripleDES input=larry

----ENVIRONMENT-----------------
Runtime: Oracle Corporation Java HotSpot(TM) 64-Bit Server VM 25.212-b10 

----ARGUMENTS-------------------
input: larry
algorithm: PBEWithMD5AndTripleDES
password: pkslow

----OUTPUT----------------------
xRvdeEnk7zgKtX5uVGCIug==

3.3 Java程式碼

既然是Java的庫,那肯定能用Java程式碼來加密解密了。具體細節可以參考【Java庫】如何使用優秀的加密庫Jasypt來保護你的敏感資訊?。

4 配置密文與其它項

4.1 配置密文

生成密文後,就要把密文配置在相應的位置,如下:

username: ENC(SUfiOs8MvmAUjg+oWl/6dQ==)

jasypt:
  encryptor:
    password: pkslow
    algorithm: PBEWithMD5AndTripleDES

配置密文的預設格式:ENC(密文),這個格式可以通過jasypt.encryptor.property.prefixjasypt.encryptor.property.suffix配置,這裡不再演示。

4.2 其它配置項

配置資訊只有 jasypt.encryptor.password 是必須的,配置項有:

配置項 必須 Default Value
jasypt.encryptor.password True -
jasypt.encryptor.algorithm False PBEWITHHMACSHA512ANDAES_256
jasypt.encryptor.keyObtentionIterations False 1000
jasypt.encryptor.poolSize False 1
jasypt.encryptor.providerName False SunJCE
jasypt.encryptor.providerClassName False null
jasypt.encryptor.saltGeneratorClassname False org.jasypt.salt.RandomSaltGenerator
jasypt.encryptor.ivGeneratorClassname False org.jasypt.iv.RandomIvGenerator
jasypt.encryptor.stringOutputType False base64
jasypt.encryptor.proxyPropertySources False false

5 如何安放你的金鑰

金鑰是非常重要的資訊,放在什麼地方,決定著你的密文是否真的安全。可以有以下幾類方式:

(1)放在application.properties

這樣能獲得配置檔案的人就能知道金鑰,不夠安全。但它是一種方便簡單的方式。存在密文和金鑰放在同一個配置檔案的風險。

(2)JVM引數

在啟動Java程式時加引數:-Djasypt.encryptor.password=pkslow,這樣就不會把金鑰放在程式碼中去了。

(3)伺服器的環境變數

把金鑰放在linux系統的環境變數中去,只有能拿到伺服器訪問許可權的人,才有可能知道金鑰在哪。例如:

# 配置profile檔案
export JASYPT_PASSWORD = pkslow

# 生效 
source /etc/profile

# 執行java程式時
java -jar -Djasypt.encryptor.password=${JASYPT_PASSWORD} xxx.jar

(4)使用自定義的Encryptor來存放

以上我們都使用了官方提供的Encryptor,其實我們是可以自定義的,如下:

@Bean("jasyptStringEncryptor")
public StringEncryptor stringEncryptor() {
  PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
  SimpleStringPBEConfig config = new SimpleStringPBEConfig();
  config.setPassword("password");
  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;
}

把金鑰寫在程式碼裡,只有能獲得jar包並反編譯的人,才能獲得密文。

如果我們把金鑰的一部分寫在程式碼裡,另一部分通過外部方式來配置,這樣就會更加安全。

6 結果測試

我們已經完成了密文的生成,現在我們測試一下是否能正常解密,測試程式碼如下:

@RestController
@RequestMapping("/jasypt")
public class JasyptController {
    @Value("${username}")
    private String username;

    @GetMapping("/name")
    public Mono<String> sendNormalText() {
        return Mono.just(username);
    }
}

訪問該介面,能返回加密前的字串,整個流程測試成功:

7 總結

本文簡介了Springboot整合Jasypt實現配置資訊的安全化,在實際專案中應用還是很多的。

另外,如果專案中是採用Spring Cloud Config的,它提供了統一的加解密方式,也方便使用。但如果應用配置沒有走配置中心,還是應該使用Jasypt。


歡迎關注公眾號<南瓜慢說>,將持續為你更新...

歡迎加博主微信,做一個點贊之友,哈哈...

多讀書,多分享;多寫作,多整理