<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          輕松實(shí)現(xiàn)MySQL數(shù)據(jù)庫加密-阿里巴巴Druid

          共 6861字,需瀏覽 14分鐘

           ·

          2021-06-05 14:31

          作者 | 王磊

          來源 | Java中文社群(ID:javacn666)

          轉(zhuǎn)載請聯(lián)系授權(quán)(微信ID:GG_Stone)

          為什么要加密?

          現(xiàn)在的開發(fā)習(xí)慣,無論是公司的項(xiàng)目還是個人的項(xiàng)目,都會選擇將源碼上傳到 Git 服務(wù)器(GitHub、Gitee 或是自建服務(wù)器),但只要將源碼提交到公網(wǎng)服務(wù)器就會存在源碼泄漏的風(fēng)險(xiǎn),而數(shù)據(jù)庫配置信息作為源碼的一部分,一旦出現(xiàn)源碼泄漏,那么數(shù)據(jù)庫中的所有數(shù)據(jù)都會公之于眾,其產(chǎn)生的不良后果無法預(yù)期(比如某某酒店的信息)。

          于是為了避免這種問題的產(chǎn)生,我們至少要對數(shù)據(jù)庫的密碼進(jìn)行加密操作,這樣即使得到了源碼,也不會造成數(shù)據(jù)的泄露,也算保住了最后一塊遮羞布。

          如何加密?

          對于 Java 項(xiàng)目來說,要想快速實(shí)現(xiàn)數(shù)據(jù)庫的加密,最簡單可行的方案就是使用阿里巴巴提供的 Druid 來實(shí)現(xiàn)加密

          什么是Druid?

          Druid(中文譯為“德魯伊”)是阿里巴巴開源的一款 Java 語言中最好的數(shù)據(jù)庫連接池。Druid 提供了強(qiáng)大的監(jiān)控和擴(kuò)展功能,當(dāng)然也包含了數(shù)據(jù)庫的加密功能。

          Druid 開源地址:https://github.com/alibaba/druid/

          Druid可以做什么?

          1. Druid 可以監(jiān)控?cái)?shù)據(jù)庫訪問性能,Druid 內(nèi)置提供了一個功能強(qiáng)大的 StatFilter 插件,能夠詳細(xì)統(tǒng)計(jì) SQL 的執(zhí)行性能,這對于線上分析數(shù)據(jù)庫訪問性能有幫助。
          2. 替換數(shù)據(jù)庫連接池 DBCP 和 C3P0,Druid 提供了一個高效、功能強(qiáng)大、可擴(kuò)展性好的數(shù)據(jù)庫連接池。
          3. 數(shù)據(jù)庫密碼加密,直接把數(shù)據(jù)庫密碼寫在配置文件中,這是不好的行為,容易導(dǎo)致安全問題。DruidDruiver 和 DruidDataSource 都支持 PasswordCallback。
          4. SQL 執(zhí)行日志,Druid 提供了不同的 LogFilter,能夠支持 Common-Logging、Log4j 和 JdkLog,你可以按需要選擇相應(yīng)的 LogFilter,監(jiān)控你應(yīng)用的數(shù)據(jù)庫訪問情況。
          5. 擴(kuò)展 JDBC,如果你要對 JDBC 層有編程的需求,可以通過 Druid 提供的 Filter-Chain 機(jī)制,很方便編寫 JDBC 層的擴(kuò)展插件。

          對于本文來說,我們重點(diǎn)來看它的第 3 個特性,也就是使用 Druid 來實(shí)現(xiàn)數(shù)據(jù)庫密碼加密。

          加密執(zhí)行流程

          在沒有進(jìn)行密碼加密之前,項(xiàng)目的交互流程是這樣的:

          在使用了密碼加密之后,項(xiàng)目的交互流程就變成了這樣:

          使用Druid實(shí)現(xiàn)加密

          本示例運(yùn)行環(huán)境:

          Spring Boot 2.4.3 

          MySQL 5.7 

          Java 1.8 

          Idea 2020.1.3

          1.添加Druid依賴

          Maven 項(xiàng)目:

          <dependency>
             <groupId>com.alibaba</groupId>
             <artifactId>druid-spring-boot-starter</artifactId>
             <version>1.2.5</version>
          </dependency>

          Gradle 項(xiàng)目:

          compile 'com.alibaba:druid-spring-boot-starter:1.2.5'

          獲取 Druid 最新版本:https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter

          2.生成密文

          Druid 添加完成之后就可以借助 Druid 中提供的 ConfigTools 類來加密密碼了,實(shí)現(xiàn)代碼如下:

          import com.alibaba.druid.filter.config.ConfigTools;

          class MyTests {
              public static void main(String[] args) throws Exception {
                  // 需要加密的明文命名
                  String password = "youPassword"// 【注意:這里要改為你自己的密碼】
                  // 調(diào)用 druid 生成私鑰、公鑰、密文
                  ConfigTools.main(new String[]{password});
              }
          }

          以上代碼執(zhí)行的結(jié)果如下:

          privateKey:MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEApOjcMWSDzJiKVGmtcBBoQPtM9tVW2H2cnS6xZK7NrbzQXYWLQD2zefIrrx9vMvqRIHEqkmAHTuUcUXHgCxu0cwIDAQABAkAlqo5ItdWo0Jqf5zdXJlg5p2yP4HCiqCYyfKzF+2s9KEmgWZJWTctZDsgQ0iYUohORR59I+J4nabhel1x5/INpAiEA6jwSyFqMUPOh1XlrzNFek+RthOQ5n4+ALPo+vULayO0CIQC0O7JM9sIq+tg+jCGv+ypk6vbuRKY9m5W2rSRXapGm3wIgRHul3jAjIDPrF/f1HaAFL+Y0Yws7Ebyp8/yCRWF7iA0CIALbe20q8FMcHPeI4zPWCIsHCpkmb3hEkjAOOKhGIT8DAiAqiUuz92NqKeyjmOfons1ka65EzVwA3NDhZ6+IQcnuig== publicKey:MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKTo3DFkg8yYilRprXAQaED7TPbVVth9nJ0usWSuza280F2Fi0A9s3nyK68fbzL6kSBxKpJgB07lHFFx4AsbtHMCAwEAAQ== password:IMgKm27bOHok3/+5aDL4jGBoVVZkpicbbM6pIXQppi3dI7h3jngSAqhqwqYnfuYpyVJ0k++q9xWWnHtd6sAWnQ==

          從上述結(jié)果可以看出,使用 ConfigTools 類會生成 3 部分的內(nèi)容:

          1. privateKey:私鑰,暫時不會用到,用于密碼的加密;
          2. publicKey:公鑰,用于密碼的解密;
          3. password:加密之后的密碼。

          PS:要實(shí)現(xiàn)數(shù)據(jù)庫的加密,主要使用的是 publicKey(公鑰)和 password(密文),這就把明文轉(zhuǎn)換成密文了。

          3.添加配置

          完成了以上操作之后,只需要將上一步生成的公鑰密文添加到項(xiàng)目的配置文件 application.yml(或application.xml)中就實(shí)現(xiàn)了加密操作了,具體配置信息如下:

          spring:
            # MySQL 配置
            datasource:
              driver-class-name: com.mysql.cj.jdbc.Driver
              type: com.alibaba.druid.pool.DruidDataSource
              druid:
                url: jdbc:mysql://127.0.0.1:3306/testdb?serverTimezone=Asia/Shanghai&characterEncoding=UTF-8&useSSL=false
                username: root
                password: IMgKm27bOHok3/+5aDL4jGBoVVZkpicbbM6pIXQppi3dI7h3jngSAqhqwqYnfuYpyVJ0k++q9xWWnHtd6sAWnQ==
                # encrypt config
                filters: config
                connect-properties:
                  config.decrypt: true
                  config.decrypt.key: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKTo3DFkg8yYilRprXAQaED7TPbVVth9nJ0usWSuza280F2Fi0A9s3nyK68fbzL6kSBxKpJgB07lHFFx4AsbtHMCAwEAAQ==

          其中 password 對應(yīng)的是上一步生成的 password(密文),而 config.decrypt.key 對應(yīng)的是上一步生成的 publicKey(公鑰),如下圖所示:

          這里提供一個原始的配置文件,以便和加密后的配置文件進(jìn)行比對:

          4.注意事項(xiàng)-插著鑰匙的鎖

          經(jīng)過前面 3 步的配置之后,我們的程序就可以正常運(yùn)行了,但這遠(yuǎn)沒有結(jié)束!

          在第 3 步配置時,我們將密文和公鑰都寫入配置文件,這就會造成當(dāng)有人拿到密文和公鑰之后,就可以使用 Druid 將加密的密碼還原出來了,這就好比一把插著鑰匙的鎖是極不安全的。

          因此我們正確的使用姿勢:是將公鑰找一個安全的地方保存起來,每次在項(xiàng)目啟動時動態(tài)的將公鑰設(shè)置到項(xiàng)目中,這樣就可以有效的保證密碼的安全了。

          正確的配置文件

          接下來我們將 Spring Boot 的公鑰設(shè)置為配置項(xiàng),在項(xiàng)目運(yùn)行時再替換為具體的值,最終的安全配置信息如下:

          spring:
            # MySQL 配置
            datasource:
              driver-class-name: com.mysql.cj.jdbc.Driver
              type: com.alibaba.druid.pool.DruidDataSource
              druid:
                url: jdbc:mysql://127.0.0.1:3306/testdb?serverTimezone=Asia/Shanghai&characterEncoding=UTF-8&useSSL=false
                username: root
                password: IMgKm27bOHok3/+5aDL4jGBoVVZkpicbbM6pIXQppi3dI7h3jngSAqhqwqYnfuYpyVJ0k++q9xWWnHtd6sAWnQ==
                # encrypt config
                filters: config
                connect-properties:
                  config.decrypt: true
                  config.decrypt.key: ${spring.datasource.druid.publickey}

          可以看出公鑰被修改成“${spring.datasource.druid.publickey}”了,這就相當(dāng)于使用占位符先把坑給占上,等項(xiàng)目啟動時再更換上具體的值。

          PS:“spring.datasource.druid.publickey”并非是固定不可變的 key,此 key 值用戶可自行定義。

          開發(fā)環(huán)境替換公鑰

          開發(fā)環(huán)境只需要在 Idea 的啟動參數(shù)中配置公鑰的值即可,如下圖所示:

          當(dāng)我們輸入正確的公鑰值時程序可以正常運(yùn)行,當(dāng)輸入一個錯誤的公鑰值時就會提示解碼失敗,如下圖所示:

          生產(chǎn)環(huán)境替換公鑰

          生產(chǎn)環(huán)境在啟動 jar 包時只需要動態(tài)設(shè)置公鑰的值即可,參考以下命令:

          java -jar xxx.jar --spring.datasource.druid.publickey=你的公鑰

          Druid運(yùn)行原理

          經(jīng)過上述步驟之后,我們就完成 MySQL 密碼的加密了,這樣當(dāng) Spring Boot 項(xiàng)目啟動時,Druid 的攔截器會使用密文和公鑰將密碼還原成真實(shí)的密碼以供項(xiàng)目使用,當(dāng)然這一切都無需人工干預(yù)(無需編寫任何代碼),Druid 已經(jīng)幫我封裝好了,我們只需要通過以上配置即可。

          什么?你想知道 Druid 是如何通過密文和公鑰還原出真實(shí)的密碼的?

          沒問題,滿足你,其實(shí) ConfigTools 類中已經(jīng)提供了相應(yīng)實(shí)現(xiàn),代碼如下:

          // 密文
          String password = "VwH1mu2IUpqjfKTd+gSikiZgJTi+3Y5zFIFRfxYnH1UqHzm1K8TIHnMaV3TErBaGsVEaGV0e63pb0Ys3Wdm7Kg==";
          // 公鑰
          String publicKey = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALWIEp19IM04sB+vQXnEOH9gFNFdL5TFGSEhORgHj4MnfTfBSNaOoSgCaM8BOpjiHmwuEb7LpvmXI1x/ymUvNzECAwEAAQ==";
          // 還原成真實(shí)的密碼
          String result = ConfigTools.decrypt(publicKey, password);
          System.out.println("最終結(jié)果:" + result);

          總結(jié)

          本文我們使用阿里巴巴開源的 Druid 實(shí)現(xiàn)了 MySQL 的密碼加密,Druid 的加密過程非常方便,無需編寫任何代碼,只需要添加 Druid 依賴,再通過 Druid 的工具類生成密文,最后將密文配置到 application.yml 文件即可。項(xiàng)目在運(yùn)行時會通過攔截器將密文轉(zhuǎn)換成真正的密碼,從而實(shí)現(xiàn)了 MySQL 密碼的加密和解碼的過程。

          最后

          原創(chuàng)不易,如果覺得本文對你有幫助,請點(diǎn)個贊再走吧

          如果可以,請隨手將它分享到你的朋友圈,讓更多需要的人知道,謝謝你。



          瀏覽 51
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产精品免费视频观看 | 大香蕉怡春院日韩精品视频 | 91专区在线| 男人的天堂视频网站 | 青青草国产视频在线观看 |