trying to convert Java RSA-PSS signature verification code (with SHA256 hash, SHA1 MGF hash) to Python

Tags: , , , ,



Here’s my Java code, which successfully verifies the signature, as expected.

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");

The full code (with the imports, keys, message and signature) can be seen at https://pastebin.com/PmhGDaPv in case you want to try to reproduce the issue.

My Python code, which does not verify the signature, as expected:

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")

The full code (with the imports, keys, message and signature) can be seen at https://pastebin.com/f5iW4Xdg in case you want to try to reproduce the issue.

So in both codes the Hash is SHA256 and the MGF1 Hash is SHA1. And the salt length is equal to the digest length of SHA256. The key and signature appear to be the same as well. So what’s up?

Answer

Crypto.Signature.pss.PSS_SigScheme#verify() does not return the result of the verification as True/False, but throws a ValueError exception if the verification fails, i.e. replace the if-statement with:

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

With this change, the verification is successful. In the code you posted, verify() returns a None, so the else-branch is executed even though verification is successful.



Source: stackoverflow