# Should I be using PKCS1 v1.5 or PSS for RSA signatures?

I am implementing an application where a user needs to sign some data that they have created, store it in an untrusted place, then later retrieve that data and verify it is still authentic before using it. The user already has a RSA keypair for doing encryption throughout the application so I would like to re-use it for this signature (or else I would normally just use HMAC).

I see that I have two schemes available with RSA signatures: PKCS1 v1.5 and PSS.

• Which of these should I be using? PKCS1 v1.5 seems a bit simpler to implement.
• Are there security concerns with each schemes I should be aware of?
• If I need to use PSS, what digest should I be using? Is SHA1 a concern if used?

Which of these should I be using? PKCS1 v1.5 seems a bit simpler to implement.

Generally you should not be implementing this yourself, there are plenty of libraries that implement these schemes out of the box.

Both the PKCS#1 v1.5 padding for signature generation and PSS padding have pro's and con's which I list below. Which one you decide to use it up to you.

Are there security concerns with each schemes I should be aware of?

PKCS#1 v1.5 padding has two drawbacks.

1. It is deterministic, which is not a requirement for signatures and this can actually be detrimental to security in some very specific situations.
2. It's missing a security proof; PSS has a security proof (for the padding mode, not for RSA itself of course). That said, PKCS#1 v1.5 padding for signature generation has not been broken (unlike PKCS#1 v1.5 padding for encryption, which does have vulnerabilities).

PSS has two drawbacks as well:

1. it is more complex to implement;
2. it is definitely not as prevalent as PKCS#1 v1.5 padding - probably because PKCS#1 v1.5 padding is older and hasn't been broken.

If I need to use PSS, what digest should I be using? Is SHA1 a concern if used?

SHA-1 is definitely an issue if you would use it for hashing the data you use for the signature (regardless of the padding mode), as it isn't collision resistant anymore. A collision resistant hash is a requirement for signature generation algorithm.

SHA-1 isn't a problem if you just use it for the underlying MGF1 used within PSS padding. Of course, for new protocols you'd still go for a more secure cryptographic hash function such as SHA-512.

PSS uses another instance of a hash function for PSS padding for a function called the mask generation function (MGF) which performs the actual padding. MGF1 is the only MGF defined for PSS, and it in turn requires a hash to create the PSS padding: the data hash value is input for MGF1. MGF1 can be compared to HMAC when it comes to security, and SHA-1 is still secure in HMAC.

The two hash functions algorithms can be different than the one used for the data hashing. Some implementations default to SHA-1 and some default to the data hash algorithms. For some reason SHA-256 is often preferred for MGF1 although SHA-512 would make a lot more sense for RSA because it would be more efficient because of its larger output size. As indicated, complexity is a drawback of PSS - even when it comes to configuring the algorithm.

If you decide to use PKCS#1 PSS padding, be sure you document the algorithm you use for both the data and the MGF1 function.

• Also, PKCS1 v1.5 signatures can easily be vulnerable to Bleichenbacher small exponent attack (typically if $e=3$) – Lery Jun 17 '17 at 22:49
• @Lery: As far as I know, there is no attack against the PKCS#1 v1.5 signature scheme even when using small exponents. When we consider implementations of PKCS#1 v1.5 signature, Bleichenbacher's small exponent attack and extensions all make a huge assumption: that the signature verification omits some verifications that are in fact mandated! Contrast with Bleichenbacher's attack on the PKCS#1 v1.5 encryption scheme where conforming implementations of decryption can be vulnerable. – fgrieu Jun 18 '17 at 8:47
• @izzle: CAUTION! if you "store a header with the signed value that shows the hashing functions that were used", you might be vulnerable to a forgery that specifies a broken hash, such as MD5. Signing the header is not an effective fix. The simplest/safest/usual is that the signature verification is done with a prescribed hash, for each given public key. That's why public key certificates usually have a field for the hash algorithm. – fgrieu Jun 18 '17 at 9:00
• On the other hand, the above is mostly theoretical in an RSA PKCS#1 context: for both schemes, absent any other flaw in signature verification, it seems difficult that an adversary could pull a forgery if the signer always uses a secure hash. – fgrieu Jun 18 '17 at 9:26
• @MaartenBodewes: nitpick: v2.0 added OAEP, it was v2.1 that added PSS (and also 'multiprime', meaning > 2, which is very little used). FWIW 2.0 (and 2.1) did drop the near-textbook 'block type 00' signature that was in allowed 1.5. – dave_thompson_085 Dec 8 '17 at 23:24