首先引入MD5加密库:=>https://cdn.bootcss.com/blueimp-md5/2.10.0/js/md5.min.js;

  步骤:=》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 = input.replace(/[^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;
    }

其中apiSignModel就是responseHeader返回的API-SIGN-MODAL,客户端可以根据该返回参数决定是否对返回的数据串 解密,异或运算是为了得到经过一次异或运算之前的初始加密串,字符串在经过两次异或运算会得到原始的数据,参考https://www.lijinma.com/blog/2014/05/29/amazing-xor/,异或匀速算实现函数=>

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 = input.replace(/[^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 };
}
this.responseencode = function (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;
}
}
module.exports = {
Base64,
Apisecure
}
最后附上小程序内封装的微信请求调用方法=>
 

前端请求参数MD5加密校验,参数串解密的更多相关文章

  1. 前端请求参数MD5加密发送后台

    最近在项目开发中遇到前端发送参数加密的问题,网上查找半天也是很乱,小编自己在项目开发中总结了一下,写到博客中,希望能够帮助大家. 查看所有代码可到我的github上查看源文件,下载后在控制台查看结果即 ...

  2. aip接口中对url参数md5加密防篡改的原理

    目前网上所有开放api的网站中,数据的调用都是采用同一种方式,即: http:www.xxx.com/aa=1&bb=2...,原后对这些参数按字典顺序排序后进行md5加密,将md5加密串与接 ...

  3. android md5加密与rsa加解密实现代码

    import java.io.UnsupportedEncodingException;import java.security.MessageDigest;import java.security. ...

  4. 请求参数MD5加密---函数助手

  5. c#对文件进行MD5加密校验

    public static string GetFileMd5Hash(string strFileFullPath) { // Create a new instance of the MD5Cry ...

  6. 从零开始设计SOA框架(三):请求参数的加密方式

    第二章中说明请求参数有哪些,主要是公共参数和业务参数,服务端需要对参数进行效验,已验证请求参数的合法性 参数效验前先解释下以下参数: 1.参数键值对:包括公共参数.业务参数      1.公共参数:按 ...

  7. mvc url路由参数的加密和解密

    查看某个信息的时候一般会在url上加上该信息在数据库中对应的主键id(而且一般是自增的) url是这样子的 xxxDetail/1 , 虽然对于我们开发人员来说可以这种显式的数据库主键会方便调试过程, ...

  8. jmeter用BeanShell调用jar包对HTTP请求中的参数进行MD5加密

    前提: eclipse.JDK.Jmeter 说明: 本文分为两部分进行配置说明 第一部分:编写JavaMD5加密脚本 第二部分:使用Jmeter的BeanShell进行验证 ************ ...

  9. 六、Jmeter中自动提取Http请求参数,并put到Map,然后进行MD5加密

    1.BeanShell PerOrocessor中的脚本 import src.com.csjin.qa.MD5.*;//个人jar包 import java.util.*; import java. ...

随机推荐

  1. centos6.5 yum update 报错Couldn't resolve host 'centos.ustc.edu.cn'

    异常信息 [root@localhost ~]# yum -y update Loaded plugins: fastestmirror, refresh-packagekit, security S ...

  2. python集合增删改查,深拷贝浅拷贝

    集合 集合是无序的,不重复的数据集合,它里面的元素是可哈希的(不可变类型),但是集合本身是不可哈希(所以集合做不了字典的键)的.以下是集合最重要的两点: 去重,把一个列表变成集合,就自动去重了. 关系 ...

  3. 关于Sublime Text编辑器的实用技巧

    本文转载至一篇博文,为您提供Sublime Text编辑器的12个技巧和诀窍,深入挖掘这个看似简洁的代码编辑器,背后所隐藏的实现各种高级功能的无限可能. 1) 选择 以下是一些Sublime Text ...

  4. ftp 只需上传禁止下载

    一.首先在ftp / 主目录下给所有用户授予读写权限 二.给子目录授予写入权限,不允许读取

  5. C++11新语法糖之尾置返回类型

    C++11的尾置返回类型初衷是为了方便复杂函数的声明和定义,但是当复杂度稍微提升一些的时候很明显能注意到这种设计的作用微乎其微. 首先考虑如下代码: C++ //返回指向数组的指针 auto func ...

  6. Java I/O---序列化接口Serializable

    1.JDK API 中关于Serializable的描述 public interface Serializable 类通过实现 java.io.Serializable 接口以启用其序列化功能.未实 ...

  7. 工厂方法模式(Method Factory),理解多态应用的好例子.

    工厂方法模式又称为多态性工厂,个人认为多态性工厂更能准确的表达这个模式的用处.与简单工厂(静态工厂)相比较,这里的多态性是指抽象出一个工厂基类,将因为一个产品有N种不同的是现这种变化封装起来,将具体的 ...

  8. 关于VS2017安装的一点扩充说明(15.5)

    其实逆天不推荐自己慢慢离线,找个离线包更新下再打包更快 Key:http://www.cnblogs.com/dunitian/p/4667038.html VS完整卸载工具:https://gith ...

  9. [编织消息框架][JAVA核心技术]annotation基础

    应用动态代理技术要先掌握annotation技术 注解是JDK1.5之后才有的新特性,JDK1.5之后内部提供的三个注解 @Deprecated 意思是“废弃的,过时的” @Override 意思是“ ...

  10. C语言--解引用

    昨天,在<C和指针>上面看到"解引用"这个名词,就好奇的去查了查. (下面是一个大一渣渣的理解,请各位朋友海涵,如果有漏洞或者补充希望前辈不吝指正.) 例: #incl ...