PHP的幾種加密算法

前言

PHP加密方式分為單項(xiàng)散列加密,對(duì)稱加密,非對(duì)稱加密這幾類。像常用的MD5、hash、crypt、sha1這種就是單項(xiàng)散列加密,單項(xiàng)散列加密是不可逆的。像URL編碼、base64編碼這種就是對(duì)稱加密,是可逆的,就是說加密解密都是用的同一秘鑰。除此外就是非對(duì)稱加密,加密和解密的秘鑰不是同一個(gè),如果從安全性而言,加密的信息如果還想著再解密回來,非對(duì)稱加密無疑是最為安全的方式。

MD5加密

md5加密算法在PHP中是最常見的加密算法,這個(gè)算法是不可逆的,通常用于加密用戶的密碼等信息來保證用戶的信息安全。來自 RFC 1321 的解釋 - MD5 報(bào)文摘要算法:MD5 報(bào)文摘要算法將任意長度的信息作為輸入值,并將其換算成一個(gè) 128 位長度的"指紋信息"或"報(bào)文摘要"值來代表這個(gè)輸入值,并以換算后的值作為結(jié)果。MD5 算法主要是為數(shù)字簽名應(yīng)用程序而設(shè)計(jì)的;在這個(gè)數(shù)字簽名應(yīng)用程序中,較大的文件將在加密(這里的加密過程是通過在一個(gè)密碼系統(tǒng)下[如:RSA]的公開密鑰下設(shè)置私有密鑰而完成的)之前以一種安全的方式進(jìn)行壓縮。好,來舉個(gè)例子

<?php

//這里是一個(gè)字符串

$str="this is zifuchuan";

//通過MD5加密函數(shù)加密

$res=md5($str);//在PHP中,MD5()函數(shù)還有第二個(gè)參數(shù),為bool類型,當(dāng)為TRUE是返回的加密是16字符原始//二進(jìn)制格式字符串,當(dāng)為FALSE是返回32位的16進(jìn)制,默認(rèn)為false,一般都默認(rèn)//返回二進(jìn)制

$res=md5($str,true);

?>

Crypt()加密算法

crypt()加密算法是一種不可逆的加密算法,他有兩個(gè)參數(shù),一個(gè)是需要加密的字符串,另外一個(gè)是鹽值(或者成為干擾字符串),如果沒有指定第二個(gè)參數(shù)那么將自己隨機(jī)生成一個(gè)干擾字符串并且是以MD5加密的方式。另外這個(gè)函數(shù)在不同的操作系統(tǒng)上的表現(xiàn)形式也是不一樣的,會(huì)自動(dòng)檢測。舉個(gè)例子。

<?php

//需要加密的字符串

$str="this is string";

//使用crypt加密,不指定鹽值

$res=crypt($str);//指定鹽值,但是鹽值只能寫兩位,如果超過了則只會(huì)取前兩位,在某些系統(tǒng)中會(huì)直接返回FALSE

$res=crypt($str,'jm');

?>

sha1加密算法

sha1加密算法和MD5加密算法一樣時(shí)不可逆的,有兩個(gè)參數(shù),一個(gè)是要加密的字符串,第二個(gè)是bool值,如果指定第二個(gè)參數(shù)為TRUE,則返回二進(jìn)制格式的字符串,如果不指定則默認(rèn)為FALSE,返回的是40位的16進(jìn)制格式的字符串,舉個(gè)例子

<?php

//需要加密的字符串

$str="this is string";

//通過sha1進(jìn)行加密

$res=sha1($str);

//通過指定第二個(gè)參數(shù)加密

$res=sha1($str,true);

?>

URL編碼加密

對(duì)于我們的網(wǎng)站,直接暴露給用戶的就是地址欄的傳參,對(duì)于這一部分都是明文的,所以我們可以使用基本的加密算法來簡單加密一下,注意,此種方式加密是可逆的,也就是說加密后的密文我們可以解密之后看到,所以如果你想實(shí)現(xiàn)真正的加密,并不推薦這個(gè)加密算法。

