Solve the problem of inconsistency between php and crypto.js using md5 encryption results

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! 

Guess you like

Origin blog.csdn.net/Douz_lungfish/article/details/127734298