? ? ? ? 最近做的一个项目,想要使用公司的OA账户,但是OA系统是php语言开发的,首先要解决的就是如何在java中做密码校验,而OA系统使用的是php crypt()函数加密,刚开始想着通过相同的算法,生成密文,然后再与数据库中存的密文做比较就可以了。但是,查了php crypt()函数的文档:
? ? ? ? ?也就是说需要知道salt以及相应的加密方式才能生成密文,跟OA开发方联系,懂的人不回信,回信的人又不懂,只说使用crypt加密,salt都不知道,说问问别人再回复,顿时感觉没指望啦,果不其然,一下班立马联系不上啦,关键时刻还得靠自己啊,谷哥度娘一起上,从网上下了一份老版本的源码,虽然不是很全,但是还是有价值的,在修改密码功能中发现了有用的东东:
class="php">$query = "SELECT PASSWORD,USEING_KEY from USER where USER_ID='".$LOGIN_USER_ID."'"; $cursor = exequery( $connection, $query ); if ( $ROW = mysql_fetch_array( $cursor ) ) { $PASSWORD = $ROW['PASSWORD']; $USEING_KEY = $ROW['USEING_KEY']; if ( crypt( $PASS0, $PASSWORD ) != $PASSWORD ) { message( "错误", "输入的原密码错误!" ); button_back( ); exit( ); } } $PASS1 = crypt( $PASS1 ); $CUR_TIME = date( "Y-m-d H:i:s", time( ) ); $query = "update USER SET PASSWORD='".$PASS1."',LAST_PASS_TIME='{$CUR_TIME}' where USER_ID='{$LOGIN_USER_ID}'"; exequery( $connection, $query );
? ? ? ? ?从上面来看,密码的生成是直接调用crypt()函数的,没有加salt,根据文档,是按照响应的规则自动随机生成的,并且每次生成的都不一样,也就是说,根据只有明文是不能直接得到密文的,此路不通,只能另辟蹊径。再看上面输出message()的if语句条件?monospace; font-size: 1em; line-height: 1.5;">crypt( $PASS0, $PASSWORD ) != $PASSWORD,这个也就是判断密码是否正确的条件,里面的$PASS0是密码的明文,$PASSWORD是数据库里面存的密文,按照这个逻辑,使用php代码将已知的密码明文以及密码密文做个验证,这里有个在线运行php以及其他语言代码的网站,还不错:http://codepad.org,经验证,所有测试的密码明文和密文都是匹配的,也就是说在当前版本的OA系统中,这块儿的逻辑还没有发生变化。
? ? ? ? 现在的问题就是找到该crypt方法的java语言实现,还是谷哥给力,在http://stackoverflow.com/questions/3292160/equivalent-of-phps-crypt-function-in-java中有人提到了apache的commons-codes里面的两个类UnixCript 和Md5Crypt,经过查看java doc以及测试,最终证实Md5Crypt中的md5Crypt方法可以实现上述php代码中crypt的功能。Over!
?
? ? ? ? 虽然问题得到了解决,但是还有疑问有待进一步研究:为什么crypt( $PASS0, $PASSWORD ) == $PASSWORD 就可以说明密码正确了?(这个可能需要详细了解其加密算法)
?