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

使用phpseclib验证Go生成的RSA-PSS签名失败问题求助

RSA-PSS签名跨Go与phpseclib v3验证失败的原因及解决方案

核心问题分析

  1. 填充方式未显式指定:phpseclib v3默认使用PKCS#1 v1.5填充进行签名/验证,而你的Go代码明确使用RSA-PSS填充,两者不匹配导致验证失败。
  2. 哈希输入逻辑不一致:Go的rsa.SignPSS接收的是消息的SHA256哈希值作为输入,而phpseclib默认的verify方法会自动对传入的原始消息计算哈希,若未对齐这一逻辑,会导致验证时的哈希输入不匹配。

修复步骤

1. 修正PHP验证代码,指定PSS填充

在PHP验证代码中添加withPadding(RSA::SIGNATURE_PSS),明确使用PSS填充:

$key = RSA::loadPublicKey('the key');
$result = $key->withPadding(RSA::SIGNATURE_PSS) // 关键:指定PSS填充
              ->withHash('sha256')
              ->withMGFHash('sha256')
              ->verify($message, $signature);

2. 对齐哈希输入逻辑

如果你的Go代码是先计算消息的SHA256哈希,再传入rsa.SignPSS(如下):

message := []byte("your original message")
digest := sha256.Sum256(message)
signature, err := rsa.SignPSS(rand.Reader, key, crypto.SHA256, digest[:], nil)

那么PHP端不能直接传入原始消息调用verify(否则会重复计算哈希),而应使用verifyRaw方法直接传入消息的哈希值:

$key = RSA::loadPublicKey('the key');
// 计算原始消息的SHA256二进制哈希
$digest = hash('sha256', $message, true);
$result = $key->withPadding(RSA::SIGNATURE_PSS)
              ->withHash('sha256')
              ->withMGFHash('sha256')
              ->verifyRaw($digest, $signature);

3. 显式指定盐长度(可选但推荐)

Go的rsa.SignPSS默认使用与哈希长度相等的盐(SHA256对应32字节),phpseclib v3可显式指定该配置以确保完全兼容:

$result = $key->withPadding(RSA::SIGNATURE_PSS)
              ->withHash('sha256')
              ->withMGFHash('sha256')
              ->withSaltLength(RSA::SALT_LENGTH_EQUALS_HASH) // 匹配Go默认盐长度
              ->verifyRaw($digest, $signature);

验证兼容性

调整后,Go生成的签名应能在PHP端正常验证,同时保持PHP生成的签名在两端的兼容性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 19:06:05