酷!學園
2010-03-18 03:26 *
歡迎光臨, 訪客. 請先 登入註冊一個帳號.
您忘了 啟用您的帳號嗎?

請輸入帳號, 密碼以及預計登入時間
新聞:
 
   首頁 | Study-Area | 鳥園 | 鳥哥的Linux私房菜   說明 搜尋 日曆 登入 註冊  
頁: [1]
  列印  
作者 主題: 使用php程式作ldap登入在密碼部份的加密該如何處理?  (閱讀 6358 次)
0 會員 以及 1 訪客 正在閱讀本篇主題.
huangxianqin
憂鬱的高中生
***
文章: 124


檢視個人資料
« 於: 2008-03-06 15:17 »

各位前輩好,小弟最近工作需求必須為一個開發的網頁系統在登入部份使用ldap認證

目前大致了解到ldap是如何運作與設定了,而我必須使用php_ldap模組來作連線驗證

想先請問是否我在作登入認證的時候必須要bind上主機才可以進行?小弟使用php.net管網提供的簡單測試程式想測試一下以ldap_compare來比較我預登入的伺服器上userpassword這個屬性的值,使用的程式碼如下,但我瞭解到該伺服器必須以帳號密碼作bind,所以如果是的話我就必須先取得帳號密碼完成bind後才能傳送帳號密碼作比對嗎?

程式碼:
$ds=ldap_connect("webmail.xxx.edu.tw");  // must be a valid LDAP server!
echo "connect result is " . $ds . "<br />";

if ($ds) {

       if (ldap_bind($ds)) {

        // prepare data
        $dn = "uid=xxx,ou=People,dc=xxx,dc=edu,dc=tw";
        $value = crypt('xxxxxxxxxx');
        $attr = "userpassword";

        // compare value
        $r=ldap_compare($ds, $dn, $attr, $value);

        if ($r === -1) {
            echo "Error: " . ldap_error($ds);
        } elseif ($r === true) {
            echo "Password correct.";
        } elseif ($r === false) {
            echo "Wrong guess! Password incorrect.";
        }

    } else { echo "Unable to bind to LDAP server."; }

    ldap_close($ds);

} else {
    echo "Unable to connect to LDAP server.";
}

而我主要的問題在於我查了sldap.conf,發現有
程式碼:
password-hash {crypt}

這行設定,這代表我傳送的密碼部份也應該作相對加密吧?於是我使用php的crypt()來先對密碼值作加密但比對回傳的結果有誤?

請問前輩們,我哪邊錯了嗎?還是我應該注意什麼?

請指教~謝謝

已記錄
twu2
酷!學園 學長們
俺是博士!
*****
會員性別: 男
文章: 4772



檢視個人資料 個人網站
« 回覆文章 #1 於: 2008-03-06 15:47 »

直接用那個使用者帳號與密碼去 bind 不就知道了嗎? 為什麼要去比對呢?

PS. 這個方法的缺點是, 要記得先檢查密碼是不是空字串, 因為不用密碼呼叫 ldap_bind() 也會成功. (也就是不允許使用空的密碼)
« 最後編輯時間: 2008-03-06 15:50 由 twu2 » 已記錄

huangxianqin
憂鬱的高中生
***
文章: 124


檢視個人資料
« 回覆文章 #2 於: 2008-03-06 17:15 »

我首先測試了學長說得直接去bind,我的sldap.conf下設定值如下:
程式碼:
database ldbm
suffix "dc=xxx,dc=edu,dc=tw"
rootdn "cn=Manager,dc=xxx,dc=edu,dc=tw"
rootpw {crypt}9FyHWS0IRFA3E

