foreword
When doing the front-end and back-end signature verification, md5 encryption was used, and it was found that the front-end and back-end encryption results were inconsistent, resulting in the failure of the signature verification. Here is a summary of the cause of the problem and the solution for your reference. The front end uses the CryptoJS front-end encryption library for encryption.
Problem recurrence
For the convenience of testing, many special characters are used in the field remark.
front end
the code
encryMd5() {
let data = {
name: "卢俊义",
age: 25,
sex: "male",
remark: "dahsdahda~很~快的()哈肯 定='';:,.,。、??/<>-=-=()()好亏·-=啥多看哈 是道坎!@#¥%……&=*()——+=-·",
}
let str = new URLSearchParams(data).toString()
console.log("query_str", str);
console.log("md5_str", CryptoJS.MD5(str).toString());
}
Results of the
The MD5 string obtained after front-end encryption is: 157474853a5d1c06f2607acbd907781d
rear end
the code
$arr = [
"name" => "卢俊义",
"age" => 25,
"sex" => "male",
"remark" => "dahsdahda~很~快的()哈肯 定='';:,.,。、??/<>-=-=()()好亏·-=啥多看哈 是道坎!@#¥%……&=*()——+=-·",
];
$str = http_build_query($arr);
echo $str.PHP_EOL;
echo md5($str).PHP_EOL;
Results of the
The MD5 string obtained after backend encryption is: c398fa37f2a8020a7a12c4bfc5027fbe
Comparative Results
By using Beyond Compare, it is found that in the process of constructing the queryString, the front-end character encoding did not encode the *.
solution
By analyzing the results of the previous step, it can be found that the problem is caused by the difference in encoding at both ends. So just unify the encoding methods on both sides. details as follows:
front end
the code
Use encodeURIComponent to encode field values one by one, and because encodeURIComponent will not encode ~!*()等字符,所以要进行补充编码,具体代码如下:
encryMd5() {
let data = {
name: "卢俊义",
age: 25,
sex: "male",
remark: "dahsdahda~很~快的()哈肯 定='';:,.,。、??/<>-=-=()()好亏·-=啥多看哈 是道坎!@#¥%……&=*()——+=-·",
}
for (let key in data) {
data[key] = (data[key] + '').toString();
data[key] = encodeURIComponent(data[key]).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').
replace(/\)/g, '%29').replace(/\*/g, '%2A')
}
console.log("encode_obj", data);
let str = new URLSearchParams(data).toString()
console.log("query_str", str);
console.log("md5_str", CryptoJS.MD5(str).toString());
}
Results of the
The MD5 string obtained after front-end encryption is: 36b00a7e6ad9dd23df98b50ae529b2d3
rear end
the code
Use the rawurlencode function to uniformly encode field values.
$arr = [
"name" => "卢俊义",
"age" => 25,
"sex" => "male",
"remark" => "dahsdahda~很~快的()哈肯 定='';:,.,。、??/<>-=-=()()好亏·-=啥多看哈 是道坎!@#¥%……&=*()——+=-·",
];
foreach ($arr as $key => $val) {
$arr[$key] = rawurlencode($val);
}
print_r($arr);
$str = http_build_query($arr);
echo $str.PHP_EOL;
echo md5($str).PHP_EOL;
Results of the
It can be seen that the execution results of the two are consistent, and the problem is solved!