中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

php中密碼的加密處理及安全措施

在數(shù)據(jù)庫中保存明文密碼是非常不明智的選擇,其危害不言而喻。

公司主營業(yè)務(wù):成都網(wǎng)站建設(shè)、做網(wǎng)站、移動網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競爭能力。成都創(chuàng)新互聯(lián)是一支青春激揚、勤奮敬業(yè)、活力青春激揚、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊。公司秉承以“開放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團(tuán)隊有機(jī)會用頭腦與智慧不斷的給客戶帶來驚喜。成都創(chuàng)新互聯(lián)推出平樂免費做網(wǎng)站回饋大家。

這里就不討論明文密碼的缺點了,只談?wù)勅绾伟踩谋4婷艽a。

基本的安全措施如下:

1.設(shè)置密碼最小位數(shù)

2.將用戶的密碼加密保存

3.通過重置密碼的一次性鏈接修改密碼

4.同一IP或mac地址一天內(nèi)只能獲取3次重置郵件

5.用戶修改密碼時需輸入原密碼

6.用戶信息被修改后發(fā)送短信/郵件提醒

當(dāng)然還可以采取更安全的措施:

7.不常用設(shè)備登陸需手機(jī)短信驗證(需要短信平臺)

8.設(shè)置安全問答信息

9.記錄錯誤登陸請求信息,多次錯誤后拒絕登陸嘗試

--------------------------------------------------------------------------

第一項:密碼的加密保存

通常情況下md5是最常用也是最簡單的,但也是破解方法最多的一種方法。

php 5.5及以上版本中提供了Password Hashing API, 非常方便的解決了密碼加密問題

http://tw2.php.net/manual/zh/ref.password.php

密碼加密

<?php
//$hash就是密碼加密后的字符串
$options = [
    'cost' => 10
    //'salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM), 不推薦手動設(shè)置鹽值
];
$hash = password_hash("123456", PASSWORD_BCRYPT, $options);
?>

注意手動設(shè)置鹽值在這里不被推薦,在php7里已經(jīng)廢掉這個選項。

password_hash中的第二個參數(shù)是對算法的設(shè)置,有兩個選項:

  1. 默認(rèn)為PASSWORD_DEFAULT,現(xiàn)在的算法為bcrypt, 但這個算法會隨著php版本的更新而更新更強(qiáng)的算法,建議數(shù)據(jù)庫字段設(shè)置為char(255)。

  2. PASSWORD_BCRYPT,算法也是bcrypt,(手冊上寫的CRYPT_BLOWFISH,其實就是crypt()使用CRYPT_BLOWFISH算法),結(jié)果永遠(yuǎn)是60個字符串,字段設(shè)置為char(60)即可。

簡單的說password_hash就是把bcrypt封裝了起來,而且會隨著以后版本的更新而改進(jìn)提升所使用的算法,就現(xiàn)階段來講,bcrypt已經(jīng)足夠安全了。

-------------------

順道解釋一下什么是 cost(消耗) 和 salt(鹽值)

cost:消耗--是用來對付暴力破解的,隨著計算機(jī)速度的不斷提升,我們可以讓一臺計算機(jī)幾十年不關(guān)機(jī)來破解一個密碼,所以我們?nèi)藶榈募由弦粋€消耗值,使計算機(jī)的算法變慢一點,當(dāng)然變慢的這一點對單次運算影響不大,但暴力破解時間就要延長到幾千上萬年了。

salt:鹽值--用于對付彩虹表(不知道自行百度一下),鹽值作為一個干擾項,使每次hash產(chǎn)生的密文均不相同,抵御彩虹表破解。

-------------------

密碼驗證

//$hash,從數(shù)據(jù)庫里讀取的加密字符串
if (password_verify('password', $hash)) {
    //驗證通過
} else {
    //驗證錯誤
}

檢查加密措施是否需要升級

//檢查hash是否由bcrypt加密,如果不是則需要升級,返回true
if (password_needs_rehash ($current_hash, PASSWORD_BCRYPT)) {
   $new_hash = password_hash($password, PASSWORD_BCRYPT)
}

獲取加密信息

password_get_info只能用于password_hash生成的hashing

-----------------------------------------------

如果你使用的是php5.5以下版本,可用以下方法(也是我現(xiàn)在使用的方法,原理上是一樣的)替代:

class Password {

    private static $algo = '$2a', $cost = '$10';
    
    public static function unique_salt() {

        return substr(sha1(mt_rand()),0,22);

    }

    public static function hash($password) {

        return crypt($password,
            self::$algo .
            self::$cost .
            '$' . self::unique_salt());

    }

    public static function check_password($hash, $password) {

        $full_salt = substr($hash, 0, 29);

        $new_hash = crypt($password, $full_salt);

        return ($hash === $new_hash);

    }
    
}

-------------------------

第二項:密碼的一次性的重置鏈接

