PHP安全編程之加密功能_PHP教程
Jul 21, 2016 pm 04:09 PM
資料加密在我們生活中的地位已經(jīng)越來越重要了,尤其是考慮到在網(wǎng)路上發(fā)生的大量交易和傳輸?shù)拇罅抠Y料。如果對於採用安全措施有興趣的話,也一定會有興趣了解PHP提供的一系列安全功能。在本篇文章中,我們將介紹這些功能,提供一些基本的用法,讓你能為自己的應(yīng)用軟體中增加安全功能。
預(yù)備知識
在詳細(xì)介紹PHP的安全功能之前,我們需要花點(diǎn)時(shí)間來向沒有接觸過這方面內(nèi)容的讀者介紹一些有關(guān)密碼學(xué)的基本知識,如果對密碼學(xué)的基本概念已經(jīng)非常熟悉,就可以跳過去這一部分。
密碼學(xué)可以通俗地被描述為對加/解密的研究和實(shí)驗(yàn),加密是將易懂的資料轉(zhuǎn)換為不易懂資料的過程,解密則是將不易懂的資料轉(zhuǎn)換為原來易懂資料的過程。不易懂的資料被稱作密碼,易懂的資料被稱作明碼。
資料的加/解密都需要一定的演算法,這些演算法可以非常簡單,例如著名的凱撒碼,但目前的加密演算法要相對複雜得多,其中一些利用現(xiàn)有的方法甚至是無法破解的。
PHP的加密功能
只要有一點(diǎn)使用非Windows平臺經(jīng)驗(yàn)的人可能對crypt()也相當(dāng)熟悉,這一函數(shù)完成被稱作單向加密的功能,它可以加密一些明碼,但不能夠?qū)⒚艽a轉(zhuǎn)換為原來的明碼。儘管從表面上來看這似乎是一個(gè)沒有什麼用處的功能,但它的確被廣泛用來保證系統(tǒng)密碼的完整性。因?yàn)?,單向加密的口令一旦落入第三方人的手裡,由於不能被還原為明文,因此也沒有什麼大用處。在驗(yàn)證使用者輸入的口令時(shí),使用者的輸入採用的也是單向演算法,如果輸入與儲存的經(jīng)加密後的口令相匹配,則輸入的口信一定是正確的。
PHP同樣提供了使用其crypt()函數(shù)完成單向加密功能的可能性。我將在這裡簡要地介紹該函數(shù): string crypt (string input_string [, string salt])
其中的input_string參數(shù)是需要加密的字串,第二個(gè)可選的salt是一個(gè)位元字符串,它能夠影響加密的暗碼,進(jìn)一步地排除被稱作預(yù)計(jì)算攻擊的可能性。預(yù)設(shè)情況下,PHP使用一個(gè)2個(gè)字元的DES幹?jǐn)_串,如果你的系統(tǒng)使用的是MD5(我以後會介紹MD5演算法),它會使用一個(gè)12個(gè)字元的干擾串。順便說一下,可以透過執(zhí)行下面的指令來發(fā)現(xiàn)系統(tǒng)將要使用的干擾串的長度: print "My system salt size is: ". CRYPT_SALT_LENGTH;
系統(tǒng)也可能支援其他的加密演算法。 crypt()支援四種演算法,以下是它支援的演算法和對應(yīng)的salt參數(shù)的長度:
演算法
Salt長度
CRYPT_STD_DES
2-character (Default)
CRYPT_EXT_DES
9-character
CRYPT_MD5
12-character beginning with 102/td>
CRYPT_BLOWFISH
16-character beginning with 102/td>
用crypt()實(shí)現(xiàn)用戶身份驗(yàn)證
作為crypt()函數(shù)的一個(gè)例子,考慮這樣一種情況,你希望創(chuàng)建一段PHP腳本程序限制對一個(gè)目錄的訪問,只允許能夠提供正確的用戶名和口令的用戶訪問這一目錄。我將把資料儲存在我喜歡的資料庫MySQL的一個(gè)表中。下面我們以建立這個(gè)被稱為members的表格開始我們的例子:
mysql>CREATE TABLE members (
??? ->username CHAR(14) NOT NULL,
??? ->password CHAR(32) NOT NULL,
??? ->PRIMARMARYo>
然後,我們假定下面的資料已經(jīng)儲存在該表中:
使用者名稱
密碼
clark
keloD1C377lKE
bruce
ba1T7vnz9AWgk
peter
paLUvRWsRLZ4U
這些加密的口令對應(yīng)的明碼分別是kent、banner和parker。注意每個(gè)口令的前二個(gè)字母,這是因?yàn)槲沂褂昧讼旅娴拇a,根據(jù)口令的前二個(gè)字母創(chuàng)建幹?jǐn)_串的:
.
= substr(, 0, 2);
= crypt(, );
// 然後就和使用者名稱一起儲存在MySQL中
我將使用Apache的口令-應(yīng)答認(rèn)證配置提示用戶輸入用戶名和口令,一個(gè)鮮為人知的有關(guān)PHP的信息是,它可以把Apache的口令-應(yīng)答系統(tǒng)輸入的用戶名和口令識別為和,我將在身份驗(yàn)證腳本中用到這二個(gè)變數(shù)。花一些時(shí)間仔細(xì)閱讀下面的腳本,多注意其中的解釋,以便更好地理解下面的程式碼:
crypt()和Apache的口令-應(yīng)答驗(yàn)證系統(tǒng)的應(yīng)用
= "localhost";
= "zorro";
= "hellodolly";
= "users";
// Set authorization to False
= 0;
// Verify that user has entered username and password
if (isset() && isset()) :
, , ) or die("Can't connect to MySQL
server!");
mysql_select_db() or die("Can't select database!");
/ / Perform the encryption
= substr(, 0, 2);
= crypt(, );
// Build the query
= "SELECT username FROMk. W ??>username = '' AND
password = ''";
// Execute the query
if (mysql_numrows(mysql_query()) == 1) :
= 1;
endif;
endif;
// confirm authorization
if (! ) :
header('WWWic-Authenticetic realm="Private"');
header('HTTP/1.0 401 Unauthorized');
print "You are unauthorized to enter this area.";
exit;
else :
print "This is the secret data!";
endif;
?>
上面就是一個(gè)核實(shí)使用者存取權(quán)限的簡單身份驗(yàn)證系統(tǒng)。在使用crypt()保護(hù)重要的機(jī)密資料時(shí),記住在缺省狀態(tài)下使用的crypt()並不是最安全的,只能用在對安全性要求較低的系統(tǒng)中,如果需要較高的安全性能,就需要我在本篇文章的後面介紹的演算法。
以下我將介紹另一個(gè)PHP支援的函數(shù)━━md5(),這函數(shù)使用MD5雜湊演算法,它有幾種很有趣的用法值得一提:
混編
一個(gè)混編函數(shù)可以將一個(gè)可變長度的資訊轉(zhuǎn)換為具有固定長度被混編過的輸出,也被稱為「資訊文摘」。這是十分有用的,因?yàn)橐粋€(gè)固定長度的字串可以用來檢查檔案的完整性和驗(yàn)證數(shù)位簽章以及使用者身份驗(yàn)證。由於它適合PHP,PHP內(nèi)建的md5()混編函數(shù)將把一個(gè)可變長度的資訊轉(zhuǎn)換為128位元(32個(gè)字元)的資訊摘要?;炀幍囊粋€(gè)有趣的特點(diǎn)是不能透過分析混編後的資訊得到原來的明碼,因?yàn)榛炀庒岬慕Y(jié)果與原來的明碼內(nèi)容沒有依賴關(guān)係。 即便只改變一個(gè)字串中的一個(gè)字符,也將使得MD5混編演算法計(jì)算出二個(gè)截然不同的結(jié)果。我們首先來看下表的內(nèi)容及其對應(yīng)的結(jié)果:
使用md5()混編字串
= "This is some message that I just wrote";
= md5();
print "hash: ";
?>
結(jié)果:hash: 81ea092649ca32b5ba375e81d8f4972c
注意,結(jié)果的長度為32個(gè)字元。再來看一下下面的表,其中的值有了一點(diǎn)微小的變化:
使用md5()對一個(gè)稍微變化的字串進(jìn)行混編
//注意,message中少了一個(gè)s
= "This is some mesage that I just wrote";
= md5();
print "hash2:
";
?>
結(jié)果:hash2: e86cf511bd5490d46d5cd61738c82c0c
可以發(fā)現(xiàn),儘管二個(gè)結(jié)果的長度都是32個(gè)字符,但明文中一點(diǎn)微小的變化使得結(jié)果發(fā)生了很大的變化,因此,混編和md5()函數(shù)是檢查數(shù)據(jù)中微小變化的一個(gè)很好的工具。
儘管crypt()和md5()各有用處,但二者在功能上都受到一定的限制。在下面的部分中,我們將介紹二個(gè)非常有用的被稱為Mcrypt和Mhash的PHP擴(kuò)展,將大大拓展PHP用戶在加密方面的選擇。
儘管我們在上面的小節(jié)中說明了單向加密的重要性,但有時(shí)我們可能需要在加密後,再把密碼數(shù)據(jù)還原成原來的數(shù)據(jù),幸運(yùn)的是,PHP透過Mcrypt擴(kuò)展庫的形式提供了這種可能性。
Mcrypt
Mcrypt 2.5.7 Unix | Win32
Mcrypt 2.4.7是一個(gè)功能強(qiáng)大的加密演算法擴(kuò)充庫,它包含有22種演算法,其中就包含下面的幾種演算法:
Blowfish RC2 Safer-sk64 xtea
Cast-256 RC4 Safer-sk128
DES RC4-iv Serpent
Enigma Rijndael-128 Threeway
Gost Rijndael-192 TripleDES
LOKI97 Rijndael-256 Twofish
PanamaSaferplus Wake
安裝:
在標(biāo)準(zhǔn)的PHP軟體包中不包括Mcrypt,因此需要下載它,下載的地址為:ftp://argeas.cs-net.gr/pub/unix/mcrypt/。下載後,按照下面的方法進(jìn)行編譯,並將它擴(kuò)充在PHP中:
下載Mcrypt軟體包。
gunzipmcrypt-x.x.x.tar.gz
tar -xvfmcrypt-x.x.x.tar
./configure --disable-posix-threads
make
make install
cd to your PHP directory.
./configure -with-mcrypt=[dir] [--other-configuration-directives]
make
make install
當(dāng)然了,根據(jù)你的要求和PHP安裝時(shí)與互聯(lián)網(wǎng)伺服器軟體的關(guān)係,上面的過程可能需要適當(dāng)?shù)男薷摹?使用Mcrypt
Mcrypt的優(yōu)點(diǎn)不僅在於其提供的加密演算法較多,還在於它可以對資料進(jìn)行加/解密處理,此外,它還提供了35種處理資料用的函數(shù)。儘管對這些函數(shù)進(jìn)行詳細(xì)介紹已經(jīng)超出了這篇文章的範(fàn)圍,我還是要就幾個(gè)典型的函數(shù)作一下簡要的介紹。
首先,我將介紹如何使用Mcrypt擴(kuò)充函式庫對資料進(jìn)行加密,然後再介紹如何使用它進(jìn)行解密。下面的程式碼對這一過程進(jìn)行了演示,首先是對數(shù)據(jù)進(jìn)行加密,然後在瀏覽器上顯示加密後的數(shù)據(jù),並將加密後的數(shù)據(jù)還原為原來的字串,將它顯示在瀏覽器上。
使用Mcrypt對資料進(jìn)行加、解密
// Designate string to be encrypted
= "Applied Cryptography, by Bruce Schneier, is
a wonderful cryptography reference.";
key
key = "Four score and twenty years ago";
// Encryption Algorithm
= MCRYPT_RIJNDAEL_128;
/// Create the initiEL_128;
/// Create the initiatation v. = mcrypt_create_iv(mcrypt_get_iv_size(,
MCRYPT_MODE_ECB), MCRYPT_RAND);
// Output original string
print "Original string
; >= mcrypt_encrypt(, key,
, MCRYPT_MODE_CBC, );
// Convert to hexadecimal and output to browser
print "Encrypted string: ".bin2
= mcrypt_decrypt(, key,
, MCRYPT_MODE_CBC, );
print "Decrypted string: ";
?>>
執(zhí)行上面的腳本將會產(chǎn)生下面的輸出:
Original string: Applied Cryptography, by Bruce Schneier, is a wonderful cryptography reference.
Encrypted string: 02a7c58b1ebd22a9523468694b091e60411cc4dea8652bb8072 34fa06bbfb20e71ecf525f29df58e28f3d954120e71ecf525f29df58e28f3d954157 8c11742f5cfa1d23fe22fe8 bfbab5e
Decrypted string: Applied Cryptography, by Bruce Schneier, is a wonderful cryptography reference.
上面的程式碼中二個(gè)最典型的函數(shù)是mcrypt_encrypt()和mcrypt_decrypt(),它們的用途是顯而易見的。我使用了「電報(bào)密碼本」模式,Mcrypt提供了幾種加密方式,由於每種加密方式都有可以影響密碼安全的特定字符,因此每種模式都需要了解。對於沒有接觸過密碼系統(tǒng)的讀者來說,可能對mcrypt_create_iv()函數(shù)更有興趣,儘管對這一函數(shù)進(jìn)行徹底的解釋已經(jīng)超出了本篇文章的範(fàn)圍,但我仍然會提到它創(chuàng)建的初始化向量(hence, iv),此向量可以使每個(gè)訊息彼此獨(dú)立。儘管不是所有的模式都需要這一初始化變量,但如果在要求的模式中沒有提供此變量,PHP就會給出警告訊息。
Mhash擴(kuò)充庫
http://sourceforge.net/projects/mhash/
0.8.3版的Mhash擴(kuò)充函式庫支援12種混編演算法,仔細(xì)檢查Mhash v.0.8.3的頭檔mhash.h可以知道,它支援下面的混編演算法:
CRC32 HAVAL160 MD5
CRC32B HAVAL192 RIPEMD160
GOST HAVAL224 SHA1
HAVAL128 HAVAL256 TIGER
安裝
象Mcrypt一樣,Mhash也沒有包括在PHP軟體包中,對於非Windows用戶而言,以下是安裝過程:
下載Mhash擴(kuò)充函式庫
gunzipmhash-x.x.x.tar.gz
tar -xvfmhash-x.x.x.tar
./configure
make
make install
cd
= "These are the directions to the secret fort. Two steps left, three steps right, and cha chacha.";
= mhash(, );
print
print
print
print
print

