Content hash, signature (Windows Crypt API)

Source: Internet
Author: User
Tags crypt

Windows provides the Crypto API, using these APIs, we can more easily implement hash, signature and so on. There's a lot of information on MSDN,

http://technet.microsoft.com/zh-cn/library/aa382371

The following example computes a hash of a given string and signs the hash value. The given string is as follows:

byte *pbbuffer = (BYTE *) "The data is hashed and signed.";

CryptAcquireContext

The first API to use is CryptAcquireContext.

The prototype is as follows:

BOOL WINAPI cryptacquirecontext (  _out_  Hcryptprov *phprov,  _in_   lpctstr pszcontainer,  _in_   lpctstr Pszprovider,  _in_   DWORD dwprovtype,  _in_   DWORD dwFlags);

Pszcontainter is a string that can specify the name of key container.

Pszprovider Specifies the CSP, which, if NULL, is the default CSP.

Dwprovtype the specified type

See MSDN for more information.

CryptAcquireContext will first look for the specified CSP, and then find the specified key container. If successful, returns the handle (first parameter) of a CSP.

The following code is a simple example. When the program executes for the first time, the first cryptacquirecontext fails because the "MyContainer" key container does not exist at all, so that we can create one. Once created, it can be acquired directly in the future.

-------------------------------------------------------------------    //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_rsa_full,                crypt_newkeyset )            {                myhandleerror ("Error during CryptAcquireContext.");}        }        else        {            myhandleerror ("Error during CryptAcquireContext.");        }    }


Cryptgetuserkey

This API can get the key inside the key container, and the first call will fail, because it doesn't exist yet, we can try to create one. According to MSDN, a key container has only one key. The newly created will overwrite the old ones.

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, and the following generates a key {            _tprintf (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 public key cryptography, generates a private key and a public key, which specifies that the key is a public key, and generates a pair of passwords.                If it is not a public key system, the password algorithm is specified, specifically for MSDN.                0,//Specifies the type of the generated key, this parameter is a lot of description, want to get 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."); }    }


CryptExportKey

We can export the public key inside the key through CryptExportKey, and then we can write to a file or send it to someone through the network. The following example is exported to a buffer inside. Note that the first parameter here is returned by the cryptgetuserkey above.

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

The next step is to calculate a hash value for the specified string.

Cryptcreatehash and Crypthashdata

First use Cryptcreatehash to create a hash object, using MD5.

The hash object is then used to compute a MD5 value for a specified buffer. The final hash value is stored inside the hash object Hhash.

    -------------------------------------------------------------------    //Create the hash object.    if (Cryptcreatehash (        Hprov,        calg_md5,        0,        0,        &hhash))    {        printf ("Hash Object Created. \ n ");    }    else    {        myhandleerror ("Error during Cryptcreatehash.");    }    -------------------------------------------------------------------    //Compute The cryptographic hash of the Buffer.    if (Crypthashdata (        hhash,        pbbuffer,        Dwbufferlen,        0))    {        printf ("The data buffer has been hashed.\n ");    }    else    {        myhandleerror ("Error during Crypthashdata.");    }


Now that the hash value is there, then the signature is next.

Cryptsignhash

This API allows you to sign the hash value (MD5) inside the Hhash, which is used to encrypt the key. (the key also exists in Hhash because the Hhash itself is the Hprov created above)

The following code first requires a technical signature, and then allocates a piece of memory. This cryptsignhash success, after the signature of the ciphertext is stored in the psignature inside. At this point, we have successfully obtained a hash value of a given content of the signature (ciphertext).

    -------------------------------------------------------------------//Determine the size of the signature and al    Locate 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."); }


Now we have a

1. Content: Byte *pbbuffer = (BYTE *) "The data is hashed and signed.";

2. The hash value after the signature (ciphertext) psignature

3. Public Key pbKeyBlob

We can send these 3 messages to each other, and the other person needs

1. Decrypt the signature with the public key (in fact, verify the public key (certificate), this is another matter)

2. Hash calculation of received content

3. Compare the signature in # # to the hash value calculated in # #, and if the same, it means the data is valid. If not, then the data is corrupted, it is possible that the transfer process has been modified, or lost. Note that, as for others posing the problem, in fact, by verifying the public key to ensure that the public key and user information generally need to be sent to each other, that is, certificates. This way the other side can verify the authenticity of the certificate. This is used to prevent someone from impersonating, using their own certificates. For example, the normal trading parties are a and b,a are customers. C can intercept this network packet, then C forge the content, and sign with C's own private key, and send a certificate containing the public key to B. If B does not check the issued certificate, then it can be cheated. A CA is required to authenticate the certificate. The certificate itself is also signed, and the certificate signature's public key is in the top-level certificate of the current certificate until the last root certificate (that is, the root certificate owned by the CA).

OK, the specific verification signature will be introduced next time.




Content hash, signature (Windows Crypt API)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.