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

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 解决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

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

目录
相关文章
|
2月前
|
数据安全/隐私保护 Python
Python中的MD5加密“解密”
Python中的MD5加密“解密”
|
26天前
|
存储 Java 数据库
密码专辑:对密码加盐加密,对密码进行md5加密,封装成密码工具类
这篇文章介绍了如何在Java中通过加盐和加密算法(如MD5和SHA)安全地存储密码,并提供了一个密码工具类PasswordUtils和密码编码类PasswordEncoder的实现示例。
29 10
密码专辑:对密码加盐加密,对密码进行md5加密,封装成密码工具类
|
21天前
|
JavaScript Java PHP
快速对比:Django、Spring Boot、Node.js 和 PHP
快速对比:Django、Spring Boot、Node.js 和 PHP
46 7
|
26天前
|
NoSQL Java Redis
shiro学习四:使用springboot整合shiro,正常的企业级后端开发shiro认证鉴权流程。使用redis做token的过滤。md5做密码的加密。
这篇文章介绍了如何使用Spring Boot整合Apache Shiro框架进行后端开发,包括认证和授权流程,并使用Redis存储Token以及MD5加密用户密码。
22 0
shiro学习四:使用springboot整合shiro,正常的企业级后端开发shiro认证鉴权流程。使用redis做token的过滤。md5做密码的加密。
|
2月前
|
JavaScript 前端开发 安全
js逆向实战之烯牛数据请求参数加密和返回数据解密
【9月更文挑战第20天】在JavaScript逆向工程中,处理烯牛数据的请求参数加密和返回数据解密颇具挑战。本文详细分析了这一过程,包括网络请求监测、代码分析、加密算法推测及解密逻辑研究,并提供了实战步骤,如确定加密入口点、逆向分析算法及模拟加密解密过程。此外,还强调了法律合规性和安全性的重要性,帮助读者合法且安全地进行逆向工程。
84 11
|
2月前
|
前端开发 数据安全/隐私保护
JS-RSA超长加密
JS-RSA超长加密
49 4
|
30天前
|
数据安全/隐私保护 Python
Python中的MD5加密“解密”
Python中的MD5加密“解密”
|
1月前
|
IDE 开发工具 数据安全/隐私保护
Python编程实现批量md5加密pdf文件
Python编程实现批量md5加密pdf文件
|
3月前
|
算法 JavaScript 前端开发
国标非对称加密:RSA算法、非对称特征、js还原、jsencrypt和rsa模块解析
国标非对称加密:RSA算法、非对称特征、js还原、jsencrypt和rsa模块解析
251 1
|
3月前
|
JavaScript PHP 开发者
PHP中的异常处理与自定义错误处理器构建高效Web应用:Node.js与Express框架实战指南
【8月更文挑战第27天】在PHP编程世界中,异常处理和错误管理是代码健壮性的关键。本文将深入探讨PHP的异常处理机制,并指导你如何创建自定义错误处理器,以便优雅地管理运行时错误。我们将一起学习如何使用try-catch块捕获异常,以及如何通过set_error_handler函数定制错误响应。准备好让你的代码变得更加可靠,同时提供更友好的错误信息给最终用户。