1.背景
現代互聯網充斥着各種攻擊、病毒、釣魚、欺詐等手段,層出不窮。對於一個公司而已最基本的財富無非是代碼和數據,“配置屬性加密”的應用場景假設如果攻擊者通過某些手段拿到部分敏感代碼或配置,甚至是全部源代碼和配置時,我們的基礎設施賬號依然不被泄漏。當然手段多種多種多樣,比如以某臺中毒的內網機器爲肉機,對其他電腦進行ARP攻擊抓去通信數據進行分析,或者獲取某個賬號直接拿到源代碼或者配置,等等諸如此類。
2.思路
採用比較安全的對稱加密算法;
對基礎設施賬號密碼等關鍵信息進行加密;
構建時、運行時傳入密鑰,在加載屬性前進行解密;
開發環境可以將密鑰放置在代碼中,測試、灰度、生產等環境放置在構建腳本或者啓動腳本中;
如果自動化部署甚至可以有專門的程序來管理這些密鑰(目前沒有,暫不考慮);
值得思考的問題?
當內網被攻破,當源碼泄漏,當zkui被攻破,當開發賬號泄漏,當運維賬號泄漏,我們如何保證生產環境的基礎設施安全,如何防範關鍵信息泄漏?
3.技術框架
Jasypt是一個優秀的加密庫,支持密碼、Digest認證、文本、對象加密,此外密碼加密複合RFC2307標準。http://www.jasypt.org/download.html
ulisesbocchio/jasypt-spring-boot,集成Spring Boot,在程序引導時對屬性進行解密。https://github.com/ulisesbocchio/jasypt-spring-boot
4.處理過程
4.1 spring boot 密碼形式
1.添加maven依賴引入jasypt
<!-- https://mvnrepository.com/artifact/com.github.ulisesbocchio/jasypt-spring-boot-starter -->
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>1.8</version>
</dependency>
2.配置加密參數
jasypt:
encryptor:
#這裏可以理解成是加解密的時候使用的密鑰
password: password
寫一個測試方法,這裏直接在單元測試裏面來實現給密碼加密,得到字符串密碼
@Autowired
StringEncryptor stringEncryptor;
@Test
public void encryptPwd() {
String result = stringEncryptor.encrypt("yourpassword");
System.out.println("==================");
System.out.println(result);
System.out.println("==================");
}
把得到的密文寫到需要使用到的地方,加密後的字符串需要放到ENC裏面,格式如下:
spring:
datasource:
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull&tinyInt1isBit=false
username: root
password: ENC(4TyrSSgQd2DCHnXVwkdKMQ==)
driver-class-name: com.mysql.jdbc.Driver
5.啓動時加載命令模式
通過命令行運行 jasypt-1.9.2.jar 包命令來加密解密:
1. 在jar包所在目錄打開命令行,運行如下加密命令:
java -cp jasypt-1.9.2.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input="root" password=security algorithm=PBEWithMD5AndDES
運行結果如下:
----ENVIRONMENT-----------------
Runtime: Oracle Corporation Java HotSpot(TM) 64-Bit Server VM 25.91-b14
----ARGUMENTS-------------------
algorithm: PBEWithMD5AndDES
input: root
password: security
----OUTPUT----------------------
i00VogiiZ1FpZR9McY7XNw==
2. 使用剛纔加密出來的結果進行解密,執行如下解密命令:
java -cp jasypt-1.9.2.jar org.jasypt.intf.cli.JasyptPBEStringDecryptionCLI input="i00VogiiZ1FpZR9McY7XNw==" password=security algorithm=PBEWithMD5AndD
運行結果如下:
----ENVIRONMENT-----------------
Runtime: Oracle Corporation Java HotSpot(TM) 64-Bit Server VM 25.91-b14
----ARGUMENTS-------------------
algorithm: PBEWithMD5AndDES
input: i00VogiiZ1FpZR9McY7XNw==
password: security
----OUTPUT----------------------
root
4.2 spring boot 密碼文件形式(這種比較流行)
0. 準備工作:
0.1 生成密碼文件
使用附件加密工具(亦可@閆妍幫忙從測試環境獲取)生成密碼文件:
a. 執行java -jar jasypt-password-tool.jar
b. 根據提示操作生成密碼文件(一級),鍵入命令genkeyfile <filepath>
如:genkeyfile E:\\password.dat
0.2 生成加密後的密碼
c. 根據提示,使用密碼文件對數據庫明文密碼加密,鍵入命令encrypt -f <plaintext> <filepath>
如:encrypt -f 12345678 E:\\password.dat
生成密文:DzANZvtzC/JrnRTz8te1s/J/Pw=
1. 應用pom.xml新增依賴:
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>1.18</version>
</dependency>
2. 配置文件新增配置(path指向加密文件):
jasypt.encryptor.password-file-path=/home/jasypt/pwd.dat
3. 配置加密密碼,如下:
hikari.datasource.write.password=ENC(DzANZvtzC/JrnRTz8te1s/J/Pw=)
4. 啓動應用,看是否能成功啓動。測試再具體測下insert、update等sql是否正常。
注:若應用啓動失敗,請檢查mybatis相關包是否衝突,如下:
<exclusion>
<artifactId>mybatis-spring</artifactId>
<groupId>org.mybatis</groupId>
</exclusion>
若有任何問題,請及時反饋,謝謝。
4.3、spring 配置
1、使用spring mvc集成,可繼承PropertyPlaceholderConfigurer子類
public class MyPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {
@Override
protected String convertProperty(String propertyName, String propertyValue) {
//針對數據庫連接密碼加密
if (propertyName.equalsIgnoreCase("spring.datasource.password")) {
propertyValue = propertyValue.replace("eszxdr", "");
}
return super.convertProperty(propertyName, propertyValue);
}
}
2、實例化自定義的PropertyPlaceholderConfigurer對象
使用xml方式配置
<bean id="propertyConfigurer" class="com.spring.boot.test.util.MyPropertPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:application.poperties</value>
</list>
</property>
</bean>
使用java配置方式
@Bean
public PropertyPlaceholderConfigurer propertyPlaceholderConfigurer(){
PropertyPlaceholderConfigurer placeholderConfigurer=new MyPropertyPlaceholderConfigurer();
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource resource = resolver.getResource("classpath:application.properties");
placeholderConfigurer.setLocation(resource);
return placeholderConfigurer;
}
3、以上方式不支持yaml文件,無法使用spring boot,因爲使用spring boot 數據庫連接會在PropertyPlaceHolderConfigurer之前初始化
參考文章:https://blog.csdn.net/clypm/article/details/79539124
參考文章:https://blog.csdn.net/u014421556/article/details/78832427#commentsedit