於是我在php程式使用這樣的方式去bind測試
程式碼:
$ldaprdn  = 'uid=k1,ou=People,dc=xxx,dc=edu,dc=tw';     // ldap rdn or dn
$ldappass = 'passwd';  // associated password
    // bind
    if (ldap_bind($ds,$ldaprdn,$ldappass)) {

其他部份還是跟之前一樣.....之前是出現:Unable to bind to LDAP server.
這次出現的訊息則是Wrong guess! Password incorrect.

可是明明我使用的登入值都一樣為何可以bind卻compare錯誤?
已記錄
twu2
酷!學園 學長們
俺是博士!
*****
會員性別: 男
文章: 4772



檢視個人資料 個人網站
« 回覆文章 #3 於: 2008-03-06 17:46 »

ldap_bind() 不成功, 表示該 dn 的密碼不對.
如果你認為密碼與 dn 都對... 那自己用那組帳號密碼在 ldap_search 指令試一下就知道了.

ldap_bind() 成功, 就表示該 dn 的密碼是對的. 既然是對的, 還用 ldap_compare() 去比對做什麼呢?
« 最後編輯時間: 2008-03-06 17:56 由 twu2 » 已記錄

huangxianqin
憂鬱的高中生
***
文章: 124


檢視個人資料
« 回覆文章 #4 於: 2008-03-06 18:10 »

我想我得再次把我的問題點說清楚一點@@"

我最主要是不懂:該如何用php去傳可以讓ldap server驗證我的uid帳號跟我的passwd,帳號那邊當然沒問題,而問題是

密碼儲存在ldap內都是採用passwd-hash {crypt}這種hash加密方式,於是我不是應該也要把使用者打在網頁上的表單密碼

先作過一樣的加密後傳給ldap server?於是我上網查一下這部份,了解到php有crypt()可以作加密,我主要以為ldap_compare

是可以驗證傳遞的內容是否跟儲存的資料一樣,這不就是我要的嗎?

而關於ldap_bind部份,我只是不太確定是否我要驗證account跟passwd要先bind server,當然我懷疑我ldap_bind()應該沒有bind成功

因為我下的密碼根本不是sladp.conf內的rootpw設定,那個在conf檔裡也是經過加密的,所以之前我請問是否我得先取得bind所需的帳號密碼才能作php表單驗證的功能

而難道透過php去查詢ldap server內的帳號密碼,不是以ldap_compare這個函式來實做嗎?也許這部份是我所誤解的地方,因為這也是我第一次用ldap....

所以請問學長,如果那是用password-hash {crypt}來作加密的話,我該怎麼用php作密碼驗證?
已記錄
twu2
酷!學園 學長們
俺是博士!
*****
會員性別: 男
文章: 4772



檢視個人資料 個人網站
« 回覆文章 #5 於: 2008-03-06 19:28 »

所以... 你是要去更改密碼, 而不是去檢查密碼才對. 更改密碼不須要去讀密碼吧, 直接改就可以了.
程式碼:
if (ldap_mod_replace($id, "uid=$username,dc=example,dc=com",
        array('userpassword' => "{MD5}".base64_encode(pack("H*",md5($newpass)))
    echo "succeded\n";
else
    echo "failed";

利用 md5 來設定密碼就可以了. 只要你之前 bind 的帳號, 有權限可以更改 userpassword 屬性就可以了.
已記錄

huangxianqin
憂鬱的高中生
***
文章: 124


檢視個人資料
« 回覆文章 #6 於: 2008-03-07 11:05 »


......我覺得學長好像還是誤解我的意思耶

我用最直接的方式來問我的問題好了

我在網頁login.php接收到來自login.html兩個使用者填的表單變數:1.$_REQUEST['account']=huangxian 2.$_REQUEST['passwd']=123456

我現在要怎麼透過ldap確定該位使用者資訊正確!!我的問題點在於要怎麼比對"密碼欄位"....因為ldap儲存的userPassword資料預設就是以password-hash {crypt}來作了加密.....

因為我使用ldap_search()查到的密碼欄位看起來像這樣:{crypt}9FyHWS0IRFA3E

我想了解的是:123456該怎麼跟{crypt}9FyHWS0IRFA3E這個作比對呢........

查了很久的資料,發現mail-list裡面也有別人有跟我一樣類似的疑問,但卻沒有明確的解答- -!  難道大家學ldap在密碼驗證部份都很直覺的會嗎?
已記錄
Pail
俺是博士!
*****
會員性別: 男
文章: 1033


檢視個人資料
« 回覆文章 #7 於: 2008-03-07 11:08 »

ldap 帳號密碼的檢查, 不是你在做的....
基本上你只能把 帳號,密碼...送給 ldap server...
它會回傳你 bind 成功/失敗....
已記錄

Pail Luo.
Email: pail.luo@gmail.com
twu2
酷!學園 學長們
俺是博士!
*****
會員性別: 男
文章: 4772



檢視個人資料 個人網站
« 回覆文章 #8 於: 2008-03-07 11:17 »

前面說過了, 要知道密碼對不對, 不是說過直接去 bind 就知道了嗎? 為什麼要直接去抓密碼的欄位出來比呢?
那是用 crypt 編碼過的, 你又不知道人家用什麼 salt 去編, 怎麼可能算出一樣的碼出來呢?

程式碼:
if ($password !== '' && ldap_bind($id, "uid=$username,dc=example,dc=com", $password))
   echo "password correct!\n";
else
   echo "wrong password!\n";

你的目的不就是要知道密碼對不對嗎? 上頭的方式, 不就知道了嗎? 有必要去抓 userPassword 出來比對嗎?
系統本來就提供一個方法讓你去判斷密碼是否正確, 你又為什麼不用, 一定要去比對 userPassword 的值呢?

已記錄

huangxianqin
憂鬱的高中生
***
文章: 124


檢視個人資料
« 回覆文章 #9 於: 2008-03-07 14:01 »

看到最後兩篇學長的回覆,我終於知道問題點跟誤會的地方在哪裡了.....

過去沒接觸過ldap,在設計網頁作會員登入部份,大概不外乎使用資料庫的資料比對...我發問前所看的書本跟網路上得資料顯示
都說ldap儲存資料就像是一個資料庫方式,而類似dns那樣去作查詢。

至少我想使用php+mysql時做會員資料驗證,不都是先以某個使用者權限帳號跟密碼進行連線後,再去取出資料庫主要的會員相關欄位作比對,所以我之前才會以為設定在sldap.conf內的rootdn跟rootpw是作ldap_bind動作,然後才有權限去查ldap其他儲存的帳號資料.....我以為那大概是ldap_compare來作...至少官方說明給我的感覺是那樣@@"

就twu2學長最後提供給小弟的方式確實是我發問的解答....會根據uid帳號去查password是否正確...
之前上來學園請教版上得學長前有先詢問過同事,他告訴我說可能有兩種處理方式,第一是傳送未加密的資料給ldap,然後用某種方式告訴ldap做了加密後在比對密碼,就twu2大大說得大概是這種,而我也看不出來那個「某種方式要求ldap作加密後在比對」,好像根本不需要,ldap自己會去判斷一樣。
而他還說有另一種是在傳輸前先做了同樣的加密動作,然後把這個加密的內容送給ldap作比對.....這是我一開始嘗試解決的方式,請問有經驗的學長,是否有這樣的方式存在呢?

還是說作ldap資料查詢針對已加密內容都是以原本「未加密」的資料送給ldap他本身會判斷處理?
已記錄
acty
鑽研的研究生
*****
文章: 675


檢視個人資料 個人網站
« 回覆文章 #10 於: 2008-04-20 20:47 »

其實寫程式時  可以先參考別人的範例

你去參考一下 以 php 寫的 ldap  管理程式 - phpldapadmin 的程式碼  大概就知道上面的大大說什麼

只要知道怎麼 bind , 不需理會密碼需不需要加密
« 最後編輯時間: 2008-04-20 20:56 由 acty » 已記錄

~~破窗計畫來囉~~~

學習與挑戰是我的樂趣... HIT!!
我知道的不多  但歡迎大家以起來討論

UNIX 管理者的學習紀錄 - http://actychen.wordpress.com
頁: [1]
  列印  
 
前往:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.11 | SMF © 2006, Simple Machines LLC Valid XHTML 1.0! Valid CSS!
本頁花了 0.415 秒,以及 17 次的資料庫查詢。