In the previous article, we hashed a string and signed it.
Now it needs to be verified by the receiving side.
Cryptimportkey
First, we need to import the public key sent by the sender into the CSP.
We are here if pbKeyBlob is the public key information received (for example, from the certificate).
if (Cryptimportkey ( Hprov, pbKeyBlob, Dwbloblen, 0, 0, &hpubkey)) { printf ("The key has been imported.\n"); } else { myhandleerror ("Public key import failed."); }
Cryptcreatehash,cryptehashdata
If Pbbuffer is what you receive, the following code calculates a hash value.
------------------------------------------------------------------- //Create a new hash object. if (Cryptcreatehash ( Hprov, calg_md5, 0, 0, &hhash)) { printf ("The hash object has been recreated. \ n "); } else { myhandleerror ("Error during Cryptcreatehash."); } ------------------------------------------------------------------- //Compute The cryptographic hash of the Buffer. if (Crypthashdata ( hhash, pbbuffer, Dwbufferlen, 0)) { printf ("The new hash has been Created.\n "); } else { myhandleerror ("Error during Crypthashdata."); }
Now you can verify it.
Cryptverifysignature
This API will decrypt the pbsignature with Hpubkey and compare it to Hhash.
------------------------------------------------------------------- //Validate the digital signature. if (Cryptverifysignature ( hhash, pbsignature, Dwsiglen, hpubkey, NULL, 0)) { printf ("The signature has been verified.\n"); } else { printf ("Signature not validated!\n"); }
In this way, we are able to verify the data sent by the sending party.
Attached: Complete code
--------------------------------------------------------------------//Copyright (C) Microsoft. All rights reserved.//Example of signing a hash and//verifying the hash signature. #pragma comment (lib, "Crypt32.lib") #i Nclude "stdafx.h" #include <stdio.h> #include <windows.h> #include <Wincrypt.h> #define My_encoding_ TYPE (pkcs_7_asn_encoding | x509_asn_encoding) void Myhandleerror (char *s); void main (void) {//------------------------------------------------- ------------------//Declare and initialize variables. Hcryptprov Hprov; byte *pbbuffer = (BYTE *) "The data is hashed and signed."; DWORD Dwbufferlen = strlen ((char *) pbbuffer) + 1; Hcrypthash Hhash; Hcryptkey HKey; Hcryptkey Hpubkey; BYTE *pbkeyblob; BYTE *pbsignature; DWORD Dwsiglen; DWORD Dwbloblen; -------------------------------------------------------------------//Acquire a Cryptographic provider context Handle. if (CryptAcquireContext (&hpROV, L "MyContainer", NULL, Prov_rsa_full, 0)) {printf ("CSP context acquired.\n"); } else {if (GetLastError () = = Nte_bad_keyset) {if (! CryptAcquireContext (&hprov, L "MyContainer", NULL, Prov_rs A_full, Crypt_newkeyset)) {Myhandleerror ("Error during CryptAcquireContext."); }} else {Myhandleerror ("Error during CryptAcquireContext."); }} Hcryptprov Hcryptprov; BYTE pbdata[1000]; Longest//key container name. DWORD cbdata; -------------------------------------------------------------------//An Hcryptprov must is acquired before using CO De like this in//' Example C program Using cryptacquirecontext. ' -------------------------------------------------------------------//Read the name of the Default CSP. cbdata = 1000; CryptGetProvParam (Hprov, Pp_name, pbdata,//should be "Microsoft strong cryptographic Provider" &cbdata, 0); cbdata = 1000; CryptGetProvParam (Hprov, Pp_container, pbdata,//Should be "Mycontainter" &cbdata, 0); -------------------------------------------------------------------//Get the public at signature key. This was the public key//So would be used by the receiver of the hash to verify//the signature. In situations where the receiver could obtain the//sender's public key from a certificate, this step would isn't be Needed. if (Cryptgetuserkey (Hprov, At_signature, &hkey)) {printf ("The SIGNATURE Key has been Acquired. \ n "); } else {if (GetLastError () = = Nte_no_key)//Nte_no_key means that the key does not exist. The following generates a key {_tprintf (the TEXT ("The signature key does not exist./n ")); _tprintf (TEXT ("Create a signature key pair./n"); if (CryptGenKey (////CryptGenKey generates a key Hprov,//Specifies the CSP module's Handle At_signature,//For a public key password system, generate a private key and a public key, which specifies that the key is a public key, and generates a password pair. Assuming that it is not a public key system, the password algorithm is specified and the MSDN is detailed. 0,//Specifies the type of the generated key. There are a lot of explanations for this number, and for more detailed information please see MSDN. &hkey)) {_tprintf (TEXT ("Created a signature key pair./n"); } else {Myhandleerror ("CryptGenKey failed"); }} else {Myhandleerror ("Error during Cryptgetuserkey for Signkey."); }}//-------------------------------------------------------------------//Export the public key. Here the public key was exported to a//PUBLICKEYBOLB so the receiver of the signed hash can//verify the SIG Nature. This BLOB could is written to a file and//sent to another user. if (CryptExportKey (HKey, NULL, PUBLICKEYBLOB, 0, NULL, &dwbloblen)) { printf ("Size of the BLOB for the public key determined. \ n "); } else {myhandleerror ("Error computing BLOB length."); }//-------------------------------------------------------------------//Allocate memory for the pbKeyBlob. if (pbKeyBlob = (byte*) malloc (Dwbloblen)) {printf ("Memory has been allocated for the BLOB. \ n "); } else {Myhandleerror ("Out of memory. \ n "); }//-------------------------------------------------------------------//Do the actual exporting into the key BLOB . if (CryptExportKey (HKey, NULL, PublicKeyBlob, 0, pbKeyBlob, &dwbloblen)) {printf ("Contents has been written to the BLOB. \ n "); } else {Myhandleerror ("Error during CrypteXportkey. "); -------------------------------------------------------------------//Create the hash object. if (Cryptcreatehash (Hprov, calg_md5, 0, 0, &hhash)) {printf ("Hash objec T created. \ n "); } else {Myhandleerror ("Error during Cryptcreatehash."); }//-------------------------------------------------------------------//Compute The cryptographic hash of the BUF Fer. if (Crypthashdata (Hhash, Pbbuffer, Dwbufferlen, 0)) {printf ("The data buffer has B Een hashed.\n "); } else {Myhandleerror ("Error during Crypthashdata."); }//-------------------------------------------------------------------//Determine the size of the signature and a Llocate memory. Dwsiglen = 0; if (Cryptsignhash (Hhash, at_signature, NULL, 0, NULL, &dwsiglen)) { printf ("Signature length%d found.\n ", Dwsiglen); } else {Myhandleerror ("Error during Cryptsignhash."); }//-------------------------------------------------------------------//Allocate memory for the signature buffer. if (pbsignature = (BYTE *) malloc (Dwsiglen)) {printf ("Memory allocated for the signature.\n"); } else {Myhandleerror ("Out of memory."); }//-------------------------------------------------------------------//Sign the hash object. if (Cryptsignhash (Hhash, At_signature, NULL, 0, Pbsignature, &dwsiglen)) {printf ("Pbsignature is the hash signature.\n"); } else {Myhandleerror ("Error during Cryptsignhash."); }//-------------------------------------------------------------------//Destroy the hash object. if (Hhash) Cryptdestroyhash (Hhash); printf ("The hash object has been destroyed.\n"); printf ("The signing phase of this program is completEd.\n\n "); -------------------------------------------------------------------//In the second phase, the hash signature is ver Ified. This would most often is done by a different user in A//separate program. The hash, signature, and the PublicKeyBlob//would is read from a file, an e-mail message,//or some other source. Here, the original pbbuffer, Pbsignature, szdescription. pbKeyBlob, and their lengths are used. The contents of the Pbbuffer must is the same data//that is originally signed. -------------------------------------------------------------------//Get The public key of the user who created the Digital signature//and import it into the CSP by using Cryptimportkey. This returns//a handle to the public key in Hpubkey. if (Cryptimportkey (Hprov, pbKeyBlob, Dwbloblen, 0, 0, &hpubkey)) { printf ("The key has been imported.\n"); } else { Myhandleerror ("Public key import failed."); }//-------------------------------------------------------------------//Create a new hash object. if (Cryptcreatehash (Hprov, calg_md5, 0, 0, &hhash)) {printf ("the hash O Bject has been recreated. \ n "); } else {Myhandleerror ("Error during Cryptcreatehash."); }//-------------------------------------------------------------------//Compute The cryptographic hash of the BUF Fer. if (Crypthashdata (Hhash, Pbbuffer, Dwbufferlen, 0)) {printf ("The new hash has been Created.\n "); } else {Myhandleerror ("Error during Crypthashdata."); }//-------------------------------------------------------------------//Validate the digital signature. if (Cryptverifysignature (Hhash, Pbsignature, Dwsiglen, Hpubkey, NULL, 0)) { printf ("The signaturehas been verified.\n "); } else {printf ("Signature not validated!\n"); }//-------------------------------------------------------------------//free memory to being used to store signature . if (pbsignature) free (pbsignature); -------------------------------------------------------------------//Destroy the hash object. if (Hhash) Cryptdestroyhash (Hhash); -------------------------------------------------------------------//Release the provider handle. if (Hprov) cryptreleasecontext (Hprov, 0);} End of main//-------------------------------------------------------------------//This example uses the function My HandleError, a simple error//handling function, to print an error message to the//Standard error (stderr) file and E XIT the program. For most applications, replace the This function with one//so does more extensive error reporting.void Myhandleerror ( Char *s) {fprintf (stderr, "An error occurred In running. \ n "); fprintf (stderr, "%s\n", s); fprintf (stderr, "Error number%x.\n", GetLastError ()); fprintf (stderr, "program terminating. \ n "); Exit (1);} End of Myhandleerror
Signature decryption, content validation