解决php和crypto.js使用md5加密结果不一致问题

简介: 解决php和crypto.js使用md5加密结果不一致问题

前言


在做 前后端验签时,使用到了md5加密,发现前后端加密结果不统一,导致验签失败。这里总结一下问题原因以及解决方法,以供参考。前端使用到了CryptoJS前端加密库进行加密。

问题复现


为了测试方便,字段remark中使用了很多特殊字符。

前端


代码


    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());
    }

执行结果


前端加密后得到的MD5字符串为:157474853a5d1c06f2607acbd907781d

image.png

后端


代码


  $arr = [
    "name"      =>  "卢俊义",
    "age"       =>  25,
    "sex"       =>  "male",
    "remark"    =>  "dahsdahda~很~快的()哈肯 定='';:,.,。、??/<>-=-=()()好亏·-=啥多看哈 是道坎!@#¥%……&=*()——+=-·",
  ];
  $str = http_build_query($arr);
  echo $str.PHP_EOL;
  echo md5($str).PHP_EOL;

执行结果


后端加密后得到的MD5字符串为:c398fa37f2a8020a7a12c4bfc5027fbe

image.png

结果对比


通过使用Beyond Compare比较发现,是在构建queryString的过程中,前端字符编码时没将*号进行编码。

ec4e2056e53f4712be63590822849e1a.png

解决方案


通过对上一步的结果进行分析可以发现,问题是由于两端编码差异造成的。所以只要对两边编码方式进行统一就好。具体如下:

前端


代码


使用encodeURIComponent对字段值逐一进行编码,并且由于encodeURIComponent不会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());
    }

执行结果


前端加密后得到的MD5字符串为:36b00a7e6ad9dd23df98b50ae529b2d3

image.png

后端


代码


使用rawurlencode函数对字段值进行统一编码。

  $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;

执行结果


image.png

可以看到两者执行结果一致,问题解决!

目录
相关文章
|
1天前
|
存储 NoSQL 数据库
认证服务---整合短信验证码,用户注册和登录 ,密码采用MD5加密存储 【二】
这篇文章讲述了在分布式微服务系统中添加用户注册和登录功能的过程,重点介绍了用户注册时通过远程服务调用第三方服务获取短信验证码、使用Redis进行验证码校验、对密码进行MD5加密后存储到数据库,以及用户登录时的远程服务调用和密码匹配校验的实现细节。
认证服务---整合短信验证码,用户注册和登录 ,密码采用MD5加密存储 【二】
|
4天前
|
存储 算法 Java
在Java中使用MD5对用户输入密码进行加密存储、同时登录验证。
这篇文章详细介绍了在Java项目中如何使用MD5算法对用户密码进行加密存储和登录验证,包括加入依赖、编写MD5工具类、注册时的密码加密和登录时的密码验证等步骤,并通过示例代码和数据库存储信息展示了测试效果。
在Java中使用MD5对用户输入密码进行加密存储、同时登录验证。
|
8天前
|
算法 JavaScript 前端开发
对称加密算法解析:DES、AES及其在`pycryptodome` 和 `crypto-js` 模块中的应用
对称加密算法解析:DES、AES及其在`pycryptodome` 和 `crypto-js` 模块中的应用
24 1
|
8天前
|
JavaScript 算法 数据安全/隐私保护
烯牛数据JS逆向:MD5数据加密?不存在的!
烯牛数据JS逆向:MD5数据加密?不存在的!
24 1
|
8天前
|
JavaScript 前端开发 数据安全/隐私保护
雪球JS逆向:阿里系加密acw_sc__v2和反debugger
雪球JS逆向:阿里系加密acw_sc__v2和反debugger
11 1
|
8天前
|
算法 JavaScript 前端开发
消息摘要算法:MD5加密
消息摘要算法:MD5加密
20 1
|
5天前
|
Java C# 数据安全/隐私保护
如何 使 Java、C# md5 加密的值保持一致
如何 使 Java、C# md5 加密的值保持一致
6 0
|
8天前
|
JavaScript 数据安全/隐私保护 Python
东方财富股票数据JS逆向:secids字段和AES加密实战
东方财富股票数据JS逆向:secids字段和AES加密实战
28 0
|
8天前
|
JavaScript 前端开发 数据安全/隐私保护
空气质量在线监测平台JS逆向:请求响应数据加密
空气质量在线监测平台JS逆向:请求响应数据加密
15 0
|
算法 Unix PHP
如何在C#中生成与PHP一样的MD5 Hash Code
原文:如何在C#中生成与PHP一样的MD5 Hash Code   最近在对一个现有的系统进行C#改造,该系统以前是用PHP做的,后台的管理员登陆用的是MD5加密算法。在PHP中,要对一个字符串进行MD5加密非常简单,一行代码即可: md5("Something you want to encrypt.")   直接调用md5()方法,然后将要进行MD5加密的字符串传进去,就可以得到返回的hash code。
1139 0