PHP對(duì)稱加密函數(shù)實(shí)現(xiàn)數(shù)據(jù)的加密解密
項(xiàng)目中有一個(gè)地方用到了將用戶ID加密、傳至下個(gè)接點(diǎn)進(jìn)行反解的需求。(原諒我不能透漏太多-_-!),第一個(gè)想到的就是康盛Ucenter中的一個(gè)函數(shù),后來(lái)搜了下,在簡(jiǎn)明魔法中也找到了個(gè)簡(jiǎn)單的方法,遂整合了下,形成了自己使用的函數(shù)。
一、對(duì)稱加密
發(fā)送方將明文使用密鑰和算法處理成密文發(fā)送出去,接收方使用密鑰和算法將密文處理成明文,發(fā)收信雙方使用同一個(gè)密鑰對(duì)數(shù)據(jù)進(jìn)行加密和解密。

因?yàn)槭褂猛粋€(gè)密鑰加密、解密,所以安全性上不僅與算法有關(guān),密鑰的安全也很重要。
當(dāng)然并不是密鑰越復(fù)雜越好,相反密鑰通常比較小的,因?yàn)殡m然密鑰越大,加密越強(qiáng),但加密與解密的過(guò)程越慢,所以密鑰的大小既要照顧到安全性,也要照顧到效率。
畢竟對(duì)稱加密算法的特點(diǎn)是算法公開(kāi)、計(jì)算量小、加密速度快、加密效率高,沒(méi)了效率高這一優(yōu)勢(shì),還不如直接用非對(duì)稱加密。
此外,每對(duì)用戶每次使用對(duì)稱加密算法時(shí),都需要使用其他人不知道的惟一鑰匙,這會(huì)使得發(fā)收信雙方所擁有的鑰匙數(shù)量呈幾何級(jí)數(shù)增長(zhǎng),密鑰管理成為用戶的負(fù)擔(dān)。
對(duì)稱加密算法在分布式網(wǎng)絡(luò)系統(tǒng)上使用較為困難,主要是因?yàn)槊荑€管理困難,使用成本較高。
二、非對(duì)稱加密
非對(duì)稱加密相對(duì)來(lái)說(shuō),就安全很多了,它使用了一對(duì)密鑰,公開(kāi)密鑰和私有密鑰,分別用來(lái)進(jìn)行加密和解密。私鑰只能由一方安全保管,不能外泄,而公鑰則可以發(fā)給任何請(qǐng)求它的人。

最常見(jiàn)的非對(duì)稱加密,應(yīng)該就是銀行系統(tǒng),支付平臺(tái)了。比如我們申請(qǐng)支付寶或者銀聯(lián)支付的接口時(shí),會(huì)得到一個(gè)公鑰,商城中進(jìn)行支付是,用公鑰將信息加密提交給平臺(tái),平臺(tái)使用密鑰對(duì)你的信息解密,進(jìn)行支付操作等。
雖然非對(duì)稱加密很安全,但是和對(duì)稱加密比起來(lái),它非常的慢,所以我們一般處理的話,大部分是用對(duì)稱加密來(lái)傳送消息,但對(duì)稱加密所使用的密鑰我們可以通過(guò)非對(duì)稱加密的方式發(fā)送出去,回想一下你申請(qǐng)到的支付接口,是不是給了你一對(duì)密鑰呢?^.^
三、結(jié)合使用
對(duì)稱性加密速度快,發(fā)送大量數(shù)據(jù)時(shí)用比較好。非對(duì)稱加密加密和解密花費(fèi)時(shí)間長(zhǎng)、速度慢,只適合對(duì)少量數(shù)據(jù)進(jìn)行加密,但是,非對(duì)稱加密的安全性是極高的。
揚(yáng)長(zhǎng)避短:將對(duì)稱加密的密鑰使用非對(duì)稱加密的公鑰進(jìn)行加密,然后發(fā)送出去,接收方使用私鑰進(jìn)行解密得到對(duì)稱加密的密鑰,然后雙方可以使用對(duì)稱加密來(lái)進(jìn)行溝通。

