You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用PHP OpenSSL验证RSA-SHA256签名失败问题排查

数字签名验证失败的解决方案

核心问题分析

前后端签名/验证流程存在两处关键不一致:

  1. 后端手动计算SHA256哈希并传入验证函数,但openssl_verify会自动对原始数据执行哈希运算,且未指定SHA256算法(默认用SHA1)
  2. 前后端生成的JSON字符串可能存在格式差异(如键顺序、转义规则),导致哈希源数据不一致

步骤1:修正后端验证逻辑

修改VerifyDigitalSignature函数

指定SHA256算法,让openssl_verify自动处理哈希:

public static function VerifyDigitalSignature($data, $base_64_digital_signature, $public_key){
    // 明确指定SHA256算法,匹配前端签名逻辑
    $isVerified = openssl_verify($data, base64_decode($base_64_digital_signature), $public_key, OPENSSL_ALGO_SHA256);
    return $isVerified;
}

修改validateRsaLogin函数

移除手动哈希步骤,确保传入原始JSON字符串,同时统一JSON生成规则:

public function validateRsaLogin(Request $request){
    // 对参数数组按键名排序,保证前后端JSON键顺序一致
    $params = $request->post('Parameters');
    ksort($params);
    
    // 统一JSON转义规则,避免斜杠、Unicode字符转义差异
    $parameters = json_encode($params, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
    
    // 直接传入原始JSON字符串进行验证,不再手动哈希
    $signature = RsaKeys::VerifyDigitalSignature(
        $parameters,
        $request->header('base64signature'),
        base64_decode($request->header('base64publickey'))
    );

    return match($signature){
        1 => true,
        0 => false,
        default => -1
    };
}

步骤2:同步前端JSON生成规则

确保前端生成签名用的JSON字符串和后端完全一致,需对参数对象按键排序后再转JSON:

// 新增键排序函数
const sortObjectKeys = (obj: Record<string, any>): Record<string, any> => {
    return Object.keys(obj).sort().reduce((res, key) => {
        res[key] = obj[key];
        return res;
    }, {} as Record<string, any>);
};

// 生成签名前先处理参数
const params = { /* 你的请求参数 */ };
const sortedParams = sortObjectKeys(params);
// 生成无空格、无额外转义的JSON字符串
const jsonStr = JSON.stringify(sortedParams);

// 传入generateSignature2生成签名
const signature = generateSignature2(jsonStr, privateKeyPem);

额外检查项

  1. 公钥格式验证:后端解码后的公钥必须是标准PEM格式(包含-----BEGIN PUBLIC KEY-----和-----END PUBLIC KEY-----),若前端传的是去除头尾的公钥内容,需在后端手动补全PEM头尾
  2. 填充方式一致性:前端forge默认使用PKCS#1 v1.5填充,后端openssl_verify默认也是该填充方式,无需额外修改
  3. 字符编码:确保前后端处理字符串时都使用UTF-8编码,避免中文等非ASCII字符的编码差异

内容的提问来源于stack exchange,提问作者Hayfa chouchene

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 05:50:18