在PHP中對(duì)于URL加密解密用到兩個(gè)函數(shù)urlencode和urldecode.

http://www.guojiadong.com?name=guojiadong&amp;amp;phone=112

我們就可以對(duì)這段地址進(jìn)行加密

<?php

//需要加密的網(wǎng)址

$str = "http://www.guojiadong.com?name=guojiadong&phone=112";

//使用urlencode加密

$res = urlencode($str);

//使用urldecode解密

$result = urldecode($res);

?>

既然通過這種方式加密解密并且加密之后也并沒有什么太大的區(qū)別,我們需要他的目的是什么呢?我們想對(duì)于想破解這串加密的字符串可以輕松的破解,其實(shí)這兩個(gè)函數(shù)有他特殊的作用,也就是說除了加密的作用,當(dāng)然了這是題外話,因?yàn)楸局黝}主要是加密,但是作為擴(kuò)展還是要說一下。

<?php

//在HTML傳參到后臺(tái)中的時(shí)候如果我們想把&作為參數(shù)傳到后臺(tái),在沒有加密之前,瀏覽器會(huì)把他作為

//參數(shù)分隔符

//例如:http://guojiadong.com?name=guojiadong&amp;123,

我們想把guojiadong&amp;123作為參數(shù)傳給

//后臺(tái),這個(gè)時(shí)候直接這樣寫后臺(tái)得到的數(shù)據(jù)卻只得到name的值為guojiadong,而123確作為變量

//當(dāng)然了用一個(gè)數(shù)字做變量是不合法的,但是瀏覽器確并不這么智能的區(qū)分他

//為了解決這個(gè)問題我們就可以對(duì)這部分字符編碼

$str="http://guojiadong.com?name=".urlencode('guojiadong&123');

//這樣我們傳過來的值就變成了name = guojiadong&123

?>

Base64編碼加密

大家注意,雖然base64寫到本節(jié)加密算法中,但是他并不是主要用來加密的,而且從大多數(shù)的程序來說,幾乎沒有人會(huì)用他作為加密手段來加密數(shù)據(jù),那么他的作用主要是用于做什么呢?這要說的base64加密的機(jī)制了。

base64加密本質(zhì)上說就是把數(shù)據(jù)轉(zhuǎn)換為ASCLL碼,比如一個(gè)圖片進(jìn)行base64編碼就會(huì)變成一堆以Ascll碼連接的字符串,這會(huì)更有利于文件的傳輸,當(dāng)然base64的作用在與文件的傳輸。例如手機(jī)客戶端上傳文件到服務(wù)器,使用base64編碼可以輕松實(shí)現(xiàn)文件的傳輸。

base64加密函數(shù)

base64_encode($data);

base64解密函數(shù)

base64_decode($data);

hash加密

hash加密也是不可逆的,因?yàn)槭墙o定一個(gè)不確定的字符串返回特定長度的字符串,這個(gè)本質(zhì)意義上來說實(shí)現(xiàn)了單項(xiàng)散列加密。使用方法

hash($ago,$data);

$ago是可以指定加密使用的哈希算法,例如:"md5","sha256","haval160,4" 等。

$data是要加密的數(shù)據(jù)

Password Hashing API 加密

Password Hashing API是PHP 5.5之后才有的新特性,它主要是提供下面幾個(gè)函數(shù)供我們使用:

password_hash() – 對(duì)密碼加密.

password_verify() – 驗(yàn)證已經(jīng)加密的密碼,檢驗(yàn)其hash字串是否一致.

password_needs_rehash() – 給密碼重新加密.

password_get_info() – 返回加密算法的名稱和一些相關(guān)信息.

雖然說crypt()函數(shù)在使用上已足夠,但是password_hash()不僅可以使我們的代碼更加簡短,而且還在安全方面給了我們更好的保障,所以,現(xiàn)在PHP的官方都是推薦這種方式來加密用戶的密碼,很多流行的框架比如Laravel就是用的這種加密方式。

