尝试将 Java RSA-PSS 签名验证码使用 SHA256 哈希、SHA1 MGF 哈希转换为 Python

问题描述

这是我的 Java 代码,它按预期成功验证了签名。

Signature sig = Signature.getInstance("RSASSA-PSS");
PssparameterSpec pssparams = new PssparameterSpec(
    "SHA-256","MGF1",new MGF1ParameterSpec("SHA-1"),MessageDigest.getInstance("SHA-256").getDigestLength(),PssparameterSpec.TRAILER_FIELD_BC
);
sig.setParameter(pssparams);

sig.initVerify(publicKey);
sig.update(plaintext.getBytes());
System.out.println(sig.verify(signatureBytes) ? "good" : "bad");

完整代码(包含导入、密钥、消息和签名)可以在 https://pastebin.com/PmhGDaPv 查看,以防您想尝试重现问题。

我的 Python 代码,未按预期验证签名:

hash = Hash.SHA256.new(message.encode("ascii"))
verifier = pss.new(key,mask_func=lambda x,y: pss.MGF1(x,y,Hash.SHA1),salt_bytes=Hash.SHA256.digest_size)
if verifier.verify(hash,signatureBytes):
    print("good")
else:
    print("bad")

完整代码(包含导入、密钥、消息和签名)可以在 https://pastebin.com/f5iW4Xdg 查看,以防您想尝试重现问题。

因此,在两个代码中,哈希都是 SHA256,而 MGF1 哈希是 SHA1。并且salt长度等于SHA256的摘要长度。密钥和签名似乎也相同。怎么了?

解决方法

Crypto.Signature.pss.PSS_SigScheme#verify() 不会将验证结果返回为 True/False,而是在验证失败时抛出 ValueError 异常,即将 if 语句替换为:

try:
    verifier.verify(hash,signatureBytes)
    print("Signature authentic")
except (ValueError):
    print("Signature not authentic")
    

通过此更改,验证成功。在您发布的代码中,verify() 返回 None,因此即使验证成功也会执行 else 分支。