我是做java的,但是最近要做和一个php的oa的对接,牵扯到了站点登陆,要去那边的数据库匹配密码
那边的加密是用php的crypt加密,我用了java中的Md5Crypt.md5Crypt去进行加密,但是加密后的值不一样,然后他给了我加密源码,我能理解到时一个循环,但是不太理解意思,因为没有接触过php,所以希望有大神帮我解释下下面这段代码,谢谢。
function getPass($str,$seed=NULL){
  if ($seed){
   $result = crypt($str,'$1$'.$seed.'$');
  } else {
   $seed = '';
   $i = 0;
   while ($i<8){
    $a = rand(65,122);
    if (($a>64 && $a<91) || ($a>96 && $a<123)){
     $seed = $seed.chr($a);
     $i++;
    }
   }
   $result = crypt($str,'$1$'.$seed.'$');
   
  }
  return $result;

解决方案 »

  1.   


    function getPass($str,$seed=NULL){   //创建getPass函数,参数为$str,$seed=NULL(默认为空)
      if ($seed){ //如何执行函数时有第二个参数,并且值不为假则执行{}
       $result = crypt($str,'$1$'.$seed.'$');  //生成加密密码
      } else {
       $seed = '';   //定义一个变量$seed为空字符串
       $i = 0;
       while ($i<8){ //循环开始
        $a = rand(65,122);// $a = 随机生成一个65至122的数(比如$a=65)
        if (($a>64 && $a<91) || ($a>96 && $a<123)){ //如何(90<$a<97)则重新生成$a否则执行{}
         $seed = $seed.chr($a); //使用chr将$a转化相对应于 ascii 所指定的单个字符。并拼接起来 
         $i++; //执行8次
        }
       }
         $result = crypt($str,'$1$'.$seed.'$'); //生成加密密码  
      }
      return $result;//返回加密后的密码
      

  2.   


    这个在php里面第二个参数是默认为null,那么在判断的时候是判断第二个参数的boolean值?如果举个例子,我在调用这个方法的时候是不是可以理解成,参数是(123,false)或者(345)这样子的?
    第二个问题是,下面的内容在执行的时候是一个随机数的8位,如果我第二次对同一个密码加密,那么这8位随机数一定不会相同,那加密出来的肯定不一样,我还是匹配不到数据库的东西吧
      

  3.   

    你先要复习一下 crypt 加密的原理
    本质上讲 crypt 是不可逆的,所以不能算是加密。加密就应该能解密不知道 java 的 Md5Crypt.md5Crypt 方法的原型是什么,请您最好贴出来php 的 crypt 函数的第二个参数 salt(盐)是佐料,你也可以理解为是密钥(但不严密,不能解密就无所谓密钥)
    这个 salt 是出现在 crypt 结果头部的,并且只有8个有效长度
    比如$s = 'abcd';
    echo crypt($s, '$1$1234567890$'), PHP_EOL;//$1$12345678$N/3zBznjFuq/Ila9YecQl.
    echo crypt($s, '$1$12345678$'), PHP_EOL;  //$1$12345678$N/3zBznjFuq/Ila9YecQl.
      

  4.   

    第一个问题: 传参的话如果只有一个参数,则默认为false, 如果有第二个参数的话,那就判断这个值是什么的了,如果是0,还是不执行if,直接进入else。
    第二个问题:我不太清楚提供PHP接口的人是怎么处理的,有可能是将$seed保存起来,登录的时候$seed是有值的,就是直接执行if里面的,返回的$result结果一样。但具体怎么实现的,你给的这段代码我真不知道。
      

  5.   

    不知道就不要装知道
    不知道求请阅读手册,虽然是英文的,但借助百度翻译也还是能看明白的主贴中构造 $seed 的算法,反映了原作者并不知道 salt 这个参数的真正含义
    因为放 8 个可打印字符比只是字母的迷惑性更大
      

  6.   


    说的我更迷糊了,我的问题很简单,就是在转换成java的时候,如果我也按照这种
    我看到数据库里,他所有的密码都是$1$OGHSacVe$bijZ9YtAYqqQDKZjDWKXs.
    $1$OykzTzPe$HlqjXFEtTrrZkE09N/ic/0
    那我可以不可以理解为他就没有走else,全部是按照salt的值为1去执行的
      

  7.   

    对于这样的加密结果
    $1$OGHSacVe$bijZ9YtAYqqQDKZjDWKXs.
    $1$OykzTzPe$HlqjXFEtTrrZkE09N/ic/0
    套红的就是程序中产生的(或传入的)$seed至于 crypt 函数,如果参数 salt 为空,那他自己会去产生一个
    而在验证结果的时候,需要从已保存的串中截取直到$(含 $)的部分作为 salt,对输入串做 crypt
    当两个结果相同时,就表示通过验证
      

  8.   

    您说的这个意思是,在执行登陆,也就是验证结果的时候,如果我对用户test,密码123,数据库加密后的结果为
    $1$OykzTzPe$HlqjXFEtTrrZkE09N/ic/0这条数据进行验证,实际上执行的crypt 函数是(123,$1$OykzTzPe$)这样的执行逻辑?就是先去查询了用户test的密码并截取了包含$的字符串作为salt进行加密验证?我理解的正确吗