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

trying to convert Java RSA-PSS signature verification code (with SHA256 hash, SHA1 MGF hash) to 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 查看完整代码(包含导入、密钥、消息和签名)。

所以在这两个代码中,Hash 都是 SHA256,而 MGF1 Hash 是 SHA1。并且盐长度等于SHA256的摘要长度。密钥和签名似乎也相同。那怎么了?

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

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

有了这个改动,验证就成功了。在您发布的代码中,verify() returns a None,因此即使验证成功,也会执行 else 分支。