Difference between revisions of "EVP Signing and Verifying"

From OpenSSLWiki
Jump to navigationJump to search
Line 73: Line 73:
 
[[Category:Crypto API]]
 
[[Category:Crypto API]]
 
[[Category:C level]]
 
[[Category:C level]]
 +
[[Category:Examples]]

Revision as of 18:10, 24 March 2013

There are two APIs available for performing sign and verify operations. The older EVP_Sign* functions, and the newer and more flexible EVP_DigestSign* functions. They are very similar, but for new applications the EVP_DigestSign* versions should be preferred.

Signing a Message

Signing a message is a three stage process:

  • Initialise the operation and identify the message digest/hash function that will be used during the sign operation.
  • Add message data (this step can be repeated as many times as necessary to add more message data)
  • Create the signature

In order to initialise the operation, you need to have first set up a EVP_PKEY object containing a public key for an algorithm that supports signing (this includes MAC codes). Refer to Working with EVP_PKEYs for further information. You also need to provide a message digest algorithm (refer to Working with Algorithms and Modes).

See the following for an example of signing a message:

EVP_MD_CTX *mdctx = NULL;
int ret = 0;

*sig = NULL;

/* Create the Message Digest Context */
if(!(mdctx = EVP_MD_CTX_create())) goto err;

/* Initialise the DigestSign operation - SHA-256 has been selected as the message digest function in this example */
if(1 != EVP_DigestSignInit(mdctx, NULL, EVP_sha256(), NULL, key)) goto err;

/* Call update with the message */
if(1 != EVP_DigestSignUpdate(mdctx, msg, strlen(msg))) goto err;

/* Finalise the DigestSign operation */
if(1 != EVP_DigestSignFinal(mdctx, *sig, slen)) goto err;
if(!(*sig = OPENSSL_malloc(sizeof(unsigned char) * (*slen)))) goto err;
if(1 != EVP_DigestSignFinal(mdctx, *sig, slen)) goto err;

/* Success */
ret = 1;

err:
if(ret != 1)
{
  /* Do some error handling */
}

/* Clean up */
if(*sig && !ret) OPENSSL_free(*sig);
if(mdctx) EVP_MD_CTX_destroy(mdctx);

Note: There is no difference in the API between signing using an asymmetric algorithm, and generating a MAC code. In the case of CMAC no message digest function is required (NULL can be passed). Signing using the EVP_Sign* functions is very similar to the above example, except there is no support for MAC codes. Note that CMAC is only supported in the (as yet unreleased) version 1.1.0 of OpenSSL.

Refer to http://www.openssl.org/docs/crypto/EVP_DigestSignInit.html for further details on the EVP_DigestSign* functions, and http://www.openssl.org/docs/crypto/EVP_SignInit.html for the EVP_Sign* functions.

Verifying a Message

Verifying a message is very similar to signing except the EVP_DigestVerify* functions (or EVP_Verify* functions) are used instead. Clearly only a public key is required for a verify operation:

if(1 != EVP_DigestVerifyInit(mdctx, NULL, EVP_sha256(), NULL, key)) goto err;
if(1 != EVP_DigestVerifyUpdate(mdctx, msg, strlen(msg))) goto err;
if(1 == EVP_DigestVerifyFinal(mdctx, sig, slen))
{
  /* Success */
}
else
{
  /* Failure */
}

Note: MAC operations do not support the verify operation. Verifying a MAC code is done by calling the sign operations and confirming that the generated code is identical to the one provided.

Refer to http://www.openssl.org/docs/crypto/EVP_DigestVerifyInit.html and http://www.openssl.org/docs/crypto/EVP_VerifyInit.html for further information on the verify functions.

See also