一次性鏈接有這么兩特點:

  1. 在鏈接生成的一定時間內(nèi)(比如24小時)點擊有效

  2. 一旦密碼被重置,鏈接立即失效

既然這樣,就需要記錄鏈接的是否過期,有以下幾種思路:

  1. 數(shù)據(jù)庫中保存鏈接生成時間和鏈接是否已被使用(考慮用一個字段記錄信息)。

  2. 利用opcode緩存,需要安裝xcache或其他類似工具

我現(xiàn)在用的便是xcahce,主要考慮到保存到庫中會增加開銷。

public function generate_link($username,$hash){

        if (function_exists('xcache_isset')) {

            //將username加密作為我們的unique_id
            $unique_id = md5($username);
            
            //將username保存到名為unique_id的緩存中,設(shè)置緩存24小時候過期
            xcache_set($unique_id, $username, 24*60*60);
            
            //將username和hash加密作為驗證信息(不放心的話可以在加一個公匙在里面)
            $validate = md5($username.$hash);
            
            //拼接成字符串
            $string = $unique_id.$validate;

            //生成重置密碼的鏈接
            $link = $_SERVER['SERVER_NAME']."/reset-password?p=".$string;

            return $link;

        }

    }

//檢查鏈接是否合法
public function check_link($p){

        if (function_exists('xcache_isset')) {

            //獲取鏈接中的unique_id
            $unique_id = substr($p, 0, 32);

            if(xcache_isset($unique_id)){

                //通過unique_id讀取username
                $username = xcache_get($unique_id);
                
                //通過username讀取hash
                $hash = findHashByUsername($username);

                //獲取鏈接中的驗證信息
                $link_md5 = substr($p,32);

                if($link_md5 === md5($username.$hash)){

                    //鏈接驗證成功

                }else{

                    //鏈接驗證失敗
                    redirect();

                }


            }else{

                redirect();
            }

        }

    }

記住密碼重置后要立即清除$unique_id的緩存

if(updateLoginPassword($username,$password)){
     xcache_unset($unique_id);
}

第三項:設(shè)置同一IP一天內(nèi)的重置密碼次數(shù)限制

和一次性鏈接很像,也有兩種思路:

  1. 將ip存到數(shù)據(jù)庫

  2. 將ip信息通過xcache保存

我就只給大家提供一個獲取ip的函數(shù)了,其他的大家自己補(bǔ)充吧

public static function validip($ip) {
		if (!empty($ip) && ip2long($ip)!=-1) {
			$reserved_ips = array (
			array('0.0.0.0','2.255.255.255'),
			array('10.0.0.0','10.255.255.255'),
			array('127.0.0.0','127.255.255.255'),
			array('169.254.0.0','169.254.255.255'),
			array('172.16.0.0','172.31.255.255'),
			array('192.0.2.0','192.0.2.255'),
			array('192.168.0.0','192.168.255.255'),
			array('255.255.255.0','255.255.255.255')
			);
			foreach ($reserved_ips as $r) {
				$min = ip2long($r[0]);
				$max = ip2long($r[1]);
				if ((ip2long($ip) >= $min) && (ip2long($ip) <= $max)) return false;
			}
			return true;
		} else {
			return false;
		}
	}

public static function getip() {
        if (self::validip($_SERVER["HTTP_CLIENT_IP"])) {
            return $_SERVER["HTTP_CLIENT_IP"];
        }
        
        if(isset($_SERVER["HTTP_X_FORWARDED_FOR"])){
            foreach (explode(",",$_SERVER["HTTP_X_FORWARDED_FOR"]) as $ip) {
                if (self::validip(trim($ip))) {
                    return $ip;
                }
            }
        }
        
        $keys = array("HTTP_X_FORWARDED","HTTP_FORWARDED_FOR","HTTP_FORWARDED");
        
        foreach ($keys as $key){
            if (self::validip($_SERVER[$key])) {
                 return $_SERVER[$key];
            }
        }
        
        return $_SERVER["REMOTE_ADDR"];
   }

網(wǎng)頁名稱:php中密碼的加密處理及安全措施
本文URL:http://www.rwnh.cn/article28/jscecp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供營銷型網(wǎng)站建設(shè)微信公眾號、網(wǎng)站改版網(wǎng)站導(dǎo)航、App設(shè)計網(wǎng)站內(nèi)鏈

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站建設(shè)
高尔夫| 苗栗县| 曲阜市| 榕江县| 十堰市| 乌拉特前旗| 伽师县| 巧家县| 中西区| 观塘区| 霍城县| 沈丘县| 中方县| 潼南县| 信丰县| 红桥区| 潮州市| 汤原县| 潞城市| 耿马| 涟源市| 商都县| 大厂| 咸阳市| 武邑县| 壶关县| 江安县| 固阳县| 天津市| 贺州市| 望谟县| 靖西县| 澄迈县| 抚远县| 黑龙江省| 甘孜县| 中牟县| 茂名市| 普定县| 永兴县| 黔江区|