当前位置: 首页 > news >正文

Java对接支付宝,回调验签失败

Java对接支付宝,回调验签失败

  • 1.验签的方法使用
  • 2.对于乱码的处理
    • 相关依据

此处是我遇到问题时的解决办法,若不适用,请再寻他法

1.验签的方法使用

//若使用AlipayConfig.SIGN_TYPE = "RSA2",使用下面的验签方法
boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, "UTF-8",AlipayConfig.SIGN_TYPE);
//若使用AlipayConfig.SIGN_TYPE = "RSA",使用下面的验签方法
boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, "UTF-8");

2.对于乱码的处理

解析HttpServletRequest—>map 的时候注意,在没有出现乱码的情况时候不要加valueStr = new String(valueStr.getBytes(“ISO-8859-1”), “utf-8”);否则可能导致验签失败
示例代码

// 1. 读取支付宝回调的参数并转换为Map
request.setCharacterEncoding("UTF-8");
Map < String, String > params = new HashMap < > ();
Map < String, String[] > requestParams = request.getParameterMap();log.info("【支付宝回调】请求ID:{},开始解析请求参数,参数数量:{}",requestId, requestParams.size());for (Iterator < String > iter = requestParams.keySet().iterator(); iter.hasNext();) {String name = iter.next();String[] values = requestParams.get(name);String valueStr = "";for (int i = 0; i < values.length; i++) {valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";}// 解决可能的乱码问题// valueStr = new String(valueStr.getBytes("ISO-8859-1"), "UTF-8");params.put(name, valueStr);log.debug("【支付宝回调】请求ID:{},解析参数:{}={}", requestId, name, valueStr);
}

代码里当我注释掉valueStr = new String(valueStr.getBytes("ISO-8859-1"), "UTF-8");反而可以验签成功
总结:
1.代码里在接收时设置

request.setCharacterEncoding("UTF-8");

2.具体的转map里不要再去用

valueStr = new String(valueStr.getBytes("ISO-8859-1"), "UTF-8")

相关依据

签名验证本质上是对原始数据的哈希 / 加密校验,编码转换会直接改变字符串的字节序列,从而导致验签失败。

  1. 签名验证的核心逻辑
    支付宝等第三方平台的回调签名,是基于原始请求参数的字节序列通过特定算法(如 RSA)生成的。验证签名时,系统会:
    ● 重新将当前参数按规则拼接成字符串
    ● 对该字符串的字节序列进行加密 / 哈希
    ● 与回调中传递的签名值对比,一致则验签通过

  2. valueStr = new String(valueStr.getBytes("ISO-8859-1"), "UTF-8");风险
    逻辑:

    • 先将valueStr按ISO-8859-1编码转为字节数组(getBytes(“ISO-8859-1”))
    • 再将字节数组按UTF-8编码转回字符串(new String(…, “UTF-8”))

    风险:

    • 如果valueStr中包含中文、特殊符号等非 ASCII 字符,ISO-8859-1是单字节编码,无法正确表示这些字符(会用?或其他乱码替代
    • 此时通过ISO-8859-1获取的字节数组已经是 “损坏” 的,再用UTF-8转回字符串时,会产生与原始字符串完全不同的字符序列
      例如:
      ● 原始字符串"测试"的 UTF-8 字节是[-26, -75, -117, -25, -107, -116]
      ● 若按ISO-8859-1转换,会得到错误的字节数组(如[63, 63],63是?的 ASCII 码)
      ● 再转成 UTF-8 字符串可能变成"??",与原始值完全不同

    对验签的直接影响:
    改变参数中包含非 ASCII 字符的valueStr的实际内容(如中文变乱码)
    ● 导致重新拼接的参数字符串与支付宝生成签名时的原始字符串不一致
    ● 最终计算出的签名值与回调中的签名不匹配,验签失败
    总结:
    1.确保从请求中读取参数时就使用正确的编码(如支付宝回调默认是 UTF-8)
    2.如果requestParams是从HttpServletRequest中获取的,应先通过request.setCharacterEncoding(“UTF-8”)设置请求编码,而非在参数解析后手动转换
    3.编码转换应在参数读取阶段完成,而非在验签前的参数处理阶段,否则必然破坏原始数据的字节序列,导致验签失败。
    对比:
    在这里插入图片描述
    在这里插入图片描述

http://www.dtcms.com/a/324344.html

相关文章:

  • 活动策划(展会、年会),在线工具能快速出邀请函不?
  • [创业之路-537]:经营分析会 - 销售目标以及支撑、关键策略、主要行动措施、资源保障、人才储备
  • 在 JDK 17 上完整观察 synchronized 锁升级过
  • 嵌入式第二十四课!!linux应用软件编程与文件操作!!!
  • Java 基础编程案例:斐波拉契数与从输入交互到逻辑处理
  • NodeJs学习日志(4):路由合并_环境配置_常用文件目录
  • HarmonyOS之module.json5功能详解
  • AI测试助手如何让Bug无处可藏
  • 湖南(源点咨询)市场调研 如何在行业研究中快速有效介入 中篇
  • 深入浅出DBSCAN:基于密度的聚类算法详解与Python实战
  • github上传文件
  • Navicat 无限适用
  • Tesseract训练个人字库操提高准确率操作全流程(详细)
  • 新手向:Python制作简易音乐播放器
  • Python中的 __name__
  • 遇到前端导出 Excel 文件出现乱码或文件损坏的问题
  • 异或循环冗余
  • Python设计模式 - 装饰模式
  • 新手向:Python实现文件加密解密工具
  • 旅行者1号无线电工作频段
  • 18.3 全量微调:数据预处理之清洗与准备
  • 机器学习——DBSCAN 聚类算法 + 标准化
  • 实现两个开发板的串口通讯(基于STC8实现)
  • 复刻苏宁易购(移动端)
  • 【GPT入门】第44课 检查 LlamaFactory微调Llama3的效果
  • cursor, vscode黄色波浪线警告问题
  • React:useEffect 与副作用
  • 小巧实用的工具——ZoomIt
  • 【C++对象诞生全解析】构造函数:从内存布局到高效初始化的终极指南
  • 152-基于CWT-CNN-BiGRU-Attention-SABO-LSSVM对滚动轴承的故障诊断