日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

项目配置不当引发了数据泄露,人已裂开!!

發布時間:2025/3/16 编程问答 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 项目配置不当引发了数据泄露,人已裂开!! 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近,有位讀者私信我說,他們公司的項目中配置的數據庫密碼沒有加密,編譯打包后的項目被人反編譯了,從項目中成功獲取到數據庫的賬號和密碼,進一步登錄數據庫獲取了相關的數據,并對數據庫進行了破壞。

雖然這次事故影響的范圍不大,但是這足以說明很多公司對于項目的安全性問題重視程度不夠。

?

數據泄露緣由

由于Java項目的特殊性,打包后的項目如果沒有做代碼混淆,配置文件中的重要配置信息沒有做加密處理的話,一旦打包的程序被反編譯后,很容易獲得這些敏感信息,進一步對項目或者系統造成一定的損害。

所以,無論是公司層面還是開發者個人,都需要對項目的安全性有所重視。

今天,我們就一起來聊聊如何在項目中加密數據庫密碼,盡量保證數據庫密碼的安全性。本文中,我使用的數據庫連接池是阿里開源的Druid。

?

數據庫密碼加密

配置數據庫連接池

這里,我就簡單的使用xml配置進行演示,當然小伙伴們也可以使用Spring注解方式,或者使用SpringBoot進行配置。

<!--數據源加密操作--> <bean?id="dbPasswordCallback"?class="com.binghe.dbsource.DBPasswordCallback"?lazy-init="true"/><bean?id="statFilter"?class="com.alibaba.druid.filter.stat.StatFilter"?lazy-init="true"><property?name="logSlowSql"?value="true"/><property?name="mergeSql"?value="true"/></bean> <!--?數據庫連接?--> <bean?id="readDataSource"?class="com.alibaba.druid.pool.DruidDataSource"destroy-method="close"?init-method="init"?lazy-init="true"><property?name="driverClassName"?value="${driver}"/><property?name="url"?value="${url1}"/><property?name="username"?value="${username}"/><property?name="password"?value="${password}"/><!--?初始化連接大小?--><property?name="initialSize"?value="${initialSize}"/><!--?連接池最大數量?--><property?name="maxActive"?value="${maxActive}"/><!--?連接池最小空閑?--><property?name="minIdle"?value="${minIdle}"/><!--?獲取連接最大等待時間?--><property?name="maxWait"?value="${maxWait}"/><!--?--><property?name="defaultReadOnly"?value="true"/><property?name="proxyFilters"><list><ref?bean="statFilter"/></list></property><property?name="filters"?value="${druid.filters}"/><property?name="connectionProperties"?value="password=${password}"/><property?name="passwordCallback"?ref="dbPasswordCallback"/><property?name="testWhileIdle"?value="true"/><property?name="testOnBorrow"?value="false"/><property?name="testOnReturn"?value="false"/><property?name="validationQuery"?value="SELECT?'x'"/><property?name="timeBetweenLogStatsMillis"?value="60000"/><!--?配置一個連接在池中最小生存的時間,單位是毫秒?--><property?name="minEvictableIdleTimeMillis"?value="${minEvictableIdleTimeMillis}"/><!--?配置間隔多久才進行一次檢測,檢測需要關閉的空閑連接,單位是毫秒?--><property?name="timeBetweenEvictionRunsMillis"?value="${timeBetweenEvictionRunsMillis}"/> </bean>

其中要注意的是:我在配置文件中進行了如下配置。

<bean?id="dbPasswordCallback"?class="com.binghe.dbsource.DBPasswordCallback"?lazy-init="true"/><property?name="connectionProperties"?value="password=${password}"/>?? <property?name="passwordCallback"?ref="dbPasswordCallback"/>

生成RSA密鑰

使用RSA公鑰和私鑰,生成一對公鑰和私鑰的工具類如下所示。

package?com.binghe.crypto.rsa; import?java.security.Key; import?java.security.KeyPair; import?java.security.KeyPairGenerator; import?java.security.interfaces.RSAPrivateKey; import?java.security.interfaces.RSAPublicKey; import?java.util.HashMap; import?java.util.Map; import?sun.misc.BASE64Decoder; import?sun.misc.BASE64Encoder; /***?算法工具類*?@author?binghe*/ public?class?RSAKeysUtil?{public?static?final?String?KEY_ALGORITHM?=?"RSA";public?static?final?String?SIGNATURE_ALGORITHM?=?"MD5withRSA";private?static?final?String?PUBLIC_KEY?=?"RSAPublicKey";private?static?final?String?PRIVATE_KEY?=?"RSAPrivateKey";public?static?void?main(String[]?args)?{Map<String,?Object>?keyMap;try?{keyMap?=?initKey();String?publicKey?=?getPublicKey(keyMap);System.out.println(publicKey);String?privateKey?=?getPrivateKey(keyMap);System.out.println(privateKey);}?catch?(Exception?e)?{e.printStackTrace();}}public?static?String?getPublicKey(Map<String,?Object>?keyMap)?throws?Exception?{Key?key?=?(Key)?keyMap.get(PUBLIC_KEY);byte[]?publicKey?=?key.getEncoded();return?encryptBASE64(key.getEncoded());}public?static?String?getPrivateKey(Map<String,?Object>?keyMap)?throws?Exception?{Key?key?=?(Key)?keyMap.get(PRIVATE_KEY);byte[]?privateKey?=?key.getEncoded();return?encryptBASE64(key.getEncoded());}public?static?byte[]?decryptBASE64(String?key)?throws?Exception?{return?(new?BASE64Decoder()).decodeBuffer(key);}public?static?String?encryptBASE64(byte[]?key)?throws?Exception?{return?(new?BASE64Encoder()).encodeBuffer(key);}public?static?Map<String,?Object>?initKey()?throws?Exception?{KeyPairGenerator?keyPairGen?=?KeyPairGenerator.getInstance(KEY_ALGORITHM);keyPairGen.initialize(1024);KeyPair?keyPair?=?keyPairGen.generateKeyPair();RSAPublicKey?publicKey?=?(RSAPublicKey)?keyPair.getPublic();RSAPrivateKey?privateKey?=?(RSAPrivateKey)?keyPair.getPrivate();Map<String,?Object>?keyMap?=?new?HashMap<String,?Object>(2);keyMap.put(PUBLIC_KEY,?publicKey);keyMap.put(PRIVATE_KEY,?privateKey);return?keyMap;} }

運行這個類,輸出的結果如下:

在輸出的結果信息中,上邊是公鑰下邊是私鑰。

對密碼進行加密

使用私鑰對明文密碼進行加密,示例代碼如下所示。

