前端请求参数MD5加密校验,参数串解密字符串长度排序
步骤:=》1.请求前对参数进⾏字典升序排序,排序函数
function objKeySort(obj) {
var newkey = Object.keys(obj).sort();
//先⽤Object内置类的keys⽅法获取要排序对象的属性名,再利⽤Array原型上的sort⽅法对获取的属性名进⾏排序,newkey是⼀个数组var newObj = {};//创建⼀个新的对象,⽤于存放排好序的键值对
for (var i = 0; i < newkey.length; i++) {//遍历newkey数组
newObj[newkey[i]] = obj[newkey[i]];//向新创建的对象中按照排好的顺序依次增加键值对
}
return newObj;//返回排好序的新对象
}
2.排序后对参数进⾏校验,校验参数涉及签名的请求头=》
oncekey客户端⽣成临时随机数6-8位字母或数字
timestr timestr时间戳
signkey请求签名key
wxsmall对随机⽣成的oncekeyMD5
并将oncekey 与timestr连接进⾏MD5,获得hash字符串将hash与datastr连接进⾏md5,datastr需引⽤函数objtostring将其转化为字符串,得到签名signkey,校验签名函数+字符串转化函数objtostring:
function signrequest
(data) {
data = objKeySort(data);//请求参数排序
var staticstr = '';
var timestr = parseInt((new Date()).getTime() / 1000);
var oncekey = parseInt(Math.random() * (100000 - 1000 + 1) + 1000, 10);
var wxsmall = md5(oncekey);
console.log("wxsmall:" + wxsmall);
var hash = md5(md5(wxsmall + '' + oncekey));
console.log("hash:" + hash);
var datastr = objtostring(data);
console.log("hash+datastr:" + hash + datastr);
var sign = md5(hash + datastr);
return { "timestr": timestr, "oncekey": oncekey, "wxsmall": wxsmall, "signkey": sign };
}
function objtostring(data) {//Object to String
var str = '';
for (var k in data) {
str += k + '=' + encodeURI(data[k]) + '&';
}
if (str) {
str = str.substring(str, str.length - 1);
}
return str;
}
3.数据解密规则:
对签名通过后返回的data加密串signdata进⾏base64解码,得到Base64后的串,Base64解码函数decode=>
function decode(input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = place(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = _keyStr.indexOf(input.charAt(i++));
enc2 = _keyStr.indexOf(input.charAt(i++));
enc3 = _keyStr.indexOf(input.charAt(i++));
enc4 = _keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
output = _utf8_decode(output);
return output;
}
// private method for UTF-8 decoding
var _utf8_decode = function (utftext) {
var string = "";
var i = 0;
var c = 0,
c1 = 0,
c2 = 0,
c3 = 0;
while (i < utftext.length) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
} else if ((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i + 1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
} else {
c2 = utftext.charCodeAt(i + 1);
c3 = utftext.charCodeAt(i + 2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
截取BASE64串string长度-4后进⾏MD5,并对MD5后的字符串截取长度15的串,将该串与BASE64串string长度-4后的串进⾏异或运算得到解密后的data字符串=>
function responseencode(data, apiSignModel) {//data => encode string
var isencode = 0;
isencode = apiSignModel;
if (!isencode) {
return data;
}
console.log("---callback-----data---encode--->", data);
data = base64.decode(data);//encodeString
var rand = data.substring(data.length - 4);
var md = md5(rand);
var p = md.substring(0, 16);
console.log("data " + data);
console.log("rand " + rand);
data = data.substring(0, data.length - 4);
data = strox(data, p);
console.log("p " + p);
return data;
}
function strox(str, orstr) {
var result = [];
var len = orstr.length;
for (var i = 0; i < str.length; i++) {
var item = str[i];
var strcode = parseInt(item.charCodeAt().toString(10));
var orcode = parseInt(orstr[i % len].charCodeAt().toString(10));
var rescode = strcode ^ orcode;
var binaryStr = String.fromCharCode(rescode);
result.push(binaryStr);
}
return result.join("");
}
简单来说,异或运算函数是将两个参数1和2相加进⾏异或得到3,再次异或运算后可将3和1进⾏异或就可以得出异或前的数字2.整体代码封装⼀下就是这样:
import md5 from './md5-support.js';
var Base64 = function () {
// private property
var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
// public method for decoding
this.decode = function (input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = place(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = _keyStr.indexOf(input.charAt(i++));
enc2 = _keyStr.indexOf(input.charAt(i++));
enc3 = _keyStr.indexOf(input.charAt(i++));
enc4 = _keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
output = _utf8_decode(output);
return output;
}
// private method for UTF-8 decoding
var _utf8_decode = function (utftext) {
var string = "";
var i = 0;
var c = 0,
c1 = 0,
c2 = 0,
c3 = 0;
while (i < utftext.length) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
} else if ((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i + 1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
} else {
c2 = utftext.charCodeAt(i + 1);
c3 = utftext.charCodeAt(i + 2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
}
var Apisecure = function () {
var base64 = new Base64();
function strox(str, orstr) {
var result = [];
var len = orstr.length;
for (var i = 0; i < str.length; i++) {
var item = str[i];
var strcode = parseInt(item.charCodeAt().toString(10));
var orcode = parseInt(orstr[i % len].charCodeAt().toString(10));
var rescode = strcode ^ orcode;
var binaryStr = String.fromCharCode(rescode);
result.push(binaryStr);
}
return result.join("");
}
function objtostring(data) {
var str = '';
for (var k in data) {
str += k + '=' + encodeURI(data[k]) + '&';
}
if (str) {
str = str.substring(str, str.length - 1);
}
return str;
}
function objKeySort(obj) {//排序的函数
var newkey = Object.keys(obj).sort();
//先⽤Object内置类的keys⽅法获取要排序对象的属性名,再利⽤Array原型上的sort⽅法对获取的属性名进⾏排序,newkey是⼀个数组var newObj = {};//创建⼀个新的对象,⽤于存放排好序的键值对
for (var i = 0; i < newkey.length; i++) {//遍历newkey数组
newObj[newkey[i]] = obj[newkey[i]];//向新创建的对象中按照排好的顺序依次增加键值对
}
return newObj;//返回排好序的新对象
}
this.signrequest = function (data) {
data = objKeySort(data);//请求参数排序
var staticstr = '';
var timestr = parseInt((new Date()).getTime() / 1000);
var oncekey = parseInt(Math.random() * (100000 - 1000 + 1) + 1000, 10);
var wxsmall = md5(oncekey);
console.log("wxsmall:" + wxsmall);
var hash = md5(md5(wxsmall + '' + oncekey));
console.log("hash:" + hash);
var datastr = objtostring(data);
console.log("hash+datastr:" + hash + datastr);
var sign = md5(hash + datastr);
return { "timestr": timestr, "oncekey": oncekey, "wxsmall": wxsmall, "signkey": sign };
}
var isencode = 0;
isencode = apiSignModel;
if (!isencode) {
return data;
}
console.log("---callback-----data---encode--->", data);
data = base64.decode(data);//encodeString
var rand = data.substring(data.length - 4);
var md = md5(rand);
var p = md.substring(0, 16);
console.log("data " + data);
console.log("rand " + rand);
data = data.substring(0, data.length - 4); data = strox(data, p);
console.log("p " + p);
return data;
}
}
Base64,
Apisecure
}
最后附上⼩程序内封装的请求调⽤⽅法=>
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论