I'm implementing hashing (aka. digest) and signing in an app that uses the OpenSSL EVP API. However the API has three very similar methods, which are confusing:
Sign
which sounds like it should be used for signing, however EVP_SignInit
is simply a #define
to EVP_DigestInit
Digest
which seems like it can only be used only for hash generation, there is no way to specify an EVP_PKEY
.DigestSign
which looks like it does both the hashing and the signing.But the documentation recomments to use DigestSign
for signing (and not the actual Sign
).
I'm not a cryptography expert, so this is very confusing to me. What is the difference between them? Which one is a good choice for implementing signing?
The following can be found in the documentation for EVP_SignInit
:
Since the private key is passed in the call to
EVP_SignFinal()
any error relating to the private key (for example an unsuitable key and digest combination) will not be indicated until after potentially large amounts of data have been passed throughEVP_SignUpdate()
.It is not possible to change the signing parameters using these function.
The previous two bugs are fixed in the newer
EVP_SignDigest()
function.
Note: I copied this verbatim, the functions are called EVP_DigestSign
not EVP_SignDigest
.
So it is a replacement function for two bugs that couldn't be amended by the previous API. Of course you'd want to have the old API to be there and behave the same way for backward compatibility.
So the old API didn't adhere to the principles of fail fast or least surprise; you don't want to crash after hashing the message because a bad scheme is used: the scheme to use is generally established beforehand.