如何验证MGF与Hash不匹配的RSA-PSS签名?
如何在Go中验证Hash与MGF哈希不匹配的RSA-PSS签名
Go标准库的crypto/rsa包对RSA-PSS的实现有个限制:MGF1掩码生成函数的哈希算法会强制和消息哈希算法保持一致,而PSSOptions结构体并没有提供单独配置MGF哈希的选项。这就导致如果遇到签名时使用了不同哈希组合(比如消息用SHA-256、MGF1用SHA-1)的非标准场景,标准库的VerifyPSS无法直接完成验证。
可行的解决方法
1. 手动实现RFC 8017规定的PSS验证逻辑
你可以参照RFC 8017第9.1.2节的验证步骤自己实现逻辑,核心是单独编写使用指定哈希的MGF1函数:
- 先使用签名对应的消息哈希算法计算原始消息的哈希值
- 实现自定义MGF1函数,传入签名指定的MGF哈希算法生成掩码
- 按照PSS的编码规则构造预期的编码消息(EM),最后将其与解密后的签名值进行对比
简化的伪代码示例:
import ( "crypto" "encoding/binary" ) // 自定义MGF1实现,支持指定哈希函数 func mgf1(seed []byte, maskLen int, hash crypto.Hash) ([]byte, error) { hashInst := hash.New() hashSize := hashInst.Size() mask := make([]byte, maskLen) counter := make([]byte, 4) for i := 0; i < maskLen; i += hashSize { binary.BigEndian.PutUint32(counter, uint32(i/hashSize)) hashInst.Write(seed) hashInst.Write(counter) copy(mask[i:], hashInst.Sum(nil)) hashInst.Reset() } return mask[:maskLen], nil } // 后续按照RFC 8017的验证步骤完成剩余逻辑:解密签名、构造EM、对比验证等
2. 采用支持自定义MGF哈希的第三方密码库
部分第三方密码库扩展了标准库的功能,允许单独配置MGF的哈希算法,比如cloudflare/cfssl的rsa模块、ThalesIgnite/crypto11(适用于硬件加密场景)等,这类库会提供额外的配置选项来满足非标准哈希组合的验证需求。
额外说明
Go标准库的设计遵循RFC 8017的推荐场景(MGF1哈希与消息哈希一致),因此没有支持非标准组合的配置项。而Java中不同加密服务提供商的差异,本质是部分厂商默认实现了非标准的哈希组合,但Go标准库不会兼容这类场景,必须通过上述两种方式解决。
内容的提问来源于stack exchange,提问作者neubert
相关产品推荐
相关产品推荐

