當網站需要會員機制時,除了會員名稱(姓名)、帳號外,當然最重要的就是密碼。 在此不討論那些腦殘的明文密碼http://plainpass.com/ 密碼加密的原則有
- 單向加密
- 可以比對正確與否
一、單向加密:也就是將密碼加密後,從加密資訊無法還原或得知原始密碼字串。這是後續要討論的所以先說明雙向編碼。 雙向編碼就是可還原原始資料,例如 base64
1 2 3 |
<?php echo base64_encode( 'a' ); // 將 a 使用 base64 編碼,結果為 YQ== echo base64_decode( 'YQ==' ); // 將 YQ== 使用 base64 解碼,結果為 a |
至於單向加密可以使用 md5() 或是 sha1 ,例如
1 2 3 |
<?php echo md5( 'a' ); // 0cc175b9c0f1b6a831c399e269772661 echo sha1( 'a' ); // 86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 |
- md5() 單向「固定」加密,字元長度 32
- sha1() 單向「固定」加密,字元長度 40
什麼是固定加密?顧名思義就是每次加密的結果是一樣的,也就是如此的特性才可以拿來當作密碼比對。
--
變動的加密字串
那有變動加密嗎?在 PHP 裡也是有的,可以使用 crypt()
產生加密,以 sha256 為例
1 2 |
<?php echo crypt('abc', '$5$rounds=5000$'. uniqid() .'$'); |
當下產生的加密字串為
1 |
$5$rounds=5000$5ad2b33017c4e$jztEpFXSNd53ndl.i0bif5vNGbOTIaZVBKb.aqWy/x6 |
使用 uniqid() 的緣故,所以重新整理每次產生的字串皆不同,如此即可防止兩個相同的密碼被輕易破解
查核密碼時,因為字串變動的緣故無法單純的使用字串比對的方式,還是需要使用 crypt() function 來檢查
1 2 3 4 5 |
<?php $hashed_password = '$5$rounds=5000$5ad2b33017c4e$jztEpFXSNd53ndl.i0bif5vNGbOTIaZVBKb.aqWy/x6'; if (crypt('abc', $hashed_password) == $hashed_password) { echo '密碼吻合!'; } |
案例二:一個相對精簡的案例
1 2 3 4 5 |
<?php $a = crypt('hoyo', ''); if (crypt('hoyo', '$1$mGxOBjJX$7ofXUMIKBGs0Lv1sQ76Kw/') == '$1$mGxOBjJX$7ofXUMIKBGs0Lv1sQ76Kw/'){ echo 'Hoyo!!!'; } |
--
3,173 total views, 2 views today