變更drupal7用戶密碼加密方式

drupal 7 採用的是加鹽(salt)MD5碼來對用戶密碼進行加密,而不是以前drupal5和drupal6時代的簡單MD5加密方式。

這種新的加鹽(salt)MD5碼加密算法的大概情況可以參考這篇《浅谈MD5加密算法中的加盐值(SALT)》。

據說這種加密方式更安全喇~但是……

嗯,但是,在跟別的只使用MD5加密的程序共享用戶的時候問題就複雜了呢。

於是,小雪此次的任務是把drupal 7 用戶密碼的加密方式改回原來的簡單MD5加密。在這裡簡單記錄一下,參考官方論壇上某位大大提供的解決辦法

  1. 備份SQL數據庫
  2. 清除所有緩存 (caches)
  3. 執行以下SQL命令:
    DELETE FROM cache WHERE cid = 'variables';
    DELETE FROM cache_bootstrap WHERE cid = 'variables';
  4. 在drupal程序的根目錄添加 tools.php 文件,文件內容如下:
    ";
      define('DRUPAL_ROOT', getcwd());
    
      try {
        include_once DRUPAL_ROOT . '/includes/database/database.inc';
        include_once DRUPAL_ROOT . '/includes/cache.inc';
        require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
        require_once DRUPAL_ROOT . '/includes/update.inc';
        require_once DRUPAL_ROOT . '/includes/common.inc';
        require_once DRUPAL_ROOT . '/includes/file.inc';
        require_once DRUPAL_ROOT . '/includes/entity.inc';
        require_once DRUPAL_ROOT . '/includes/unicode.inc';
        require_once DRUPAL_ROOT . '/sites/default/settings.php';
    
    
        echo "mode=" . $_REQUEST["mode"] . "
    ";
        if($_REQUEST["mode"] == "set-var") {
          variable_set($_REQUEST["name"], $_REQUEST["value"]);
          echo "variable '" . $_REQUEST["name"] . "' was set to  '" . $_REQUEST["value"] . "'";
        } else if($_REQUEST["mode"] == "get-var") {
          $var = variable_get($_REQUEST["name"]);
          echo "get variable '"  . $_REQUEST["name"] . "'  value= '" .  $var . "'";
          //NOT WORKING FOR SOME REASON BIU NOT REQUIRE FOR THIS CHANGE
        }
    
      }catch(Exception $e) {
        echo "
    error:
    ";
        echo $e->getMessage();
      }
    
    ?>
  5. 在瀏覽器中打開以下網址:
    http://[drupal所在根目錄地址]/tools.php?mode=set-var&name=password_inc&value=includes/mypassword.inc
    如果網頁顯示有 variable ‘password_inc’ was set to ‘includes/mypassword.inc’ 則成功
  6. 在drupal程序的includes文件夾下添加 mypassword.inc 文件,文件內容如下:
    DEBUG mypassword.inc _password_crypt::password = '" . $password . "'";
      return md5($password);
    }
    
    /**
    * Parse the log2 iteration count from a stored hash or setting string.
    */
    function _password_get_count_log2($setting) {
      $itoa64 = _password_itoa64();
      return strpos($itoa64, $setting[3]);
    }
    
    /**
    * Hash a password using a secure hash.
    *
    * @param $password
    *   A plain-text password.
    * @param $count_log2
    *   Optional integer to specify the iteration count. Generally used only during
    *   mass operations where a value less than the default is needed for speed.
    *
    * @return
    *   A string containing the hashed password (and a salt), or FALSE on failure.
    */
    function user_hash_password($password, $count_log2 = 0) {
      return _password_crypt($password);
    }
    
    /**
    * Check whether a plain text password matches a stored hashed password.
    *
    * Alternative implementations of this function may use other data in the
    * $account object, for example the uid to look up the hash in a custom table
    * or remote database.
    *
    * @param $password
    *   A plain-text password
    * @param $account
    *   A user object with at least the fields from the {users} table.
    *
    * @return
    *   TRUE or FALSE.
    */
    function user_check_password($password, $account) {
    
      $stored_hash = $account->pass;
      $hash = _password_crypt($password);
    
      //echo "
    DEBUG mypassword.inc user_check_password::stored_hash = '" . $stored_hash . "'";
      //echo "
    DEBUG mypassword.inc user_check_password::hash = '" . $hash . "'";
      return ($hash && $stored_hash == $hash);
    }
    
    /**
    * Check whether a user's hashed password needs to be replaced with a new hash.
    *
    * This is typically called during the login process when the plain text
    * password is available. A new hash is needed when the desired iteration count
    * has changed through a change in the variable password_count_log2 or
    * DRUPAL_HASH_COUNT or if the user's password hash was generated in an update
    * like user_update_7000().
    *
    * Alternative implementations of this function might use other criteria based
    * on the fields in $account.
    *
    * @param $account
    *   A user object with at least the fields from the {users} table.
    *
    * @return
    *   TRUE or FALSE.
    */
    function user_needs_new_hash($account) {
      // Check whether this was an updated password.
      if ((strlen($account->pass) != DRUPAL_HASH_LENGTH)) {
        return TRUE;
      }
    
      return FALSE;
      // Ensure that $count_log2 is within set bounds.
      //$count_log2 = _password_enforce_log2_boundaries(variable_get('password_count_log2', DRUPAL_HASH_COUNT));
      // Check whether the iteration count used differs from the standard number.
      //return (_password_get_count_log2($account->pass) !== $count_log2);
    }
    ?>
  7. 至此,已經將drupal7用戶密碼加密方式改為簡單的MD5了,現在可以移除剛才的tools.php文件了。

如果不成功,歡迎前往原帖查看debug方式XD 。小雪在生產和測試環境都是做一次就成功了,對不同的站點做也成功實現了,因此覺得這個變更應該不會太常出包吧XD。

需要注意的是,更改完了加密方式以後,原來的密碼就失效了~如果你跟小雪一樣在操作前就已經用user ID 1的賬號登錄了,並且保持活動狀態的話,在更改完密碼以後就可以直接在drupal後台對除此賬號外的用戶更改新密碼。也可以在SQL數據庫中直接更新相應的密碼,用update命令可以批量更新喔~