maven项目密码md5加密_加密Spring Boot中的application.properties
1 概述
什么?都2020年了還在Spring Boot的配置文件中寫明文密碼?
(雖然是小項目,明文也沒人看.)
(明文簡單快捷方便啊!!! )
(你看直接用戶名root密碼123456多么簡單!!!)
...
不廢話了,這篇文章主要講了如何使用jasypt-spring-boot這個開源組件來進行配置文件的加密,包括簡單加密以及非對稱加密,同時也介紹了使用jar/war部署時如何輸入加密口令.
2 簡單加密
jasypt簡單加密就是直接把加密口令寫死在文件中.(好吧這樣就差不多大概跟沒加密一樣... )
2.1 依賴
目前最新版本為3.0.2,具體請查看官方github(戳這里).
<dependency><groupId>com.github.ulisesbocchio</groupId><artifactId>jasypt-spring-boot-starter</artifactId><version>3.0.2</version>
</dependency>2.2 加密口令
在application.properties中加上:
jasypt.encryptor.password=xxxxxx為對稱加密的口令. 默認使用PBE算法進行加密,PBE其實并沒有包含真正的加密與解密算法,而是將已有的消息摘要算法(如MD5,SHA等)與對稱加密算法(如AES,DES,RC2等)進行了組合,默認組合的是HCMA消息認證算法,SHA512消息摘要算法以及AES256對稱加密算法.PBE使用口令與隨機生成的鹽去生成對應(yīng)的對稱加密密鑰,再用密鑰去進行對稱加密.
2.3 輸出密文
這里在配置文件中加一個測試字段password與密鑰test進行測試:
這里為了方便就在run里面測試:
@SpringBootApplication
@EnableEncryptableProperties
public class DemoApplication implements CommandLineRunner {private static final Logger l = LoggerFactory.getLogger(DemoApplication.class);@Autowiredprivate StringEncryptor stringEncryptor;@Autowiredprivate ApplicationContext applicationContext;public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}@Overridepublic void run(String... args) throws Exception {Environment environment = applicationContext.getEnvironment();l.info(stringEncryptor.encrypt(environment.getProperty("password")));}
}注意使用@Autowired進行StringEncryptor的自動裝配時,官方文檔說加上
@Configuration
@EnableEncryptableProperties由于
@SpringBootApplication包含了
@Configuration因此這里只需要后一個. 運行后獲取密文輸出:
2.4 替換配置文件
把上面的密文替換到原配置文件,加上前綴ENC(與后綴):
這樣就加密成功了,直接獲取屬性可以看到明文:
3 自定義加密
當然,上面的簡單加密不能滿足實際使用需求,因此,這里需要進行自定義加密.
3.1 自定義加密前后綴
需要使用一個前后綴區(qū)分需要加密與不需加密的字段,默認前綴為
ENC(后綴為:
)因此加密時需要加上ENC(與). 自定義前后綴指定兩個屬性就可以了:
密碼字段需要對應(yīng)修改.
3.2 口令參數(shù)化
其實就是在啟動的時候加上命令行參數(shù)或者應(yīng)用環(huán)境變量,或者通過系統(tǒng)環(huán)境變量讀取口令,詳細使用方式請看第4點部署. 命令行參數(shù):
java -jar xxx.jar --jasypt.encryptor.password=xxx應(yīng)用環(huán)境變量:
java -Djasypt.encryptor.password=xxx -jar xxx.jar系統(tǒng)環(huán)境變量:
jasypt.encryptor.password=${TEST}前提是已經(jīng)設(shè)置好對應(yīng)系統(tǒng)變量.
3.3 自定義加密類
可以實現(xiàn)StringEncryptor接口,重寫里面的encrypt與decrypt方法,再定義一個加密配置類,指定加密類的名字:
@Configuration
@EnableEncryptableProperties
public class MyEncryptorConfiguration {@Bean("MyEncryptor")public StringEncryptor getStringEncryptor(){return new StringEncryptor() {@Overridepublic String encrypt(String s) {return "111";}@Overridepublic String decrypt(String s) {return "222";}};}
}這里是一個很簡單的例子,加密直接返回111,解密直接返回222,具體加解密算法直接替換函數(shù)體即可. 注意需要在配置文件中寫上Bean的名字:
jasypt.encryptor.bean=codeSheepEncryptorBean使用構(gòu)造函數(shù)注入(Autowired也可以):
private final StringEncryptor stringEncryptor;
public DemoApplication(MyEncryptorConfiguration encryptorConfiguration)
{stringEncryptor = encryptorConfiguration.getStringEncryptor();
}測試:
@Override
public void run(String... args) throws Exception {Environment environment = applicationContext.getEnvironment();l.info(stringEncryptor.encrypt(environment.getProperty("password")));l.info(stringEncryptor.decrypt(environment.getProperty("password")));
}4 部署
4.1 jar部署
4.1.1 命令行參數(shù)方式
這種方式的話先把配置文件中的jasypt.encryptor.password去掉,然后修改在Spring Boot的運行配置,進行本地測試:
打包時,如果測試的話需要設(shè)置Maven的參數(shù),不測試的話直接勾選Skip Tests:
打包后(右側(cè)Maven->package)加上參數(shù)運行就可以了:
4.1.2 應(yīng)用環(huán)境變量方式
其實和第一種方式差不多,也是把jasypt.encryptor.password去掉,在VM options中設(shè)置參數(shù),Spring Boot運行配置如下:
Maven設(shè)置(當然也可以跳過測試):
不過遺憾的是筆者測試失敗了:
~~沒理由啊,那為什么Spring Boot那里就這樣設(shè)置就可以....~~ (有大佬知道為什么會失敗的話可以留言,感激不盡.) 這里就直接跳過測試了.
然后就可以愉快地運行了(筆者的win下需要加兩個單引號):
4.1.3 系統(tǒng)環(huán)境變量方式
設(shè)置環(huán)境變量這個應(yīng)該不用怎么說了,直接去設(shè)置就行,然后修改一下jasypt.encryptor.password,兩個花括號中間是對應(yīng)的環(huán)境變量名:
Spring Boot運行配置:
Maven:
這次Maven測試就沒問題了. ~~真是奇了怪了.~~ 運行(還是這個舒服,直接-jar):
4.2 war部署
4.2.1 jar-war轉(zhuǎn)換
原來的是jar打包,換成war時,需要修改pom.xml中的<packaging>為war,同時加上tomcat依賴:
<packaging>war</packaging>
...
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId><scope>provided</scope>
</dependency>再添加一個ServletInitializer:
public class ServletInitializer extends SpringBootServletInitializer {@Overrideprotected SpringApplicationBuilder configure(SpringApplicationBuilder builder){return builder.sources(DemoApplication.class);}
}其中DemoApplication為main函數(shù)所在的類. war轉(zhuǎn)為jar時進行對應(yīng)的相反操作就可以了.
4.2.2 命令行參數(shù)方式
Maven設(shè)置就不說了,像上面一樣,打包之后... 筆者找不到設(shè)置Tomcat命令行參數(shù)的方式,所以,就跳過這個了... (歡迎大佬找到的留言補充,感激不盡!!!) ~~筆者太菜了,害.~~
4.2.3 應(yīng)用環(huán)境變量方式
win下可以直接修改catalina.bat或者進入tomcat9w.exe(tomcat9,tomcat8是tomcat8w.exe)進行圖形化修改,這里選擇修改catalina.bat的方式,找到setlocal,后面加上
set "JAVA_OPTS=-Djasypt.encryptor.password=test"然后把war放到webapps下就可以了.
4.2.4 環(huán)境變量方式
這種方式最簡單,設(shè)置好了環(huán)境變量,修改配置文件:
直接war打包部署就行.
5 非對稱加密
Spring Boot2.2.1之后支持非對稱加密,密鑰對的格式可以為PEM/DER.
5.1 加密
這里使用的一位大佬的RSA自定義位數(shù)加密工具類(戳這里),無需額外依賴,僅自帶JDK實現(xiàn)(JDK8+).
import java.util.Base64;
import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
/*** Java RSA 加密工具類* 參考: https://blog.csdn.net/qy20115549/article/details/83105736*/
public class Test {/*** 密鑰長度 于原文長度對應(yīng) 以及越長速度越慢*/private final static int KEY_SIZE = 2048;/*** 用于封裝隨機產(chǎn)生的公鑰與私鑰*/private static Map<Integer, String> keyMap = new HashMap<Integer, String>();/*** 隨機生成密鑰對*/public static void genKeyPair() throws NoSuchAlgorithmException {// KeyPairGenerator類用于生成公鑰和私鑰對,基于RSA算法生成對象KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");// 初始化密鑰對生成器keyPairGen.initialize(KEY_SIZE, new SecureRandom());// 生成一個密鑰對,保存在keyPair中KeyPair keyPair = keyPairGen.generateKeyPair();// 得到私鑰RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();// 得到公鑰RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();String publicKeyString = Base64.getEncoder().encodeToString(publicKey.getEncoded());// 得到私鑰字符串String privateKeyString = Base64.getEncoder().encodeToString(privateKey.getEncoded());// 將公鑰和私鑰保存到Map//0表示公鑰keyMap.put(0, publicKeyString);//1表示私鑰keyMap.put(1, privateKeyString);}/*** RSA公鑰加密** @param str 加密字符串* @param publicKey 公鑰* @return 密文* @throws Exception 加密過程中的異常信息*/public static String encrypt(String str, String publicKey) throws Exception {//base64編碼的公鑰byte[] decoded = Base64.getDecoder().decode(publicKey);RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));//RSA加密Cipher cipher = Cipher.getInstance("RSA");cipher.init(Cipher.ENCRYPT_MODE, pubKey);String outStr = Base64.getEncoder().encodeToString(cipher.doFinal(str.getBytes("UTF-8")));return outStr;}/*** RSA私鑰解密** @param str 加密字符串* @param privateKey 私鑰* @return 明文* @throws Exception 解密過程中的異常信息*/public static String decrypt(String str, String privateKey) throws Exception {//64位解碼加密后的字符串byte[] inputByte = Base64.getDecoder().decode(str);//base64編碼的私鑰byte[] decoded = Base64.getDecoder().decode(privateKey);RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));//RSA解密Cipher cipher = Cipher.getInstance("RSA");cipher.init(Cipher.DECRYPT_MODE, priKey);String outStr = new String(cipher.doFinal(inputByte));return outStr;}public static void main(String[] args) throws Exception {long temp = System.currentTimeMillis();//生成公鑰和私鑰genKeyPair();//加密字符串System.out.println("公鑰:" + keyMap.get(0));System.out.println("私鑰:" + keyMap.get(1));System.out.println("生成密鑰消耗時間:" + (System.currentTimeMillis() - temp) / 1000.0 + "秒");// String message = "RSA測試ABCD~!@#$";String message = "test";System.out.println("原文:" + message);temp = System.currentTimeMillis();String messageEn = encrypt(message, keyMap.get(0));System.out.println("密文:" + messageEn);System.out.println("加密消耗時間:" + (System.currentTimeMillis() - temp) / 1000.0 + "秒");temp = System.currentTimeMillis();String messageDe = decrypt(messageEn, keyMap.get(1));System.out.println("解密:" + messageDe);System.out.println("解密消耗時間:" + (System.currentTimeMillis() - temp) / 1000.0 + "秒");}
}5.2 修改配置文件
把明文輸入,得到密文與私鑰后,替換原來的配置文件:
密文復(fù)制到對應(yīng)加密字段,加上前后綴,同時私鑰格式選擇der,把私鑰復(fù)制過去:
運行測試沒問題就可以了.
總結(jié)
以上是生活随笔為你收集整理的maven项目密码md5加密_加密Spring Boot中的application.properties的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 顶着锅盖弱弱问一句,如果爱五曾小贤换人演
- 下一篇: 骄字开头的成语有哪些啊?