一月 9, 2012

hoamon's sandbox
hoamon
hoamon's sandbox is about »

tag cloud

» 不應該在資料庫中紀錄使用者的明碼密碼

看到這個有趣的 Blog :「我的密碼沒加密」。我才知道這世上不懂『不應該在資料庫中紀錄使用者的明碼密碼』的程式設計師是如此之多。

這本應是菜鳥程式設計師才應該犯下的錯,沒想到連存在好幾年的「綠界」都有。我真的不願相信這是事實。話說回來,對一個合格的 Linux/Unix 管理員,不能有明碼密碼根本就是常識。

過去,我還想用 PGP 驗證來取代『在伺服器資料庫紀錄使用者密碼』,這法子絕對能確保「使用者密碼」不會外洩。只是,我沒遇到那個使用者能接受自己產生一對公私錀,利用它們來作登入的。

雖然我沒作出個 PGP 驗證的實際上線系統,但 StartSSL.com 作到了,它不是用 PGP 加解密,是另一種公私錀原理。所以外國月亮比較圓是真的。

在我所撰寫過的系統中,只要有帳號認證的,一定會在伺服器端用 md5/sha1 作 hash ,另外也會在瀏覽器端用 javascript 作 md5 hash 。

伺服器端 hash 是防自己人及入侵者,防入侵者不用講了,這是一定要的,但「自己人」為什麼要防呢? 想想看,一個系統內幾千甚至上萬個會員的帳號/密碼都可以給自己人看,那這些自己人難道不會換工作,難道不會對老闆不爽,難道不會被「社交」,將密碼變暗碼,除了保護使用者外,也是為自己人免責,至少使用者自己被社交了,他也不能栽髒我們。

而瀏覽器端的 md5 hash 又是為了什麼? 因為我寫的網頁系統少能跑在 https 上,無法為使用者輸入的密碼作加密以防止中間人攻擊。所以我只好用 md5 函式 hash 過使用者明碼密碼,這雖無法完全避免使用者帳戶被盜用(在明碼傳輸中,它就是有可能遭受中間人攻擊),但至少讓它們難以反推用戶的原始密碼。

另外也曾在一個「歷史系統」中,在瀏覽器端部份是使用 rsa 加密的。因為它之前只有使用「伺服器端 hash」作保護,而當我要再加上「瀏覽器端 hash 」功能時,會面臨「無法使用它的明碼密碼來作自我 hash 」。

是的, hash 也是有技巧的,不要用同一個 salt key 作,要不然入侵者破了一個使用者密碼後,其他的也都猜出來了。所以瀏覽器端,我都是用使用者原始密碼內的某個字去當 salt 來作 hash 的。

於是在「歷史系統」中,要把它一次轉成「有瀏覽器端 hash 」功能的話,勢必要每個使用者回來登入一次,我才有機會將系統轉移。這不是件容易的事。退而求其次,使用 rsa 加密就是不錯的方法。這方法是某個學弟找到的,原本我還不知道有原生的 js 函式庫能作 rsa 加密呢!

提了這些方法說明保護使用者明碼密碼不是作不到,只是有點麻煩而已。

然而那些程式設計師真的只是怕麻煩才不想使用 hash 密碼嗎? 根本不懂的程式設計師,就不要講了,剩下沒用 hash 的,除了怕麻煩外,我猜還怕另一樣東西: debug 。

紀錄「使用者明碼」密碼的惟一好處就是能操作「使用者」所能看到的頁面。

試想一個場景,某天使用者打客服電話,詢問歷史訂單事宜,他一直抱怨看不到之前的一筆 Ubuntu NB 訂單,可是客服用後台管理系統查詢,卻明確地說明使用者真的有這筆訂單。那這問題要如何解決?

如果客服有使用者的帳密,他是不是自己登入系統,來到相同頁面觀看,就能了解到底是系統有 bug ,還是使用者不會操作。有可能問題只是出在「訂單分頁」不夠明確,使用者不知道要點到第二頁去觀看訂單。

讓客服知道明碼密碼以便可以看到與使用者相同介面的網頁是不得以的方法嗎? 不。我們有更安全的作法。

我們的作法是在客服後台,有一個轉移帳戶的頁面,讓他填入帳號(且不用輸入密碼)後可轉換成任一個使用者,我們再紀錄那一個客服曾轉換成誰,又作了什麼,這樣客服不用知道使用者的明碼密碼,也可以變成那一個使用者,而且我們也知道客服幹了什麼好事,所以客服可以在面臨無法排除的困難時才會丟 ticket 給我們,這不是三方皆喜:使用者安全、客服好作事、程式設計師省事。

那這架構怎麼作? 因為程式語言、框架百百種。我只說明觀念,請程式設計師們自行發揮,當然有問題歡迎發問,或覺得我的方法可以改進的,也歡迎指教。

認證系統多半是使用 Session 架構來確認連線的使用者身份為何? 其他用 cookie 或是 GET 連結的也差不多,都是把使用者識別 ID (可能是使用者帳號,也可能是臨時編號)藏在某個變數之中,讓程式在執行時,能找到一個 key 值去對應資料庫中的使用者。

所以我們只要在那個對應資料庫使用者的程式中,多加上一個判斷式,如果有另一個轉換識別 ID 時,就把原使用者識別 ID 換成這個轉換識別 ID 。

例如: 何阿蒙客服登入系統後,連線 request 的使用者識別 ID 為 hoamon ,當他設定好轉換帳號為 grace 後,連線的 request 物件多了一個 grace 的轉換識別 ID 。這樣「對應資料庫使用者的程式」在運行時,就會知道使用者得用 grace 去代換,而不是 hoamon 。而我們的 log 函式在發現 request 物件多了轉換識別 ID 後,也會把『 hoamon => grace 』及所作的事一起紀錄到資料庫中。

這樣就能完全排除「明碼密碼」的使用了。

五月 4, 2009

hoamon's sandbox
hoamon
hoamon's sandbox is about »

tag cloud

» 千萬不要相信任何一個網頁系統(包含 Google),除非你用了公私錀(如 PGP)加密

當我們在作業系統(尤其是 Linux)中使用 Open Source 軟體時,我們有一定的信心認為程式作者不會呼隆我們。因為只要有心,我們看得到程式碼。

但對於任何一個網頁系統而言,基本上,你必須將它們都視為壞人,它們絕對拿得到你所上傳的資料,包含密碼 *1。就算它標榜著 Open Source 出品,也不能保證它放置網頁伺服器上的程式碼與 Open Source 版本是一模一樣的。

事實上,在使用網頁系統時,請保持著一種信念:「若要人不知,除非己莫為」。放到網站上的資料,除了你,別人(閘道器管理員、系統管理員、程式設計師甚至是客服小妹)絕對有辦法打開看,除非你使用公錀加密內文。這一點,就連 Google 網站也不例外。

所以,當我看到無名網站上提供一種「密碼保護文章/相簿」的功能時,我覺得很好笑,看看它在 html form 上所設計的方式,完全是以明碼形式將密碼傳至沒有 https 的網址,這樣何謂「密碼保護」! 無名站上工程師絕對有能力看得到你所保護的內文以及密碼。甚至有可能那些性愛相簿外流的原因中,有部份就是離職員工搞的鬼,但是誰知道呢? 當你用明文形式傳遞密碼時,理論上,它就不叫「密碼」了,當你用明文形式上傳文章或相片時,它們也不會是「有保護」的。

要真正上傳儲存「有保護」的內容,以目前技術來說,最簡單的就是 PGP 加密了。像是下面的密文,你看得出我寫的是什麼了嗎? 雖然,我大方地 po 在 blogger 上,但沒有私錀的人就是看不到。

-----BEGIN PGP MESSAGE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Use GnuPG with Firefox : http://getfiregpg.org (Version: 0.7.5)

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
ZvAf4PfWSCxGoarWUY+BGaGXCNUNifob+g==
=8e3M
-----END PGP MESSAGE-----

上面的密文,我用了三把公錀作加密,理論上,只有我、我老婆及 django-pgpauth 的私錀能解開。如果各位有興趣的話,我把 django-pgpauth 的私錀(我並未設定密碼)就放在 comment 中,請自取用。

如果你真的覺得要放在網站上的資料是需要隱私的,請不要相信該站所提供的密碼保護功能,用自己的比較安心。

至於如何使用 PGP (Linux/Mac/Windows 皆適用)來加解密及簽章驗證,請參考此篇

註1: 除非它們在認證網頁上,先用 One-Way Function(如: md5, sha-1) 先將明文密碼轉換過。

三月 27, 2009

hoamon's sandbox
hoamon
hoamon's sandbox is about »

tag cloud

» 如何在收信人不知情下,讓寄件人得知信件是否已開啟?

基本上,這問題的目的已經接近怪客行為了。因為你讓電腦使用者在不知情的情況下,傳遞某些訊息。

不過,因為問這問題的人不是為了收集 Email 位置,而是要確定收信人是否'''誤報'''信件接收狀態(也就是明明有收到,卻假裝沒收到來逃避作事)。所以,我提供一個廣為周知的方法來點醒他一下。

方法是'''利用圖檔'''。大家在使用 Gmail 時,有沒有發現為什麼某些信件格式是 html 且內含圖檔的信件都會被 Gmail 隱藏圖檔呢? 然後再提供一個顯示圖檔的連結, Gmail 何必脫褲子放屁,多此一舉讓使用者麻煩呢? 因為它是全球第一的 mail 服務商,別小看這個動作了。

因為圖檔是必須再連到某個伺服器來觀看的,所以如果這圖檔的 src 是 "http://some.where.from.you/?user_id=234455&mail;_id=45" ,則 http 伺服器勢必得到外部使用者的一個連線需求,且這連線還傳入了兩個變數:某個使用者及某封信件編號,如此一來,寄信者不就得到了收信者在瀏覽信件時所發出的連線需求。這樣就能確定收信者的確有收到此信。

但問題是,這個簡單的刺探動作早就被許多 webmail 或是 mail client 軟體給阻斷了。那又有什麼用呢? 是的,我們只能相信人類,人多是愚蠢的,所以如果你在信中放的是某些有趣/養眼的圖檔,誘惑他自己按下顯示圖檔的按紐,那他就中招了。

七月 30, 2007

hoamon's sandbox
hoamon
hoamon's sandbox is about »

tag cloud

» 網站登入不用密碼

不要跟我說那就是用 html 寫的網站。

要如何設計一個網站具有使用者辦認的需求但又不要求使用者打密碼呢?

你覺得這網站該如何設計?歡迎你與我討論。

請看我的想法

biggo.com.tw

A Django site.