Last active
November 3, 2016 03:36
-
-
Save wilsoncook/cb2aefd4ba4c86ab16ab to your computer and use it in GitHub Desktop.
极简的服务器HTTP通信加密---PHP/JS端
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 通用通信加密验证库【注:传递的参数名仅支持:数字、大小写字母】 | |
* @author Wilson Zeng jackzcs@gmail.com | |
* @version 0.0.1 | |
*/ | |
(function () { | |
// Establish the root object, `window` in the browser, or `exports` on the server. | |
var root = this; | |
//依赖自由的md5 | |
//if (typeof(md5) !== 'function') function md5(e){var t;var n=function(e,t){return e<<t|e>>>32-t};var r=function(e,t){var n,r,i,s,o;i=e&2147483648;s=t&2147483648;n=e&1073741824;r=t&1073741824;o=(e&1073741823)+(t&1073741823);if(n&r){return o^2147483648^i^s}if(n|r){if(o&1073741824){return o^3221225472^i^s}else{return o^1073741824^i^s}}else{return o^i^s}};var i=function(e,t,n){return e&t|~e&n};var s=function(e,t,n){return e&n|t&~n};var o=function(e,t,n){return e^t^n};var u=function(e,t,n){return t^(e|~n)};var a=function(e,t,s,o,u,a,f){e=r(e,r(r(i(t,s,o),u),f));return r(n(e,a),t)};var f=function(e,t,i,o,u,a,f){e=r(e,r(r(s(t,i,o),u),f));return r(n(e,a),t)};var l=function(e,t,i,s,u,a,f){e=r(e,r(r(o(t,i,s),u),f));return r(n(e,a),t)};var c=function(e,t,i,s,o,a,f){e=r(e,r(r(u(t,i,s),o),f));return r(n(e,a),t)};var h=function(e){var t;var n=e.length;var r=n+8;var i=(r-r%64)/64;var s=(i+1)*16;var o=new Array(s-1);var u=0;var a=0;while(a<n){t=(a-a%4)/4;u=a%4*8;o[t]=o[t]|e.charCodeAt(a)<<u;a++}t=(a-a%4)/4;u=a%4*8;o[t]=o[t]|128<<u;o[s-2]=n<<3;o[s-1]=n>>>29;return o};var p=function(e){var t="",n="",r,i;for(i=0;i<=3;i++){r=e>>>i*8&255;n="0"+r.toString(16);t=t+n.substr(n.length-2,2)}return t};var d=[],v,m,g,y,b,w,E,S,x,T=7,N=12,C=17,k=22,L=5,A=9,O=14,M=20,_=4,D=11,P=16,H=23,B=6,j=10,F=15,I=21;e=this.utf8_encode(e);d=h(e);w=1732584193;E=4023233417;S=2562383102;x=271733878;t=d.length;for(v=0;v<t;v+=16){m=w;g=E;y=S;b=x;w=a(w,E,S,x,d[v+0],T,3614090360);x=a(x,w,E,S,d[v+1],N,3905402710);S=a(S,x,w,E,d[v+2],C,606105819);E=a(E,S,x,w,d[v+3],k,3250441966);w=a(w,E,S,x,d[v+4],T,4118548399);x=a(x,w,E,S,d[v+5],N,1200080426);S=a(S,x,w,E,d[v+6],C,2821735955);E=a(E,S,x,w,d[v+7],k,4249261313);w=a(w,E,S,x,d[v+8],T,1770035416);x=a(x,w,E,S,d[v+9],N,2336552879);S=a(S,x,w,E,d[v+10],C,4294925233);E=a(E,S,x,w,d[v+11],k,2304563134);w=a(w,E,S,x,d[v+12],T,1804603682);x=a(x,w,E,S,d[v+13],N,4254626195);S=a(S,x,w,E,d[v+14],C,2792965006);E=a(E,S,x,w,d[v+15],k,1236535329);w=f(w,E,S,x,d[v+1],L,4129170786);x=f(x,w,E,S,d[v+6],A,3225465664);S=f(S,x,w,E,d[v+11],O,643717713);E=f(E,S,x,w,d[v+0],M,3921069994);w=f(w,E,S,x,d[v+5],L,3593408605);x=f(x,w,E,S,d[v+10],A,38016083);S=f(S,x,w,E,d[v+15],O,3634488961);E=f(E,S,x,w,d[v+4],M,3889429448);w=f(w,E,S,x,d[v+9],L,568446438);x=f(x,w,E,S,d[v+14],A,3275163606);S=f(S,x,w,E,d[v+3],O,4107603335);E=f(E,S,x,w,d[v+8],M,1163531501);w=f(w,E,S,x,d[v+13],L,2850285829);x=f(x,w,E,S,d[v+2],A,4243563512);S=f(S,x,w,E,d[v+7],O,1735328473);E=f(E,S,x,w,d[v+12],M,2368359562);w=l(w,E,S,x,d[v+5],_,4294588738);x=l(x,w,E,S,d[v+8],D,2272392833);S=l(S,x,w,E,d[v+11],P,1839030562);E=l(E,S,x,w,d[v+14],H,4259657740);w=l(w,E,S,x,d[v+1],_,2763975236);x=l(x,w,E,S,d[v+4],D,1272893353);S=l(S,x,w,E,d[v+7],P,4139469664);E=l(E,S,x,w,d[v+10],H,3200236656);w=l(w,E,S,x,d[v+13],_,681279174);x=l(x,w,E,S,d[v+0],D,3936430074);S=l(S,x,w,E,d[v+3],P,3572445317);E=l(E,S,x,w,d[v+6],H,76029189);w=l(w,E,S,x,d[v+9],_,3654602809);x=l(x,w,E,S,d[v+12],D,3873151461);S=l(S,x,w,E,d[v+15],P,530742520);E=l(E,S,x,w,d[v+2],H,3299628645);w=c(w,E,S,x,d[v+0],B,4096336452);x=c(x,w,E,S,d[v+7],j,1126891415);S=c(S,x,w,E,d[v+14],F,2878612391);E=c(E,S,x,w,d[v+5],I,4237533241);w=c(w,E,S,x,d[v+12],B,1700485571);x=c(x,w,E,S,d[v+3],j,2399980690);S=c(S,x,w,E,d[v+10],F,4293915773);E=c(E,S,x,w,d[v+1],I,2240044497);w=c(w,E,S,x,d[v+8],B,1873313359);x=c(x,w,E,S,d[v+15],j,4264355552);S=c(S,x,w,E,d[v+6],F,2734768916);E=c(E,S,x,w,d[v+13],I,1309151649);w=c(w,E,S,x,d[v+4],B,4149444226);x=c(x,w,E,S,d[v+11],j,3174756917);S=c(S,x,w,E,d[v+2],F,718787259);E=c(E,S,x,w,d[v+9],I,3951481745);w=r(w,m);E=r(E,g);S=r(S,y);x=r(x,b)}var q=p(w)+p(E)+p(S)+p(x);return q.toLowerCase()} | |
var md5=(function(){function e(e,t){var o=e[0],u=e[1],a=e[2],f=e[3];o=n(o,u,a,f,t[0],7,-680876936);f=n(f,o,u,a,t[1],12,-389564586);a=n(a,f,o,u,t[2],17,606105819);u=n(u,a,f,o,t[3],22,-1044525330);o=n(o,u,a,f,t[4],7,-176418897);f=n(f,o,u,a,t[5],12,1200080426);a=n(a,f,o,u,t[6],17,-1473231341);u=n(u,a,f,o,t[7],22,-45705983);o=n(o,u,a,f,t[8],7,1770035416);f=n(f,o,u,a,t[9],12,-1958414417);a=n(a,f,o,u,t[10],17,-42063);u=n(u,a,f,o,t[11],22,-1990404162);o=n(o,u,a,f,t[12],7,1804603682);f=n(f,o,u,a,t[13],12,-40341101);a=n(a,f,o,u,t[14],17,-1502002290);u=n(u,a,f,o,t[15],22,1236535329);o=r(o,u,a,f,t[1],5,-165796510);f=r(f,o,u,a,t[6],9,-1069501632);a=r(a,f,o,u,t[11],14,643717713);u=r(u,a,f,o,t[0],20,-373897302);o=r(o,u,a,f,t[5],5,-701558691);f=r(f,o,u,a,t[10],9,38016083);a=r(a,f,o,u,t[15],14,-660478335);u=r(u,a,f,o,t[4],20,-405537848);o=r(o,u,a,f,t[9],5,568446438);f=r(f,o,u,a,t[14],9,-1019803690);a=r(a,f,o,u,t[3],14,-187363961);u=r(u,a,f,o,t[8],20,1163531501);o=r(o,u,a,f,t[13],5,-1444681467);f=r(f,o,u,a,t[2],9,-51403784);a=r(a,f,o,u,t[7],14,1735328473);u=r(u,a,f,o,t[12],20,-1926607734);o=i(o,u,a,f,t[5],4,-378558);f=i(f,o,u,a,t[8],11,-2022574463);a=i(a,f,o,u,t[11],16,1839030562);u=i(u,a,f,o,t[14],23,-35309556);o=i(o,u,a,f,t[1],4,-1530992060);f=i(f,o,u,a,t[4],11,1272893353);a=i(a,f,o,u,t[7],16,-155497632);u=i(u,a,f,o,t[10],23,-1094730640);o=i(o,u,a,f,t[13],4,681279174);f=i(f,o,u,a,t[0],11,-358537222);a=i(a,f,o,u,t[3],16,-722521979);u=i(u,a,f,o,t[6],23,76029189);o=i(o,u,a,f,t[9],4,-640364487);f=i(f,o,u,a,t[12],11,-421815835);a=i(a,f,o,u,t[15],16,530742520);u=i(u,a,f,o,t[2],23,-995338651);o=s(o,u,a,f,t[0],6,-198630844);f=s(f,o,u,a,t[7],10,1126891415);a=s(a,f,o,u,t[14],15,-1416354905);u=s(u,a,f,o,t[5],21,-57434055);o=s(o,u,a,f,t[12],6,1700485571);f=s(f,o,u,a,t[3],10,-1894986606);a=s(a,f,o,u,t[10],15,-1051523);u=s(u,a,f,o,t[1],21,-2054922799);o=s(o,u,a,f,t[8],6,1873313359);f=s(f,o,u,a,t[15],10,-30611744);a=s(a,f,o,u,t[6],15,-1560198380);u=s(u,a,f,o,t[13],21,1309151649);o=s(o,u,a,f,t[4],6,-145523070);f=s(f,o,u,a,t[11],10,-1120210379);a=s(a,f,o,u,t[2],15,718787259);u=s(u,a,f,o,t[9],21,-343485551);e[0]=m(o,e[0]);e[1]=m(u,e[1]);e[2]=m(a,e[2]);e[3]=m(f,e[3])};function t(e,t,n,r,i,s){t=m(m(t,e),m(r,s));return m(t<<i|t>>>32-i,n)};function n(e,n,r,i,s,o,u){return t(n&r|~n&i,e,n,s,o,u)};function r(e,n,r,i,s,o,u){return t(n&i|r&~i,e,n,s,o,u)};function i(e,n,r,i,s,o,u){return t(n^r^i,e,n,s,o,u)};function s(e,n,r,i,s,o,u){return t(r^(n|~i),e,n,s,o,u)};function o(t){var n=t.length,r=[1732584193,-271733879,-1732584194,271733878],i;for(i=64;i<=t.length;i+=64){e(r,u(t.substring(i-64,i)))};t=t.substring(i-64);var s=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(i=0;i<t.length;i++)s[i>>2]|=t.charCodeAt(i)<<(i%4<<3);s[i>>2]|=128<<(i%4<<3);if(i>55){e(r,s);for(i=0;i<16;i++)s[i]=0};s[14]=n*8;e(r,s);return r};function u(e){var t=[],n;for(n=0;n<64;n+=4){t[n>>2]=e.charCodeAt(n)+(e.charCodeAt(n+1)<<8)+(e.charCodeAt(n+2)<<16)+(e.charCodeAt(n+3)<<24)};return t};function c(e){var t="",n=0;for(;n<4;n++)t+=a[e>>n*8+4&15]+a[e>>n*8&15];return t};function h(e){for(var t=0;t<e.length;t++)e[t]=c(e[t]);return e.join("")};function d(e){return h(o(unescape(encodeURIComponent(e))))};function m(e,t){return e+t&4294967295};var a="0123456789abcdef".split("");return d})(); | |
//获取一个字符串的ascii值的和 | |
function getStrAscii (str) { | |
var sum = 0; | |
for (var i = 0; i < str.length; i ++) { sum += (str + '').charCodeAt(i); } | |
return sum; | |
} | |
//通过ascii码值的和来排序(升序)一维数组 | |
function sortAscii (arr) { | |
var map = {}, __getCacheAscii = function (key) { return typeof map[key] == 'undefined' ? (map[key] = getStrAscii(key)) : map[key]; }; //获取一个字符串$key的ascii码和,并缓存 | |
for (var i = 0; i < arr.length; i++) { | |
var sumI = __getCacheAscii(arr[i]); | |
for (var j = i + 1; j < arr.length; j++) { | |
var sumJ = __getCacheAscii(arr[j]); | |
if (sumJ < sumI) { var tmp = arr[j]; arr[j] = arr[i]; arr[i] = tmp; } | |
} | |
} | |
return arr; | |
} | |
function isArray (obj) { | |
return Object.prototype.toString.call(obj) === '[object Array]'; | |
} | |
//将hash型params使用PHP的sort算法排序,返回数组 | |
//exclude=参数排除列表 | |
function sortParams (params, exclude) { | |
if (exclude) { for (var i = 0; i < exclude.length; i++) { delete params[exclude[i]]; } } | |
var keys = []; | |
for (var key in params) { keys.push(key); } | |
sortAscii(keys); | |
var ret = []; | |
for (var i = 0; i < keys.length; i ++) { ret.push(params[keys[i]]); } | |
return ret; | |
} | |
var SignAuther = { | |
/** | |
* 通信验证 | |
* 算法:sign = md5(md5(substr(timeline, -5)) + md5(参数值1 + 参数值2 + ... + key)) | |
* @param array $params 参数值列表(按顺序,若为hash表,则将自动sort后转换) | |
* @param [type] $sign 签名 | |
* @param [type] $timeline 通信时间线 | |
* @param [type] $key 加密密钥 | |
* @param [type] $expire 请求过期时限(秒) | |
* @return bool [description] | |
*/ | |
check: function (p) { | |
p || (p = {}); | |
p['params'] || (p['params'] = []); | |
p['sign'] || (p['sign'] = ''); | |
p['timeline'] = parseInt(p['timeline']) || 0; | |
p['key'] || (p['key'] = ''); | |
p['expire'] = parseInt(p['expire']) || 5; | |
//---参数处理 | |
if (typeof(p['params']) == 'string') p['params'] = [p['params']]; | |
//是hash表,转换为数组,并排除timeline,sign | |
if (!isArray(p['params'])) p['params'] = sortParams(p['params'], ['timeline', 'sign']); | |
//---参数值字符串拼接 | |
var paramStr = p['params'].join(''); | |
//---组合sign | |
var curSign = md5(md5((p['timeline'] + '').slice(-5)) + md5(paramStr + p['key'])); | |
if (Math.floor(Date.now() / 1000) > (p['timeline'] + p['expire']) || (curSign !== p['sign'])) { | |
return false; | |
} | |
return true; | |
}, | |
/** | |
* 构建通信sign | |
* 算法:sign = md5(md5(substr(timeline, -5)) + md5(参数值1 + 参数值2 + ... + key)) | |
* @param array $params 参数值列表(按顺序,若为hash表,则将自动sort后转换) | |
* @param [type] $key 加密密钥 | |
* @param [type] $timeline 默认为当前时间 | |
* @return array('timeline' => 时间戳, 'sign' => sign) | |
*/ | |
build: function (p) { | |
p || (p = {}); | |
p['params'] || (p['params'] = []); | |
p['timeline'] = parseInt(p['timeline']) || Math.floor(Date.now() / 1000); | |
p['key'] || (p['key'] = ''); | |
//---参数处理 | |
if (typeof(p['params']) == 'string') p['params'] = [p['params']]; | |
//是hash表,转换为数组,并排除timeline,sign | |
if (!isArray(p['params'])) p['params'] = sortParams(p['params'], ['timeline', 'sign']); | |
//---参数值字符串拼接 | |
var paramStr = p['params'].join(''); | |
// console.log('----------BUILD', (p['timeline'] + '').slice(-5), paramStr + p['key'], md5((p['timeline'] + '').slice(-5)), md5(paramStr + p['key'])); | |
return { | |
'timeline': p['timeline'], | |
'sign': md5(md5((p['timeline'] + '').slice(-5)) + md5(paramStr + p['key'])) | |
}; | |
} | |
}; | |
//暴露到所处环境 | |
if (typeof(module) !== 'undefined') { | |
module.exports = SignAuther; | |
} else { | |
root.SignAuther = SignAuther; | |
} | |
}).call(this); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); | |
/** | |
* 通用通信加密验证库【注:传递的参数名仅支持:数字、大小写字母】 | |
* @author Wilson Zeng jackzcs@gmail.com | |
* @version 0.0.1 | |
*/ | |
class SignAuther { | |
//判断是否是关联数组 | |
public static function isAssoc($arr) { | |
return array_keys($arr) !== range(0, count($arr) - 1); | |
} | |
//获取一个字符串的ascii值的和 | |
public static function getStrAscii ($str) { | |
$sum = 0; | |
for ($i = 0; $i < strlen($str); $i ++) { $sum += ord($str[$i]); } | |
return $sum; | |
} | |
//通过ascii码值的和来排序(升序)一维数组 | |
public static function sortAscii (&$arr) { | |
$count = count($arr); | |
$map = array(); | |
for ($i = 0; $i < $count; $i++) { | |
$sumI = SignAuther::__getCacheAscii($map, $arr[$i]); | |
for ($j = $i + 1; $j < $count; $j++) { | |
$sumJ = SignAuther::__getCacheAscii($map, $arr[$j]); | |
if ($sumJ < $sumI) { | |
$tmp = $arr[$j]; | |
$arr[$j] = $arr[$i]; | |
$arr[$i] = $tmp; | |
} | |
} | |
} | |
return $arr; | |
} | |
//获取一个字符串$key的ascii码和,并缓存 | |
public static function __getCacheAscii (&$map, $key) { | |
if (!isset($map[$key])) { $map[$key] = SignAuther::getStrAscii($key); } | |
return $map[$key]; | |
} | |
//将hash型params使用PHP的sort算法排序,返回数组 | |
//$exclude=参数排除列表 | |
public static function sortParams($params, $exclude) { | |
if ($exclude) { foreach ($exclude as $ekey) { unset($params[$ekey]); } } | |
$keys = array_keys($params); | |
SignAuther::sortAscii($keys); | |
$ret = array(); | |
foreach ($keys as $key) { $ret[] = $params[$key]; } | |
return $ret; | |
} | |
/** | |
* 通信验证 | |
* 算法:sign = md5(md5(substr(timeline, -5)) + md5(参数值1 + 参数值2 + ... + key)) | |
* @param array $params 参数值列表(按顺序,若为hash表,则将自动sort后转换) | |
* @param [type] $sign 签名 | |
* @param [type] $timeline 通信时间线 | |
* @param [type] $key 加密密钥 | |
* @param [type] $expire 请求过期时限(秒) | |
* @return bool [description] | |
*/ | |
public static function check ($p) { | |
$p = array_merge(array( | |
'params' => array(), //参数值列表(按顺序) | |
'sign' => '', | |
'timeline' => 0, | |
'key' => '', | |
'expire' => 5, | |
), (array)$p); | |
//---参数处理 | |
if (is_string($p['params'])) $p['params'] = array($p['params']); | |
//是hash表,转换为数组,并排除timeline,sign | |
if (self::isAssoc($p['params'])) $p['params'] = self::sortParams($p['params'], array('timeline', 'sign')); | |
//---参数值字符串拼接 | |
$paramStr = implode('', (array)$p['params']); | |
//---组合sign | |
$curSign = md5(md5(substr($p['timeline'], -5)) . md5($paramStr . $p['key'])); | |
// var_dump('--------CHECK', substr($p['timeline'], -5), $paramStr . $p['key'], md5(substr($p['timeline'], -5)), md5($paramStr . $p['key'])); | |
if (time() > ($p['timeline'] + $p['expire']) || ($curSign !== $p['sign'])) { | |
return false; | |
} | |
return true; | |
} | |
/** | |
* 构建通信sign | |
* 算法:sign = md5(md5(substr(timeline, -5)) + md5(参数值1 + 参数值2 + ... + key)) | |
* @param array $params 参数值列表(按顺序,若为hash表,则将自动sort后转换) | |
* @param [type] $key 加密密钥 | |
* @param [type] $timeline 默认为当前时间 | |
* @return array('timeline' => 时间戳, 'sign' => sign) | |
*/ | |
public static function build ($p) { | |
$p = array_merge(array( | |
'params' => array(), //参数值列表(按顺序) | |
'key' => '', | |
'timeline' => time(), | |
), (array)$p); | |
//---参数处理 | |
if (is_string($p['params'])) $p['params'] = array($p['params']); | |
//是hash表,转换为数组,并排除timeline,sign | |
if (self::isAssoc($p['params'])) $p['params'] = self::sortParams($p['params'], array('timeline', 'sign')); | |
//---参数值字符串拼接 | |
$paramStr = implode('', (array)$p['params']); | |
return array( | |
'timeline' => $p['timeline'], | |
'sign' => md5(md5(substr($p['timeline'], -5)) . md5($paramStr . $p['key'])), | |
); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
//---通信验证封装 | |
//验证 | |
//$data = $_POST 或 $_GET 或 $_REQUEST 或 其他,默认为$_POST | |
function SA_check($data) { | |
if (!$data) $data = &$_POST; | |
return SignAuther::check(array( | |
'params' => $data, | |
'key' => DDM_API_KEY, | |
'sign' => $data['sign'], | |
'timeline' => $data['timeline'], | |
)); | |
} | |
//构建 | |
function SA_build($data) { | |
return SignAuther::build(array( | |
'params' => $data, | |
'key' => DDM_API_KEY, | |
)); | |
} | |
//针对json形式返回数据(不适合大数据) | |
//返回格式: | |
//{"data":"原始json数据base64串", "timeline":0, "sign":"ddddd"} | |
function safeJsonReturn($status, $message) { | |
$json = json_encode(array('status' => $status, 'message' => $message)); | |
$base64 = base64_encode($json); | |
$ret = SA_build($base64); | |
exit(json_encode(array( | |
'data' => $base64, | |
'timeline' => $ret['timeline'], | |
'sign' => $ret['sign'], | |
))); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment