《PHP學(xué)習(xí):AES加解密在php接口請(qǐng)求過(guò)程中的應(yīng)用示例》要點(diǎn):
本文介紹了PHP學(xué)習(xí):AES加解密在php接口請(qǐng)求過(guò)程中的應(yīng)用示例,希望對(duì)您有用。如果有疑問(wèn),可以聯(lián)系我們。
PHP實(shí)戰(zhàn)在php請(qǐng)求接口的時(shí)候,我們經(jīng)常需要考慮的一個(gè)問(wèn)題就是數(shù)據(jù)的安全性,因?yàn)閿?shù)據(jù)傳輸過(guò)程中很有可能會(huì)被用fillder這樣的抓包工具進(jìn)行截獲.一種比較好的解決方案就是在客戶端請(qǐng)求發(fā)起之前先對(duì)要請(qǐng)求的數(shù)據(jù)進(jìn)行加密,服務(wù)端api接收到請(qǐng)求數(shù)據(jù)后再對(duì)數(shù)據(jù)進(jìn)行解密處理,返回結(jié)果給客戶端的時(shí)候也對(duì)要返回的數(shù)據(jù)進(jìn)行加密,客戶端接收到返回?cái)?shù)據(jù)的時(shí)候再解密.因此整個(gè)api請(qǐng)求過(guò)程中數(shù)據(jù)的安全性有了一定程度的提高.
PHP實(shí)戰(zhàn)今天結(jié)合一個(gè)簡(jiǎn)單的demo給大家分享一下AES加解密技術(shù)在php接口請(qǐng)求中的應(yīng)用.
PHP實(shí)戰(zhàn)首先,準(zhǔn)備一個(gè)AES加解密的基礎(chǔ)類:
PHP實(shí)戰(zhàn)
<?php
/**
* 加密基礎(chǔ)類
*/
class Crypt_AES
{
protected $_cipher = "rijndael-128";
protected $_mode = "cbc";
protected $_key;
protected $_iv = null;
protected $_descriptor = null;
/**
* 是否按照PKCS #7 的標(biāo)準(zhǔn)進(jìn)行填充
* 為否默認(rèn)將填充“\0”補(bǔ)位
* @var boolean
*/
protected $_PKCS7 = false;
/**
* 構(gòu)造函數(shù),對(duì)于密鑰key應(yīng)區(qū)分2進(jìn)制字符串和16進(jìn)制的.
* 如需兼容PKCS#7標(biāo)準(zhǔn),應(yīng)選項(xiàng)設(shè)置開(kāi)啟PKCS7,默認(rèn)關(guān)閉
* @param string $key
* @param mixed $iv 向量值
* @param array $options
*/
public function __construct($key = null, $iv = null, $options = null)
{
if (null !== $key) {
$this->setKey($key);
}
if (null !== $iv) {
$this->setIv($iv);
}
if (null !== $options) {
if (isset($options['chipher'])) {
$this->setCipher($options['chipher']);
}
if (isset($options['PKCS7'])) {
$this->isPKCS7Padding($options['PKCS7']);
}
if (isset($options['mode'])) {
$this->setMode($options['mode']);
}
}
}
/**
* PKCS#7狀態(tài)查看,傳入Boolean值進(jìn)行設(shè)置
* @param boolean $flag
* @return boolean
*/
public function isPKCS7Padding($flag = null)
{
if (null === $flag) {
return $this->_PKCS7;
}
$this->_PKCS7 = (bool) $flag;
}
/**
* 開(kāi)啟加密算法
* @param string $algorithm_directory locate the encryption
* @param string $mode_directory
* @return Crypt_AES
*/
public function _openMode($algorithm_directory = "" , $mode_directory = "")
{
$this->_descriptor = mcrypt_module_open($this->_cipher,
$algorithm_directory,
$this->_mode,
$mode_directory);
return $this;
}
public function getDescriptor()
{
if (null === $this->_descriptor) {
$this->_openMode();
}
return $this->_descriptor;
}
protected function _genericInit()
{
return mcrypt_generic_init($this->getDescriptor(), $this->getKey(), $this->getIv());
}
protected function _genericDeinit()
{
return mcrypt_generic_deinit($this->getDescriptor());
}
public function getMode()
{
return $this->_mode;
}
public function setMode($mode)
{
$this->_mode = $mode;
return $this;
}
public function getCipher()
{
return $this->_cipher;
}
public function setCipher($cipher)
{
$this->_cipher = $cipher;
return $this;
}
/**
* 獲得key
* @return string
*/
public function getKey()
{
return $this->_key;
}
/**
* 設(shè)置可以
* @param string $key
*/
public function setKey($key)
{
$this->_key = $key;
return $this;
}
/**
* 獲得加密向量塊,如果其為null時(shí)將追加當(dāng)前Descriptor的IV大小長(zhǎng)度
*
* @return string
*/
public function getIv()
{
if (null === $this->_iv && in_array($this->_mode, array( "cbc", "cfb", "ofb", ))) {
$size = mcrypt_enc_get_iv_size($this->getDescriptor());
$this->_iv = str_pad("", 16, "\0");
}
return $this->_iv;
}
/**
* 獲得向量塊
*
* @param string $iv
* @return Crypt_AES $this
*/
public function setIv($iv)
{
$this->_iv = $iv;
return $this;
}
/**
* 加密
* @param string $str 被加密文本
* @return string
*/
public function encrypt($str){
$td = $this->getDescriptor();
$this->_genericInit();
$bin = mcrypt_generic($td, $this->padding($str));
$this->_genericDeinit();
return $bin;
}
public function padding($dat)
{
if ($this->isPKCS7Padding()) {
$block = mcrypt_enc_get_block_size($this->getDescriptor());
$len = strlen($dat);
$padding = $block - ($len % $block);
$dat .= str_repeat(chr($padding),$padding);
}
return $dat;
}
public function unpadding($str)
{
if ($this->isPKCS7Padding()) {
$pad = ord($str[($len = strlen($str)) - 1]);
$str = substr($str, 0, strlen($str) - $pad);
}
return $str;
}
/**
* 解密
* @param string $str
* @return string
*/
public function decrypt($str){
$td = $this->getDescriptor();
$this->_genericInit();
$text = mdecrypt_generic($td, $str);
$this->_genericDeinit();
return $this->unpadding($text);
}
/**
* 16進(jìn)制轉(zhuǎn)成2進(jìn)制數(shù)據(jù)
* @param string $hexdata 16進(jìn)制字符串
* @return string
*/
public static function hex2bin($hexdata)
{
return pack("H*" , $hexdata);
}
/**
* 字符串轉(zhuǎn)十六進(jìn)制
* @param string $hexdata 16進(jìn)制字符串
* @return string
*/
public static function strToHex($string)
{
$hex='';
for($i=0;$i<strlen($string);$i++)
$hex.=dechex(ord($string[$i]));
$hex=strtoupper($hex);
return $hex;
}
/**
* 十六進(jìn)制轉(zhuǎn)字符串
* @param string $hexdata 16進(jìn)制字符串
* @return string
*/
function hexToStr($hex)
{
$string='';
for($i=0;$i<strlen($hex)-1;$i+=2)
$string.=chr(hexdec($hex[$i].$hex[$i+1]));
return $string;
}
}
PHP實(shí)戰(zhàn)客戶端請(qǐng)求部分:
PHP實(shí)戰(zhàn)
<?php
include 'AES.php';
$md5Key = 'ThisIsAMd5Key'; // 對(duì)應(yīng)服務(wù)端:$md5key = 'ThisIsAMd5Key';
$aesKey = Crypt_AES::strToHex('1qa2ws4rf3edzxcv'); // 對(duì)應(yīng)服務(wù)端:$aesKey = '3171613277733472663365647A786376';
$aesKey = Crypt_AES::hex2bin($aesKey);
$aesIV = Crypt_AES::strToHex('dfg452ws'); // 對(duì)應(yīng)服務(wù)端:$aesIV = '6466673435327773';
$aes = new Crypt_AES($aesKey,$aesIV,array('PKCS7'=>true, 'mode'=>'cbc'));
// var_dump($aes);
$data['name'] = 'idoubi';
$data['sex']= 'male';
$data['age'] = 23;
$data['signature'] = '白天我是一個(gè)程序員,晚上我就是一個(gè)有夢(mèng)想的演員.';
$content = base64_encode($aes->encrypt(json_encode($data)));
$content = urlencode($content);
$sign = md5($content.$md5Key);
$url = 'http://localhost/aesdemo/api.php';
$params = "version=1.0&sign=$sign&content=$content";
// 請(qǐng)求接口
post($url, $params);
/**
* 接口請(qǐng)求函數(shù)
*/
function post($url, $params) {
$curlPost= $params;
$ch = curl_init(); //初始化curl
curl_setopt($ch, CURLOPT_URL, $url); //提交到指定網(wǎng)頁(yè)
curl_setopt($ch, CURLOPT_HEADER, 0); //設(shè)置header
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //要求結(jié)果為字符串且輸出到屏幕上
curl_setopt($ch, CURLOPT_POST, 1); //post提交方式
curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);
$result = curl_exec($ch);//運(yùn)行curl
curl_close($ch);
var_dump(json_decode($result, true));
}
PHP實(shí)戰(zhàn)接口處理邏輯:
PHP實(shí)戰(zhàn)
<?php
include 'AES.php';
$data = $_POST; // 接口請(qǐng)求得到的數(shù)據(jù)
$content = $data['content'];
$sign = $data['sign'];
$aesKey = '3171613277733472663365647A786376';
$aesIV = '6466673435327773';
$md5key = 'ThisIsAMd5Key';
// 校驗(yàn)數(shù)據(jù)
if(strcasecmp(md5(urlencode($content).$md5key),$sign) == 0) {
// 數(shù)據(jù)校驗(yàn)成功
$key = Crypt_AES::hex2bin($aesKey);
$aes = new Crypt_AES($key, $aesIV, array('PKCS7'=>true, 'mode'=>'cbc'));
$decrypt = $aes->decrypt(base64_decode($content));
if (!$decrypt) { // 解密失敗
echo json_encode('can not decrypt the data');
} else {
echo json_encode($decrypt); // 解密成功
}
} else{
echo json_encode('data is not integrity'); // 數(shù)據(jù)校驗(yàn)失敗
}
PHP實(shí)戰(zhàn)上述接口請(qǐng)求過(guò)程中定義了三個(gè)加解密需要用到的參數(shù):$aesKey、$aesIV、$md5key,在實(shí)際應(yīng)用過(guò)程中,只要與客戶端用戶約定好這三個(gè)參數(shù),客戶端程序員利用這幾個(gè)參數(shù)對(duì)要請(qǐng)求的數(shù)據(jù)進(jìn)行加密后再請(qǐng)求接口,服務(wù)端程序員在接收到數(shù)據(jù)后利用同樣的加解密參數(shù)對(duì)數(shù)據(jù)進(jìn)行解密,整個(gè)api請(qǐng)求過(guò)程中的數(shù)據(jù)就很安全了.
PHP實(shí)戰(zhàn)以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持維易PHP.
轉(zhuǎn)載請(qǐng)注明本頁(yè)網(wǎng)址:
http://www.fzlkiss.com/jiaocheng/2949.html