如何避免在tomcat的server.xml数据源的资源定义中明文存储密码?
时间:2020-03-06 14:40:58 来源:igfitidea点击:
tomcat的server.xml
中的资源定义看起来像这样...
<Resource name="jdbc/tox" scope="Shareable" type="javax.sql.DataSource" url="jdbc:oracle:thin:@yourDBserver.yourCompany.com:1521:yourDBsid" driverClassName="oracle.jdbc.pool.OracleDataSource" username="tox" password="toxbaby" maxIdle="3" maxActive="10" removeAbandoned="true" removeAbandonedTimeout="60" testOnBorrow="true" validationQuery="select * from dual" logAbandoned="true" debug="99"/>
密码是明文的。如何避免这种情况?
解决方案
我们使用C#的SHA1CryptoServiceProvider
print(SHA1CryptoServiceProvider sHA1Hasher = new SHA1CryptoServiceProvider(); ASCIIEncoding enc = new ASCIIEncoding(); byte[] arrbytHashValue = sHA1Hasher.ComputeHash(enc.GetBytes(clearTextPW)); string HashData = System.BitConverter.ToString(arrbytHashValue); HashData = HashData.Replace("-", ""); if (HashData == databaseHashedPassWO) { return true; } else { return false; });
)
Tomcat需要知道如何连接到数据库,因此需要访问纯文本密码。如果密码是加密的,则Tomcat需要知道如何解密它,因此我们只是将问题移到了其他地方。
真正的问题是:除了Tomcat之外,谁还能访问server.xml
?一种解决方案是仅向root用户授予对server.xml
的读取访问权限,这要求Tomcat以root特权启动:如果恶意用户在系统上获得root特权,则丢失数据库密码可能是一个小问题。
否则,我们应该在每次启动时手动键入密码,但这很少是一个可行的选择。
如前所述,加密密码只是将问题转移到其他地方。
无论如何,这很简单。
只需编写一个类,其中包含用于密钥的静态字段等,以及用于加密,解密密码的静态方法。
使用此类将密码加密在Tomcat的配置文件(" server.xml"或者" yourapp.xml" ...)中。
为了在Tomcat中"即时"解密密码,请扩展DBCP的BasicDataSourceFactory
并在资源中使用该工厂。
它看起来像:
<Resource name="jdbc/myDataSource" auth="Container" type="javax.sql.DataSource" username="user" password="encryptedpassword" driverClassName="driverClass" factory="mypackage.MyCustomBasicDataSourceFactory" url="jdbc:blabla://..."/>
对于定制工厂:
package mypackage; .... public class MyCustomBasicDataSourceFactory extends org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory { @Override public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment) throws Exception { Object o = super.getObjectInstance(obj, name, nameCtx, environment); if (o != null) { BasicDataSource ds = (BasicDataSource) o; if (ds.getPassword() != null && ds.getPassword().length() > 0) { String pwd = MyPasswordUtilClass.unscramblePassword(ds.getPassword()); ds.setPassword(pwd); } return ds; } else { return null; } }
希望这可以帮助。