熱AI工具

Undress AI Tool
免費(fèi)脫衣圖片

Undresser.AI Undress
人工智慧驅(qū)動的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費(fèi)的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費(fèi)的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強(qiáng)大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6
視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

std::chrono在C 中用於處理時(shí)間,包括獲取當(dāng)前時(shí)間、測量執(zhí)行時(shí)間、操作時(shí)間點(diǎn)與持續(xù)時(shí)間及格式化解析時(shí)間。 1.獲取當(dāng)前時(shí)間使用std::chrono::system_clock::now(),可轉(zhuǎn)換為可讀字符串但係統(tǒng)時(shí)鐘可能不單調(diào);2.測量執(zhí)行時(shí)間應(yīng)使用std::chrono::steady_clock以確保單調(diào)性,並通過duration_cast轉(zhuǎn)換為毫秒、秒等單位;3.時(shí)間點(diǎn)(time_point)和持續(xù)時(shí)間(duration)可相互操作,但需注意單位兼容性和時(shí)鐘紀(jì)元(epoch)

toAccessenvironmentVariablesInphp,useGetenv()或$ _envsuperglobal.1.getEnv('var_name')retievesSpecificvariable.2。 $ _ en v ['var_name'] accessesvariablesifvariables_orderInphp.iniincludes“ e” .setVariablesViaCliWithvar = vualitephpscript.php,inapach

