王小潔
(山西職業(yè)技術(shù)學(xué)院,山西 太原 030006)
信息時(shí)代網(wǎng)絡(luò)數(shù)據(jù)的安全傳輸是大家非常關(guān)心的問題,各個(gè)網(wǎng)站的用戶資料更是信息保護(hù)的焦點(diǎn),在網(wǎng)站開發(fā)技術(shù)日趨成熟完善的過程中,黑客等不法分子乘虛而入,對一些重要網(wǎng)站,比如用戶數(shù)據(jù)最為重要的電商等相關(guān)領(lǐng)域網(wǎng)站進(jìn)行攻擊,盜取網(wǎng)站用戶的密碼集,致使許多網(wǎng)民隱私泄露,安全受到極大威脅,這種不安全事件給WEB應(yīng)用程序開發(fā)人員敲響了警鐘,對網(wǎng)站注冊用戶的賬號及密碼一定要使用穩(wěn)定成熟的加密算法進(jìn)行加密保護(hù),使不法分子無機(jī)可乘,還網(wǎng)民一個(gè)放心、安全、綠色的網(wǎng)絡(luò)環(huán)境。
PHP是當(dāng)今被廣泛使用的web開發(fā)語言之一,因其具有源代碼開放、可嵌入到HTML中、執(zhí)行效率高等特點(diǎn),備受業(yè)界人士青睞,市場占比也明顯上升。本文針對PHP用戶登錄信息傳輸特點(diǎn),分析RSA算法優(yōu)勢,闡述了如何實(shí)現(xiàn)基于RSA算對用戶信息進(jìn)行加密,以期對從事PHP項(xiàng)目開發(fā)的人員提供交流借鑒。
用戶與網(wǎng)站的交互是通過表單進(jìn)行的,用戶在客戶端瀏覽器表單中輸入的登錄信息一般通過POST方法或GET方法傳回服務(wù)器。當(dāng)采用GET方法傳遞數(shù)據(jù)時(shí),PHP把表單中的變量名和值附加到action屬性指定的URL之后,與URL使用分號分隔,一起顯示在瀏覽器的地址欄中。如下面的代碼段:
當(dāng)用戶輸入用戶名“user1”、密碼“123456”后單擊“提交”按鈕時(shí),瀏覽器地址欄將出現(xiàn)下面的內(nèi)容:
http://localhost/login.php?user-name=user1&password=123456
當(dāng)表單數(shù)據(jù)使用POST方法傳遞時(shí),用戶輸入的內(nèi)容不會(huì)出現(xiàn)在地址欄中,使得傳輸相對安全一些,并且也能傳輸更多的數(shù)據(jù)內(nèi)容,兩者加密過程相同,本文代碼以POST傳輸方式為例,對傳輸數(shù)據(jù)進(jìn)行加密設(shè)計(jì)。
RSA算法是一種極具影響力的非對稱加密算法,已被ISO推薦為公鑰數(shù)據(jù)加密標(biāo)準(zhǔn),是迄今被研究最廣泛的公鑰算法,被普遍認(rèn)為是最優(yōu)秀的公鑰方案之一。從誕生至今經(jīng)歷了各種攻擊考驗(yàn),迄今沒有出現(xiàn)任何可靠的破解該算法的方式,只要鑰匙的長度足夠長,用RSA加密的信息實(shí)際上是很難被破解的,加之該算法易于理解和操作,被業(yè)界人士廣泛使用[1]。
RSA算法需產(chǎn)生兩個(gè)密鑰:公鑰(publickey)和私鑰(privatekey)。公鑰與私鑰不一致且必須成對出現(xiàn),其中一個(gè)密鑰用來加密,對應(yīng)的另一個(gè)密鑰用來解密,一般習(xí)慣使用公鑰加密私鑰解密。
公鑰和私鑰常用openssl命令行生成,這種操作比較復(fù)雜。在此推薦可以提供在線生成RSA密鑰對的工具,該工具可以提供pkcs#1格式及pkcs#8格式的密鑰對。生成密鑰位數(shù)可以是512位(bit)、1024位(bit)、2048位(bit)、4096位(bit)四種, 其網(wǎng)址為http://web.chacuo.net/netrsakeypair,一般在程序設(shè)計(jì)中,生成密鑰位數(shù)可選擇“1024位(bit)”,密鑰格式可選擇“pkcs#8格式”。
openssl模塊使用相關(guān)函數(shù)來生成證書及加密解密數(shù)據(jù)。首先查看該模塊是否已經(jīng)開啟,查看的方法是在php程序中執(zhí)行“phpinfo();”語句,或在phpstudy等工具中單擊“查看phpinfo”,查找“openssl”,如果有則無需再做操作,如果沒有就需要啟用該模塊。啟用方法是打開php.ini配置文件,在文中查找“openssl”,刪除“extension=php-openssl.dll”之前的分號,保存配置文件即可。
到鏈接地址http://web.chacuo.net/netrsakeypair打開網(wǎng)站,單擊“生成密鑰對(RSA)”按鈕,就會(huì)生成一對唯一的密鑰,每單擊一次該按鈕,就會(huì)生成不同的密鑰對。
復(fù)制生成的公鑰及私鑰,在程序中分別保存為兩個(gè)常量,框架代碼如下:
<?php
define("RSA-public","-----BEGIN PUBLIC KEY-----
。。。
-----END PUBLIC KEY-----
");
define("RSA-private","-----BEGIN PRIVATE KEY-----
。。。
-----END PRIVATE KEY-----");
?>
由于生產(chǎn)的密鑰比較長,為增加程序可讀性,將此段代碼保存成一個(gè)文件,如“config.php”,方便后續(xù)在主程序中使用require命令包含此代碼段。
編寫加密解密函數(shù)方便后續(xù)程序調(diào)用,此處函數(shù)名命名為RSA-Openssl,該函數(shù)應(yīng)有兩個(gè)參數(shù),一個(gè)是加密或解密的串,一個(gè)是決定加密還是解密操作。此處當(dāng)$type=′encode′為加密操作,當(dāng)$type==′decode′時(shí)為解密操作。
若進(jìn)行加密操作,則首先檢查生成的公鑰,并使用公鑰加密數(shù)據(jù)。使用openssl-pkey-get-public()函數(shù)檢查生成的公鑰是否可用。如果不可用,檢查是否密鑰復(fù)制操作有誤;如果可用,再使用openssl-public-encrypt()函數(shù)對需要加密的數(shù)據(jù)進(jìn)行加密,代碼如下:
if ($type=='encode') {
$return=openssl-pkey-get-public(RSA-public);//檢查公鑰是否可用
if(!$return){
die("公鑰不可用");
}
openssl-public-encrypt($data,$crypted,$return);//使用公鑰加密數(shù)據(jù)
$crypted=base64-encode($crypted);
return $crypted;
}
代碼中為防止運(yùn)行結(jié)果出現(xiàn)亂碼,所以使用了base64-encode()函數(shù)對擬加密的數(shù)據(jù)進(jìn)行MIME base64編碼[2]?!鏲rypted為使用公鑰加密后的加密串。
若進(jìn)行解密操作,則先使用openssl-pkey-get-private(key)函數(shù)檢查生成的私鑰是否可用,其中參數(shù)key為使用公鑰加密過的加密串。如果不可用,檢查是否密鑰在復(fù)制操作過程中有誤;如果可用,則使用openssl-private-decrypt()函數(shù)對加密過進(jìn)行解密,代碼如下:
if ($type=='decode') {
$private-is-use=openssl-pkey-get-private(RSA-private);//檢查私鑰是否可用
if(!$private-is-use){
die("私鑰不可用");
}
//對私鑰進(jìn)行解密
openssl-private-decrypt(base64-decode($data),$decrypted,$private-is-use);
return($decrypted);
}
上述代碼段中,參數(shù)RSA-private是私鑰。$crypted為加密串,因?yàn)橹笆褂胋ase64-encode()函數(shù)進(jìn)行過處理,所以此時(shí)要用base64-decode()函數(shù)進(jìn)行反處理,否則解密時(shí)輸出“NULL”。參數(shù)$decrypted是解密后的結(jié)果。
使用HTML設(shè)計(jì)交互表單,以方便用戶輸入其用戶名及密碼,比如用于輸入用戶名文本框的id="user-name",密碼框的id="password",提交按鈕的id="sub",之后單擊“提交”按鈕向服務(wù)器提交用戶信息。
為使用JSON技術(shù)及JQuery中的Ajax技術(shù),需要從相關(guān)網(wǎng)站下載或克隆“jsencrypt.min.js”文件及“jquery-2.1.4.min.js”文件,存儲(chǔ)在項(xiàng)目文件夾中,并使用下面的代碼引入程序中[3]:
編寫對參數(shù)為string的字符串進(jìn)行加密的函數(shù)RSA-Openssl,以備在提交按鈕的單擊事件中調(diào)用。核心代碼如下:
function RSA-Openssl(string)
{var encrypt=new JSEncrypt();
encrypt.setPublicKey(′。。?!?;//參數(shù)為公鑰
var encrypted=encrypt.encrypt(string);//參數(shù)為擬加密的串
return encrypted; }
編寫“提交”按鈕的單擊事件,核心代碼如下:
$("#sub").click(function(){
var username=$("#user-name").val();
var pwd=$("#password").val();
//單擊“提交”按鈕,此處規(guī)定內(nèi)容要提交到“user.php”文件中
$.post(′user.php′,{username:username,pwd:pwd},function(data){
if(data.err==1){
alert(data.msg);
}else{
alert(data.msg);
}
},′json′);
return false;
});
在user.php中,對用戶信息進(jìn)行解密,核心代碼如下:
$username=RSA-Openssl($username,′decode′);//對傳過來的用戶名解密
$pwd=RSA-Openssl($pwd,′decode′);//對傳過來的密碼解密
if ($username=="admin"&&$pwd=="123456"){
echo json-encode(array(′err′=>1,′msg′=>′登錄成功′));
}else{
echo json-encode(array(′err′=>-1,′msg′=>′用戶名或密碼錯(cuò)誤′));
}
此處以用戶名為“admin”、密碼為“123456”為例,當(dāng)兩者均輸入正確,則讓用戶成功登錄,否則不允許用戶登錄。經(jīng)過上述編程設(shè)計(jì),當(dāng)用戶在瀏覽器中輸入用戶名及密碼等信息后單擊提交按鈕,將加密傳輸至服務(wù)器,服務(wù)器接收數(shù)據(jù)后解密,還原信息,有效保護(hù)了用戶個(gè)人資料,提高了網(wǎng)站的安全性。
保護(hù)網(wǎng)站用戶的個(gè)人信息是網(wǎng)站安全的重要部分,WEB應(yīng)用程序開發(fā)人員在開發(fā)項(xiàng)目時(shí)應(yīng)對用戶登錄注冊模塊的用戶信息進(jìn)行RSA加密設(shè)計(jì),RSA加密算法是成熟可靠的加密技術(shù),使用RSA算法進(jìn)行信息加密,會(huì)使數(shù)據(jù)的傳輸更可靠,對信息時(shí)代中建設(shè)可靠安全的網(wǎng)絡(luò)環(huán)境意義深遠(yuǎn)。