項(xiàng)目中使用的方法不宜透露,只在這里列出兩個(gè)其他的例子吧。第一個(gè)是ucenter中的,第二個(gè)是簡(jiǎn)明魔法中看到的。
需要注意的是,由于是base64算法,加密后的字符串有可能會(huì)出現(xiàn) + \ ,如果是用在url中,是不友好的,可以在外部或改下方法,正則驗(yàn)證遞歸調(diào)取下。
/**
* 字符串加密以及解密函數(shù)
* @param string $string 原文或者密文
* @param string $operation 操作(ENCODE | DECODE), 默認(rèn)為 DECODE
* @param string $key 密鑰
* @param int $expiry 密文有效期, 加密時(shí)候有效, 單位 秒,0 為永久有效
* @return string 處理后的 原文或者 經(jīng)過(guò) base64_encode 處理后的密文
*/
function _authcode ($string, $operation = 'DECODE', $key = 'Ruesin', $expiry = 0)
{
$ckey_length = 4;
$key = md5($key);
$keya = md5(substr($key, 0, 16));
$keyb = md5(substr($key, 16, 16));
$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0,
$ckey_length) : substr(md5(microtime()), - $ckey_length)) : '';
$cryptkey = $keya . md5($keya . $keyc);
$key_length = strlen($cryptkey);
$string = $operation == 'DECODE' ? base64_decode(
substr($string, $ckey_length)) : sprintf('%010d',
$expiry ? $expiry + time() : 0) . substr(md5($string . $keyb), 0, 16) .
$string;
$string_length = strlen($string);
$result = '';
$box = range(0, 255);
$rndkey = array();
for ($i = 0; $i <= 255; $i ++) {
$rndkey[$i] = ord($cryptkey[$i % $key_length]);
}
for ($j = $i = 0; $i < 256; $i ++) {
$j = ($j + $box[$i] + $rndkey[$i]) % 256;
$tmp = $box[$i];
$box[$i] = $box[$j];
$box[$j] = $tmp;
}
for ($a = $j = $i = 0; $i < $string_length; $i ++) {
$a = ($a + 1) % 256;
$j = ($j + $box[$a]) % 256;
$tmp = $box[$a];
$box[$a] = $box[$j];
$box[$j] = $tmp;
$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
}
if ($operation == 'DECODE') {
if ((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) &&
substr($result, 10, 16) ==
substr(md5(substr($result, 26) . $keyb), 0, 16)) {
return substr($result, 26);
} else {
return '';
}
} else {
return $keyc . str_replace('=', '', base64_encode($result));
}
}
/*********************************************************************
函數(shù)名稱:encrypt
函數(shù)作用:加密解密字符串
使用方法:
加密 :encrypt('str','E','nowamagic');
解密 :encrypt('被加密過(guò)的字符串','D','nowamagic');
參數(shù)說(shuō)明:
$string :需要加密解密的字符串
$operation:判斷是加密還是解密:E:加密 D:解密
$key :加密的鑰匙(密匙);
*********************************************************************/
function encrypt($string,$operation,$key='')
{
$key=md5($key);
$key_length=strlen($key);
$string=$operation=='D'?base64_decode($string):substr(md5($string.$key),0,8).$string;
$string_length=strlen($string);
$rndkey=$box=array();
$result='';
for($i=0;$i<=255;$i++)
{
$rndkey[$i]=ord($key[$i%$key_length]);
$box[$i]=$i;
}
for($j=$i=0;$i<256;$i++)
{
$j=($j+$box[$i]+$rndkey[$i])%256;
$tmp=$box[$i];
$box[$i]=$box[$j];
$box[$j]=$tmp;
}
for($a=$j=$i=0;$i<$string_length;$i++)
{
$a=($a+1)%256;
$j=($j+$box[$a])%256;
$tmp=$box[$a];
$box[$a]=$box[$j];
$box[$j]=$tmp;
$result.=chr(ord($string[$i])^($box[($box[$a]+$box[$j])%256]));
}
if($operation=='D')
{
if(substr($result,0,8)==substr(md5(substr($result,8).$key),0,8))
{
return substr($result,8);
}
else
{
return'';
}
}
else
{
return str_replace('=','',base64_encode($result));
}
}
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
php設(shè)計(jì)模式之策略模式實(shí)例分析【星際爭(zhēng)霸游戲案例】
這篇文章主要介紹了php設(shè)計(jì)模式之策略模式,結(jié)合星際爭(zhēng)霸游戲案例形式分析了php策略模式相關(guān)原理、用法及操作注意事項(xiàng),需要的朋友可以參考下2020-03-03
Yii使用EasyWechat實(shí)現(xiàn)小程序獲取用戶的openID的方法
這篇文章主要介紹了Yii使用EasyWechat實(shí)現(xiàn)小程序獲取用戶的openID的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04
淺談Laravel模板實(shí)體轉(zhuǎn)義帶來(lái)的坑
今天小編就為大家分享一篇淺談Laravel模板實(shí)體轉(zhuǎn)義帶來(lái)的坑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-10-10
PHP 數(shù)據(jù)結(jié)構(gòu)隊(duì)列(SplQueue)和優(yōu)先隊(duì)列(SplPriorityQueue)簡(jiǎn)單使用實(shí)例
這篇文章主要介紹了PHP 數(shù)據(jù)結(jié)構(gòu)隊(duì)列(SplQueue)和優(yōu)先隊(duì)列(SplPriorityQueue)簡(jiǎn)單使用實(shí)例,需要的朋友可以參考下2015-05-05
使用pthreads實(shí)現(xiàn)真正的PHP多線程(需PHP5.3以上版本)
PHP 5.3 以上版本,使用pthreads PHP擴(kuò)展,可以使PHP真正地支持多線程。多線程在處理重復(fù)性的循環(huán)任務(wù),能夠大大縮短程序執(zhí)行時(shí)間2014-05-05