PHPhasthreecommentstyles://,#forsingle-lineand/.../formulti-line.Usecommentstoexplainwhycodeexists,notwhatitdoes.MarkTODO/FIXMEitemsanddisablecodetemporarilyduringdebugging.Avoidover-commentingsimplelogic.Writeconcise,grammaticallycorrectcommentsandu

在PHP中判斷字符串是否以特定字符串開頭可通過多種方法實(shí)現(xiàn):1.使用strncmp()比較前n個(gè)字符,若返回0則開頭匹配,不區(qū)分大小寫;2.使用strpos()檢查子字符串位置是否為0,區(qū)分大小寫,可用stripos()替代實(shí)現(xiàn)不區(qū)分大小寫;3.可封裝startsWith()或str_starts_with()函數(shù)提高複用性;此外需注意空字符串默認(rèn)返回true、編碼兼容性及性能差異,strncmp()通常效率更高。

避免“undefinedindex”錯誤的關(guān)鍵方法有三:首先,使用isset()檢查數(shù)組鍵是否存在並確保值不為null,適用於大多數(shù)常規(guī)場景;其次,使用array_key_exists()僅判斷鍵是否存在,適用於需要區(qū)分鍵不存在和值為null的情況;最後,使用空合併運(yùn)算符??(PHP7 )簡潔地設(shè)置默認(rèn)值,推薦用於現(xiàn)代PHP項(xiàng)目,同時(shí)注意表單字段名拼寫、謹(jǐn)慎使用extract()及遍歷前檢查數(shù)組非空以進(jìn)一步規(guī)避風(fēng)險(xiǎn)。

使用PHP預(yù)處理語句執(zhí)行帶有IN子句的查詢時(shí),1.需根據(jù)數(shù)組長度動態(tài)生成佔(zhàn)位符;2.使用PDO時(shí)可直接傳入數(shù)組,用array_values確保索引連續(xù);3.使用mysqli時(shí)需構(gòu)造類型字符串並綁定參數(shù),注意展開數(shù)組的方式及版本兼容性;4.避免拼接SQL、處理空數(shù)組和確保數(shù)據(jù)類型匹配。具體做法是:先用implode與array_fill生成佔(zhàn)位符,再依擴(kuò)展特性綁定參數(shù),從而安全執(zhí)行IN查詢。

安裝PHP在Windows上的關(guān)鍵步驟包括:1.下載合適的PHP版本並解壓,推薦使用ThreadSafe版本配合Apache或NonThreadSafe版本配合Nginx;2.配置php.ini文件,將php.ini-development或php.ini-production重命名為php.ini;3.將PHP路徑添加到系統(tǒng)環(huán)境變量Path中以便命令行使用;4.測試PHP是否安裝成功,通過命令行執(zhí)行php-v和運(yùn)行內(nèi)置服務(wù)器測試解析能力;5.若使用Apache,需在httpd.conf中配置P

PHP的基礎(chǔ)語法包括四個(gè)關(guān)鍵點(diǎn):1.PHP標(biāo)籤必須使用結(jié)束,推薦使用完整標(biāo)籤;2.輸出內(nèi)容常用echo和print,其中echo支持多參數(shù)且效率更高;3.註釋方式有//、#和//,用於提升代碼可讀性;4.每條語句必須以分號結(jié)尾,空格和換行不影響執(zhí)行但影響可讀性。掌握這些基本規(guī)則有助於寫出清晰穩(wěn)定的PHP代碼。