package?com.binghe.dbsource.demo; import?com.alibaba.druid.filter.config.ConfigTools; /***?使用密鑰加密數據庫密碼的代碼示例*?@author?binghe*/ public?class?ConfigToolsDemo?{/***?私鑰對數據進行加密*/private?static?final?String?PRIVATE_KEY_STRING?=?"MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKtq3IJP5idDXZjML6I8HTAl0htWZSOO43LhZ/+stsIG50WsuW0UJ2vdrEtjvTEfJxP6N1VNrbsF9Lrsp6A4AyUwx00ZUueTlbUaX60134Di0IdQ3C4RTt5mPIbF3hUKers8csltgYR4fByvR3Eq4lt+jAolVHKmyzufukH3d3vJAgMBAAECgYBXiyW+r4t9NdxRMsaI9mZ5tncNWxwgAtOKUi/I1a4ofVoTrVitqoNPhVB+2BtBQQW2IC2uNROq1incZQxeuPxxZJgz1lnnZyHvDE3wuMZAGTcalID+5xBZ2j6fBtDnxbfIL/tIfGJrX+0mUXP2LIo242yQIlzr7RV60iuE2Ms54QJBAOqE0ycvztfxubqBWO7l8PsS3qDUv9lLBBO/Q8I+qVl4tzh+SD/13BqLuaj9eWPGPyml+faWtbmuQgBqauT23l0CQQC7HmMC0CgZS6taQxmPkXzw0XhxZ7tBZeLWl87hqc2S79P0BPX9kPukiC4LpA5xyz0CZ5azJXd2EwRsxF32GERdAkASEi4bJOnxZeUD5BewQPOyxR92kS4/VjJ4OxLDkwSFqnGj3sc+dnmBaibiSLXj5FDVqr56K97Q8gaP9aNLBWLZAkEAjwGnPBQoQUTinaZgl6fibA47VbiolU+v8L+u3iqvMVhXjcxo0DUJDXMCdeUZIQDqDLdsplfBGB1qqVHeWeGsBQJAXGNe2I510WLjMdn+olhi5ZjMr4F4oiF8TAE1Uu74FWn0sc418E7ScgXPCgpGVK0QaXo2wtDeMIoxJwm9Zh8oyg==";public?static?void?main(String[]?args)?throws?Exception?{//密碼明文,也就是數據庫的密碼String?plainText?=?"root";System.out.printf(ConfigTools.encrypt(PRIVATE_KEY_STRING,?plainText));} }

運行上述代碼示例,結果如下所示。

然后將數據庫配置的鏈接密碼改為這個輸出結果如下:

jdbc.username=root jdbc.password=EA9kJ8NMV8zcb5AeLKzAsL/8F1ructRjrqs69zM70BwDyeMtxuEDEVe9CBeRgZ+qEUAshhWGEDk9ay3TLLKrf2AOE3VBn+w8+EfUIEXFy8u3jYViHeV8yc8Z7rghdFShhd/IJbjqbsro1YtB9pHrl4EpbCqp7RM2rZR/wJ0WN48=

編寫解析數據庫密碼的類

package?com.binghe.dbsource; import?java.util.Properties; import?com.alibaba.druid.filter.config.ConfigTools; import?com.alibaba.druid.util.DruidPasswordCallback; /***?數據庫密碼回調*?@author?binghe*/ public?class?DBPasswordCallback?extends?DruidPasswordCallback?{private?static?final?long?serialVersionUID?=?-4601105662788634420L;/***?password的屬性*/private?static?final?String?DB_PWD?=?"password";/***?數據對應的公鑰*/public?static?final?String?PUBLIC_KEY_STRING?=?"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCratyCT+YnQ12YzC+iPB0wJdIbVmUjjuNy4Wf/rLbCBudFrLltFCdr3axLY70xHycT+jdVTa27BfS67KegOAMlMMdNGVLnk5W1Gl+tNd+A4tCHUNwuEU7eZjyGxd4VCnq7PHLJbYGEeHwcr0dxKuJbfowKJVRypss7n7pB93d7yQIDAQAB";@Overridepublic?void?setProperties(Properties?properties)?{super.setProperties(properties);String?pwd?=?properties.getProperty(DB_PWD);if?(pwd?!=?null?&&?!"".equals(pwd.trim()))?{try?{//這里的password是將jdbc.properties配置得到的密碼進行解密之后的值//所以這里的代碼是將密碼進行解密//TODO?將pwd進行解密;String?password?=?ConfigTools.decrypt(PUBLIC_KEY_STRING,?pwd);?setPassword(password.toCharArray());}?catch?(Exception?e)?{setPassword(pwd.toCharArray());}}} }

這里DBPasswordCallback類,就是在配置文件中配置的DBPasswordCallback類,如下所示。

<bean?id="dbPasswordCallback"?class="com.binghe.dbsource.DBPasswordCallback"?lazy-init="true"/>

其中PasswordCallback是javax.security.auth.callback包下面的,底層安全服務實例化一個 PasswordCallback 并將其傳遞給 CallbackHandler 的 handle 方法,以獲取密碼信息。

當然,除了使用上述的方式,自己也可以對應一套加解密方法,只需要將 DBPasswordCallback的 String password = ConfigTools.decrypt(PUBLIC_KEY_STRING, pwd); 替換即可。

另外,在編寫解析數據庫密碼的類時,除了可以繼承阿里巴巴開源的Druid框架中的DruidPasswordCallback類外,還可以直接繼承自Spring提供的PropertyPlaceholderConfigurer類,如下所示。

public?class?DecryptPropertyPlaceholderConfigurer?extends?PropertyPlaceholderConfigurer{/***?重寫父類方法,解密指定屬性名對應的屬性值*/@Overrideprotected?String?convertProperty(String?propertyName,String?propertyValue){if(isEncryptPropertyVal(propertyName)){return?DesUtils.getDecryptString(propertyValue);//調用解密方法}else{return?propertyValue;}}/***?判斷屬性值是否需要解密,這里我約定需要解密的屬性名用encrypt開頭*/private?boolean?isEncryptPropertyVal(String?propertyName){if(propertyName.startsWith("encrypt")){return?true;}else{return?false;}} }

此時,就需要將xml文件中的如下配置

<bean?id="dbPasswordCallback"?class="com.binghe.dbsource.DBPasswordCallback"?lazy-init="true"/>

修改為下面的配置。

<bean?id="dbPasswordCallback"?class="com.binghe.dbsource.DecryptPropertyPlaceholderConfigurer"?lazy-init="true"/>

到此,在項目中對數據庫密碼進行加密和解析的整個過程就完成了。

有道無術,術可成;有術無道,止于術

歡迎大家關注Java之道公眾號

好文章,我在看??

總結

以上是生活随笔為你收集整理的项目配置不当引发了数据泄露,人已裂开!!的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。