使用PHP gree/jose库校验webhook签名返回false的解决方案咨询
问题根因
你的代码存在三个核心错误导致验签失败:
- 错误调用
sign()方法生成验签参数:验签操作无需本地生成签名,传入verify()的第二个参数应该是对请求头中Signature字段base64解码后的原始签名值 - 冗余的公钥处理逻辑:
JOSE_JWK::decode($components)返回的phpseclib RSA实例已经完成公钥加载,不需要再调用createKey()、loadKey()重复处理 - 未指定匹配的签名哈希算法:官方标注的
RSA256对应SHA256哈希算法,需要手动设置算法匹配。
修复后可运行代码
// 原始参数保持不变 $signature = '1IJl6VyKU4pYfqMHUd55QBNq5Etbz5a7DOCkID2Nloay76y4f02w2iMXONlyL/Bx9SkrbivOHW1l1XadkUrd5pKUK1fhpcnItukLrsK5ADQOcuEjSLBg9qJffZYooXfc7hOD/fV0sN33W2vBYJspbR3P766DwG/6IO/20f9t/DcSWa79EFZPMnsCicEArNS3iIYBtdZSX5ta5EETt7S8acHbpIlSDrTcYpo0vuz19LQ6SPQqN2LGdR+U7ZOiUQWdfMXhUgE7w94pHQzcOq1IHfw3CylUEcRR/DhrGqs4mBaagO6JpWzeqE1uTAiN579kOtSSqjblTb2AXALTQ3+TtA=='; $payload = '{"eventId":"569886904","officeId":"132917981","eventType":"INTEGRATION_DEACTIVATED","event":{"integration":{"status":"INACTIVE","webhookId":"2bc47eed-08a0-4d18-a5c0-b7f18ab802e3","officeId":"132917981","createdDateTime":"2020-03-17T23:39:41.804Z","lastUpdatedDateTime":"2020-03-17T23:39:41.804Z"}},"createdDateTime":"2020-03-17T23:39:41.806Z"}'; $components = [ 'kty' => 'RSA', 'e' => 'AQAB', 'n' => 'ANV-aocctqt5xDRnqomCgsO9dm4hM0Qd75TqG7z2G5Z89JQ7SRy2ok-fIJRiSU5-JfjPc3uph3gSOXyqlNoEh4YGL2R4AP7jhxy9xv0gDVtj1tExB_mmk8EUbmj8hTIrfAgEJrDeB4qMk7MkkKxhHkhLNEJEPZfgYHcHcuKjp2l_vtpiuR9Ouz0febB9K4gLozrp9KHW2K-m0z02-tSurxmmij5nnJ-CEgp0wXcCS4w4G0jve4hcLlL9FU8HKxrb0d4rMQgM3VAal6yG5pwMdtrsch7xA-occwWFC_tHgpDJGNvOJNFtuk7Cit_aom-6U6ssGF13sUtdrog2ePWjVxc=', 'kid' => '2020-03-18', 'alg' => 'RSA256', ]; // 修复后的验签逻辑 $rsa = JOSE_JWK::decode($components); // 指定使用SHA256作为哈希算法,匹配RSA256签名规则 $rsa->setHash('sha256'); // 签名格式设置为PKCS1,匹配通用RSA签名规范 $rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1); // 对原始签名base64解码后直接传入verify方法 $verifyResult = $rsa->verify($payload, base64_decode($signature)); var_dump($verifyResult); // 输出 bool(true)
注意事项
- 生产环境使用时,需要确保请求体获取的内容和签名时的原始内容完全一致,不要有多余的空格、换行或者编码转换
- 如果后续第三方服务更新了JWK的kid,需要同步更新
$components的取值,避免公钥不匹配导致验签失败
内容的提问来源于stack exchange,提问作者mickmackusa
相关产品推荐
相关产品推荐

