Sign簽名生成與校驗
阿新 • • 發佈:2019-01-08
引數說明:
from 介面發起方標識,由管理員分配
secret 金鑰,由管理員分配
sign 簽名
timestamp 時間戳 s (用於校驗簽名有效期)
sign演算法;
1.對所有引數(此時不含sign引數)升序排列得出arrarg
2.把arrarg的值以’&’拼接成一個字串得出strarg
3.secret.’&’.strarg.’&’.secret得出sign
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* 發起方 校驗類
*/
class Sign {
const TIME = 'timestamp';
const FROM = 'from';
const SIGN = 'sign';
const TIMEOUT = 30; // 簽名有效期 s
private $ci;
private $froms;
public function __construct()
{
$this->ci =& get_instance();
$this->froms = $this->ci->config->item('api_froms' );
}
/**
* [create 生成簽名]
* @param [array] $args [引數列表]
* @param [string] $secret [金鑰]
* @return [string] sign
*/
public function create($args,$secret)
{
if(isset($args[self::SIGN]))
{
unset($args[self::SIGN]);
}
if (!is_array($args))
{
return FALSE;
}
else
{
ksort($args);
$strArgs = implode('&', $args);
return md5($secret.'&'.$strArgs.'&'.$secret);
}
}
/**
* [valid 校驗請求]
* @param string $method [呼叫方式]
* @return [array]
*/
public function valid($data)
{
$err = -2;
$msg = 'falid';
if( FALSE === $secret=$this->checkFrom($data) )
{
$msg = 'the from is not defined';
}
elseif(FALSE === $this->checkTime($data))
{
$msg = 'the sign is overdue';
}
elseif(FALSE === $this->checkSign($data,$secret))
{
$msg = 'the sign is wrong';
}
else
{
$err = 2;
$msg = 'ok';
}
return array('err'=>$err,'msg'=>$msg);
}
private function checkSign($data,$secret)
{
$sign = isset($data[self::SIGN]) ? $data[self::SIGN] : FALSE;
if(!$sign )
{
return FALSE;
}
elseif($sign != $this->create($data,$secret))
{
return FALSE;
}
else
{
return TRUE;
}
}
private function checkTime($data)
{
if(! isset($data[self::TIME]))
{
return FALSE;
}
elseif( self::TIMEOUT < intval(time()-$data[self::TIME]) )
{
return FALSE;
}
else
{
return TRUE;
}
}
private function checkFrom($data)
{
if( ! isset($this->froms[$data[self::FROM]]) )
{
return FALSE;
}
else
{
return $this->froms[$data[self::FROM]];
}
}
}