首頁 >後端開發 >php教程 >PHP對稱加密函數實現資料的加密解密詳解

PHP對稱加密函數實現資料的加密解密詳解

墨辰丷
墨辰丷原創
2018-05-31 10:05:322479瀏覽

本文詳細介紹了PHP一個簡單的對稱加密函數實現資料的加密解密,詳細的介紹了對稱加密和非對稱加密,有需要的可以了解一下。

專案中有一個地方用到了將使用者ID加密、傳至下個接點進行反解的需求。 (原諒我不能透漏太多-_-!),第一個想到的就是康盛Ucenter中的一個函數,後來搜了下,在簡明魔法中也找到了個簡單的方法,遂整合了下,形成了自己使用的函數。

一、對稱加密

發送方將明文使用金鑰和演算法處理成密文發送出去,接收方使用金鑰和演算法將密文處理成明文,發收信雙方使用同一個金鑰對資料進行加密和解密。

因為使用同一個金鑰加密、解密,所以安全性上不僅與演算法有關,金鑰的安全性也很重要。

當然不是密鑰越複雜越好,相反密鑰通常比較小的,因為雖然密鑰越大,加密越強,但加密與解密的過程越慢,所以密鑰的大小既要照顧到安全性,也要照顧到效率。

畢竟對稱加密演算法的特點是演算法公開、計算量小、加密速度快、加密效率高,沒了效率高這一優勢,還不如直接用非對稱加密。

此外,每次使用對稱加密演算法時,每對使用者都需要使用其他人不知道的惟一鑰匙,這會使得發收信雙方所擁有的鑰匙數量呈幾何級數增長,密鑰管理成為使用者的負擔。

對稱加密演算法在分散式網路系統上使用較為困難,主要是因為金鑰管理困難,使用成本較高。

二、非對稱加密

非對稱加密相對來說,就安全很多了,它使用了一對金鑰,公開金鑰和私有金鑰,分別用來進行加密和解密。私鑰只能由一方安全保管,不能外洩,而公鑰則可以發給任何要求它的人。

最常見的非對稱加密,應該就是銀行系統,支付平台了。例如我們申請支付寶或銀聯支付的介面時,會得到一個公鑰,商城中進行支付是,用公鑰將資訊加密提交給平台,平台使用金鑰對你的資訊解密,進行支付操作等。

雖然非對稱加密很安全,但是和對稱加密比起來,它非常的慢,所以我們一般處理的話,大部分是用對稱加密來傳送消息,但對稱加密所使用的密鑰我們可以透過非對稱加密的方式發送出去,回想一下你申請到的支付接口,是不是給了你一對金鑰呢? ^.^

三、結合使用

對稱性加密速度快,傳送大量資料時用比較好。非對稱加密加密和解密花費時間長、速度慢,只適合對少量資料進行加密,但是,非對稱加密的安全性是極高的。

揚長避短:將對稱加密的金鑰使用非對稱加密的公鑰進行加密,然後發送出去,接收者使用私鑰進行解密得到對稱加密的金鑰,然後雙方可以使用對稱加密來進行溝通。

專案中使用的方法不宜透露,只在這裡列出兩個其他的例子吧。第一個是ucenter中的,第二個是簡潔魔法中看到的。

要注意的是,由於是base64演算法,加密後的字串有可能會出現\ ,如果是用在url中,是不友善的,可以在外部或改下方法,正則驗證遞歸調取下。

/**
 * 字符串加密以及解密函数
 * @param string $string 原文或者密文
 * @param string $operation 操作(ENCODE | DECODE), 默认为 DECODE
 * @param string $key 密钥
 * @param int $expiry 密文有效期, 加密时候有效, 单位 秒,0 为永久有效
 * @return string 处理后的 原文或者 经过 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 == &#39;DECODE&#39;) {
  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 &#39;&#39;;
  }
 } else {
  return $keyc . str_replace(&#39;=&#39;, &#39;&#39;, base64_encode($result));
 }
}

/*********************************************************************
函数名称:encrypt
函数作用:加密解密字符串
使用方法:
加密  :encrypt(&#39;str&#39;,&#39;E&#39;,&#39;nowamagic&#39;);
解密  :encrypt(&#39;被加密过的字符串&#39;,&#39;D&#39;,&#39;nowamagic&#39;);
参数说明:
$string :需要加密解密的字符串
$operation:判断是加密还是解密:E:加密 D:解密
$key  :加密的钥匙(密匙);
*********************************************************************/
function encrypt($string,$operation,$key=&#39;&#39;)
{
 $key=md5($key);
 $key_length=strlen($key);
 $string=$operation==&#39;D&#39;?base64_decode($string):substr(md5($string.$key),0,8).$string;
 $string_length=strlen($string);
 $rndkey=$box=array();
 $result=&#39;&#39;;
 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==&#39;D&#39;)
 {
  if(substr($result,0,8)==substr(md5(substr($result,8).$key),0,8))
  {
   return substr($result,8);
  }
  else
  {
   return&#39;&#39;;
  }
 }
 else
 {
  return str_replace(&#39;=&#39;,&#39;&#39;,base64_encode($result));
 }
}

以上就是本文的全部內容,希望對大家的學習有幫助。


相關推薦:

PHP實作的Redis多庫選擇功能單例類別(詳解)

PHP策略模式定義與用法(詳解)

#PHP自訂函數判斷是否為Get/Post/Ajax提交的方法詳解

##

以上是PHP對稱加密函數實現資料的加密解密詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn