标签:des style io os ar for strong 数据 sp
前面一个文章里面,我们把一个字符串进行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
标签:des style io os ar for strong 数据 sp
原文地址:http://blog.csdn.net/zj510/article/details/39993349