resin中jndi数据源密码进行加密

格陵兰鲨鱼王 8月前 ⋅ 214 阅读

背景

安全检查,有人觉得在resin的配置文件中明文存放数据源密码不安全,要求把配置文件中的密码进行加密。

分析过程

项目使用的是resin的jndi方式来配置数据源,猜测resin启动的时候读取配置文件中的数据源信息,然后创建连接池。所以我只需要找到resin读取配置文件中密码的地方,把加密的密码进行解密即可。

在resin/lib下面找到了resin.jar,凭着第六感觉得就是这货。

jd-gui.exe打开查看反编译的代码。

因为配置文件中有password关键字

<database>
    <jndi-name>jdbc/main_db</jndi-name>
    <driver type="com.mysql.jdbc.Driver">
        <url>jdbc:mysql://127.0.0.1:3306/***?characterEncoding=gbk</url>
        <user>root</user>
        <password>2root</password>
    </driver>
    <prepared-statement-cache-size>8</prepared-statement-cache-size>
    <max-connections>50</max-connections>
    <max-idle-time>320s</max-idle-time>
</database>

所以全局搜索password

很幸运,在com.caucho.sql.DriverConfig文件中找到了。

改造过程

  • 新建项目,添加resin.jar为依赖项。新建DriverConfig.java文件,并拷贝上面反编译的代码。
  • 原本想在读取配置文件后修改password的值,没有找到这个地方,后来干脆修改DriverConfig.java中的setPassword方法。
// 删除密码前面的第一位,假装是一个解密过程
public void setPassword(String password) {
    if(password != null && password.length()>0){
        this._password = password.substring(1);
    }else{
        this._password = password;
    }
}
  • 然后编译

编译时遇到一个问题,DriverConfig.java文件中的import javax.resource.spi.ManagedConnectionFactory;报不存在,经排查发现这是企业版javaEE中的类,想要安装JavaEE8,下载下来之后发现事情没那么简单,不知道怎么安装。

后来下载了resin源码,在resin-4.0.13\modules\jca\src\javax\resource\spi路径下找到了ManagedConnectionFactory,所以把Java源码中jca下的代码拷贝到了新建项目中,万万没想到,啥错都没有报,编译通过。

  • 用编译后的DriverConfig.class文件替换原来resin.jar中的文件,把jar放回lib
  • 修改resin.xml文件中的数据源配置,在原来密码的前面加个2(假装加密)
  • 启动项目,正常访问数据库,改造完成

方法二

后来,发现了另一种更好的办法。原来,resin自身就已经支持jndi密码加密。见:官方文档。只要自定义一个解密的类即可。

原文地址


全部评论: 0

    我有话说: