签名解密,内容验证

来源:互联网 发布:预科生的贩毒网络免费 编辑:程序博客网 时间:2024/05/21 03:16

前面一个文章里面,我们把一个字符串进行hash计算,并且签名。

现在就需要在接收方来验证了。

CryptImportKey

首先,我们需要把发方发过来的公钥导入到CSP里面。我们这里假设pbKeyBlob就是收到的公钥信息(比如从证书里面获取)。

    if (CryptImportKey(        hProv,        pbKeyBlob,        dwBlobLen,        0,        0,        &hPubKey))    {        printf("The key has been imported.\n");    }    else    {        MyHandleError("Public key import failed.");    }


CryptCreateHash,CrypteHashData

假设pbBuffer就是收到的内容,下面的代码就计算了一个hash值。

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

现在就可以verify了。

CryptVerifySignature

这个API会把pbSignature用hPubKey解密并且和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");    }


就这样,我们可以把发方发过来的数据进行验证了。


附:完整代码

//--------------------------------------------------------------------// Copyright (C) Microsoft.  All rights reserved.// Example of signing a hash and // verifying the hash signature.#pragma comment(lib, "crypt32.lib")#include "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 that is to be 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_RSA_FULL,                CRYPT_NEWKEYSET))            {                MyHandleError("Error during CryptAcquireContext.");            }        }        else        {            MyHandleError("Error during CryptAcquireContext.");        }    }    HCRYPTPROV hCryptProv;    BYTE       pbData[1000];       // 1000 will hold the longest     // key container name.    DWORD cbData;    //-------------------------------------------------------------------    // An HCRYPTPROV must be acquired before using code like that 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 is the public key    // that will 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 not 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意味着密钥不存在,下面就生成一个密钥        {            _tprintf(TEXT("The signature key does not exist./n"));            _tprintf(TEXT("Create a signature key pair./n"));            if (CryptGenKey(                           // CryptGenKey生成一个密钥                hProv,                           //指定CSP模块的句柄                AT_SIGNATURE,                     //对于公钥密码系统,生成一个私钥和一个公钥,这个参数指定了这个密钥是公钥,于是生成了一个密码对。如果不是公钥系统,则指定了密码算法,具体看MSDN。                0,                                  //指定了生成密钥的类型,这个参数的说明挺多的,想获取更为详尽的资料请看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 is exported to a     // PUBLICKEYBOLB so that the receiver of the signed hash can    // verify the signature. This BLOB could be 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 have 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 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.");    }    //-------------------------------------------------------------------    // Determine the size of the signature and allocate 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 verified.    // This would most often be done by a different user in a    // separate program. The hash, signature, and the PUBLICKEYBLOB    // would be read from a file, an email message,     // or some other source.    // Here, the original pbBuffer, pbSignature, szDescription.     // pbKeyBlob, and their lengths are used.    // The contents of the pbBuffer must be the same data     // that was 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 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.");    }    //-------------------------------------------------------------------    // 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");    }    //-------------------------------------------------------------------    // Free memory to be 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 MyHandleError, a simple error//  handling function, to print an error message to the  //  standard error (stderr) file and exit the program. //  For most applications, replace this function with one //  that does more extensive error reporting.void MyHandleError(char *s){    fprintf(stderr, "An error occurred in running the program. \n");    fprintf(stderr, "%s\n", s);    fprintf(stderr, "Error number %x.\n", GetLastError());    fprintf(stderr, "Program terminating. \n");    exit(1);} // End of MyHandleError


0 0
原创粉丝点击