首页 > 代码库 > 签名解密,内容验证

签名解密,内容验证

前面一个文章里面,我们把一个字符串进行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 = http://www.mamicode.com/1000;>

签名解密,内容验证