## 關於Jasypt 就是java套件,用於當專案布置時,可以把配置文件中的敏感資訊替換成密文,啟動專案時帶入密鑰才能正常解密運行,避免敏感資訊明文顯示,這裡只有簡單使用,然後最好一開始配置就帶入jasypt,不然只要上版控(Git)就還要把舊的紀錄清除,很麻煩 ## 使用方式 整體流程是: -> 先手動把需要加密的明文手動經過加密(帳號、密碼...) -> 放上配置文件用ENC(密文)的方式寫<font style='color:red;'>※</font>  -> 專案啟動類加上@EnableEncryptableProperties才會自動解密  -> 啟動專案時帶上加密的密鑰 範例為springboot + maven 先加依賴 ```java= <dependency> <groupId>com.github.ulisesbocchio</groupId> <artifactId>jasypt-spring-boot-starter</artifactId> //(這邊主要是用3以後,3以前差異好像蠻大我也不了解) <version>3.0.4</version> </dependency> ``` 這邊加密是直接寫在測試類(JUnit5),運行時也可以順便測試加解密正常 ```java= import org.jasypt.encryption.pbe.StandardPBEStringEncryptor; import org.jasypt.iv.RandomIvGenerator; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; public class JasyptEncodeTest { @Test @DisplayName("測試Jasypt加密解密") void jasyptEncodeDecode() { StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor(); //jasypt解密時默認是用RandomIvGenerator做向量,但這邊預設是null所以要指定 encryptor.setIvGenerator(new RandomIvGenerator()); encryptor.setPassword("testEncode"); // 加密密鑰 String originUrl = "testUrl"; String originUsername = "testUsername"; String originPassword = "testPassword"; String dbUrl = encryptor.encrypt(originUrl); String dbUsername = encryptor.encrypt(originUsername); String dbPassword = encryptor.encrypt(originPassword); System.out.println("加密----------------------------------------"); System.out.println("Encrypted text: [" + dbUrl + "]"); System.out.println("Username text: [" + dbUsername + "]"); System.out.println("Password text: [" + dbPassword + "]"); System.out.println("-------------------------------------------"); Assertions.assertEquals(originUrl, encryptor.decrypt(dbUrl)); Assertions.assertEquals(originUsername, encryptor.decrypt(dbUsername)); Assertions.assertEquals(originPassword, encryptor.decrypt(dbPassword)); } } ``` 比較要注意的是encryptor.setIvGenerator(new RandomIvGenerator()); 這部分一定要做設置,因為加密時和解密時的默認方式不一樣,很奇怪,我也這樣覺得 運行成功之後把輸出的密文寫到配置類上並且寫成ENC(密文)<font style='color:red;'>※</font>  然後這邊還需要加一個配置就是 ```java= //jasypt3以上會以PBEWITHHMACSHA512ANDAES_256為默認算法,和加密時StandardPBEStringEncryptor默認的PBEWithMD5AndDES算法不同,所以這邊要指定 jasypt.encryptor.algorithm=PBEWithMD5AndDES ``` 之後就是專案啟動時設置密鑰,專案就會自動解密配置ENC()包裹的密文 簡單啟動的話就是 ``` //mvn打包 mvn clean install //啟動時帶入密鑰 java "-Djasypt.encryptor.password=密鑰" -jar XXX.jar ``` 或是可以使用環境變數的方式寫密鑰,這邊就不提 ## 錯誤原因 主要會發生的其實就幾個問題 1. 沒有帶入密鑰  2. 解密錯誤   自己排查可能原因就幾個 如果確認加密解密的密鑰相同,就繼續往下看  ▲這是什麼配置都不做時,專案啟動默認<font style='color:red;'>解密</font>方式  ▲然後這是<font style='color:red;'>加密</font>類默認加密方式 除了單純密鑰錯誤的問題外,會導致差異的屬性主要就是algorithm(算法)和ivGeneratorSet(向量), 看看ChatGpt的說明  所以現在要做的就是<font style='color:red;'>同步加密解密方式</font> 1. 設定成相同加密算法 2. 設定相同的向量算法 我的作法就是加密時設定向量成解密默認方式RandomIvGenerator(浮動向量) 也可以把解密配置設定成NoIvGenerator(不加向量) 然後後解密的算法設置成加密類的默認算法PBEWithMD5AndDES 或是也可以更改加密算法,總而言之就是<font style='color:red;'>必須同步兩邊</font> ## 清除Git紀錄 當今天不小心把加密前的明文推上版控,後續就算用jasypt加密蓋過去還是可以從commit紀錄看到舊的明文,所以勢必得要清除紀錄才能保證安全性 這邊就要用到<font style='color:red;'>Git filter-repo</font> [當然還是有其他清除的方式啦](https://ithelp.ithome.com.tw/m/articles/10279857), 但我就沒試過了 ### Git filter-repo 是官方推薦用於修改commit的插件,得另外安裝 安裝方式有兩種 1. 透過python pip安裝 2. 官方Git下載 這邊不多講,詳細直接看官方[Github](https://github.com/newren/git-filter-repo) 相關安裝都完成後 <font style='color:red;'>先把要處理的檔案做備份</font>(要整個檔案備份) 先說明後續流程 1. 下指令刪除本地commit紀錄(也會刪除指定本地檔案, 所以上面才說要先做備份) 2. 本地的所有commit都要重新push到遠端repository覆蓋掉所有舊的紀錄 (就可以刪去所有帶有敏感資訊的檔案紀錄) 3. 本地,把剛剛被移除的<font style='color:red;'>備份檔案</font>更改成加密後的版本, 重新下commit,當成全新的檔案push到遠端repository 4. 這樣就可以更新成功,清除之前推送過的敏感資訊 --- <font style='color:red;'>※</font>有一個問題要特別注意,就是切換分支的問題,假設我有<font style='color:red;'>主分支A</font>,<font style='color:red;'>A</font>下了一個<font style='color:red;'>commit#123</font>,之後從<font style='color:red;'>A切出了branch B</font>,今天如果==git filter-repo==去修改<font style='color:red;'>B的#123</font>,==git push --force==推上遠端repository後,會導致<font style='color:red;'>A的#123</font>紀錄也被同步更改,<font style='color:red;'>因為git是用commit的hash去追蹤,只要推送紀錄是相同的commit就算切分支,該紀錄被刪除還是會同步連動</font> --- 接下來開始下指令 1. 檢查git filter-repo有沒有安裝成功 ``` git filter-repo --version ``` 2. sensitive-file為指定要刪除包含敏感資訊的檔案,要指定對的路徑, ex:src/main/java/resource/sensitiveFile.properties ``` git filter-repo --path <sensitive-file> --invert-paths //如果有多個要刪除的檔案, 重複多個--path git filter-repo --path <sensitive-file1> --path <sensitive-file2> --invert-paths ``` 3. 推送本地[localBranchName]分支commit覆蓋遠端[repositoryName]的分支 ``` git push --force [repositoryName] [localBranchName] ``` 4. 剩下就是更改新檔案,然後正常下commit,正常push
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up