$hash = password_hash($passwod, PASSWORD_DEFAULT);

對(duì),就是這么簡單,一行代碼,All done。

PASSWORD_DEFAULT目前使用的就是Bcrypt,所以在上面我會(huì)說推薦這個(gè),不過因?yàn)镻assword Hashing API做得更好了,我必須鄭重地想你推薦Password Hashing API。這里需要注意的是,如果你代碼使用的都是PASSWORD_DEFAULT加密方式,那么在數(shù)據(jù)庫的表中,password字段就得設(shè)置超過60個(gè)字符長度,你也可以使用PASSWORD_BCRYPT,這個(gè)時(shí)候,加密后字串總是60個(gè)字符長度。

這里使用password_hash()你完全可以不提供鹽值(salt)和 消耗值 (cost),你可以將后者理解為一種性能的消耗值,cost越大,加密算法越復(fù)雜,消耗的內(nèi)存也就越大。當(dāng)然,如果你需要指定對(duì)應(yīng)的鹽值和消耗值,你可以這樣寫:

$options = [

'salt' => custom_function_for_salt(), //write your own code to generate a suitable salt

'cost' => 12 // the default cost is 10 ];

$hash = password_hash($password, PASSWORD_DEFAULT, $options);

密碼加密過后,我們需要對(duì)密碼進(jìn)行驗(yàn)證,以此來判斷用戶輸入的密碼是否正確:

if (password_verify($password, $hash)) {

// Pass }

else {

// Invalid

}

很簡單的吧,直接使用password_verify就可以對(duì)我們之前加密過的字符串(存在數(shù)據(jù)庫中)進(jìn)行驗(yàn)證了。

然而,如果有時(shí)候我們需要更改我們的加密方式,如某一天我們突然想更換一下鹽值或者提高一下消耗值,我們這時(shí)候就要使用到password_needs_rehash()函數(shù)了:

if (password_needs_rehash($hash, PASSWORD_DEFAULT, ['cost' => 12])) {

// cost change to 12 $hash = password_hash($password, PASSWORD_DEFAULT, ['cost' => 12]);

// don't forget to store the new hash!

}

只有這樣,PHP的Password Hashing API才會(huì)知道我們重現(xiàn)更換了加密方式,這樣的主要目的就是為了后面的密碼驗(yàn)證。

簡單地說一下password_get_info(),這個(gè)函數(shù)一般可以看到下面三個(gè)信息:

algo – 算法實(shí)例

algoName – 算法名字

options – 加密時(shí)候的可選參數(shù)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. 對(duì)稱加密 對(duì)稱加密指的就是加密和解密使用同一個(gè)秘鑰,所以叫做對(duì)稱加密。對(duì)稱加密只有一個(gè)秘鑰,作為私鑰。 常見...
    愛學(xué)習(xí)的小仙女呀閱讀 1,270評(píng)論 0 3
  • 概述 之前一直對(duì)加密相關(guān)的算法知之甚少,只知道類似DES、RSA等加密算法能對(duì)數(shù)據(jù)傳輸進(jìn)行加密,且各種加密算法各有...
    Henryzhu閱讀 3,214評(píng)論 0 14
  • 作者/上善若水 1.md5(string $str,bool $flag = false); $flag = fa...
    渴望碩壯的成熟閱讀 4,182評(píng)論 2 7
  • 首先羅列一些知識(shí)點(diǎn): 1.加密算法通常分為對(duì)稱性加密算法和非對(duì)稱性加密算法:對(duì)于對(duì)稱性加密算法,信息接收雙方都需事...
    JonesCxy閱讀 1,572評(píng)論 2 4
  • “30分廚娘”,給自己的這個(gè)“愛稱”,是有感于我很欣賞的繪本作家高木直子的作品《30分老媽》。(注意:本文末有驚j...
    我是吹西西閱讀 486評(píng)論 0 1

友情鏈接更多精彩內(nèi)容