本文实现完整流程,对数据进行Hash,签名,验证签名。程序的流程性较强,或许这就是测试CSP应该有的步骤吧。
本程序使用VS2005编译运行通过。注意在导出头文件的时候,头文件的顺序十分重要,就如同本程序中,
<wincrypt.h>在编译的过程中大量的使用了<windows.h>,因此在引入头文件的顺序时,要首先引入<windows.h>,然后引入<wincrypt.h>.
#include <stdio.h> #include <stdlib.h> #include <windows.h> #include <wincrypt.h> void main() { HCRYPTPROV hProv; BYTE* puBuffer = (BYTE*)"data hash and sign."; DWORD dwBufferLen = strlen((char*)puBuffer) + 1; HCRYPTHASH hHash; HCRYPTKEY hKey; //签名密钥句柄 HCRYPTKEY hPubKey; BYTE* pbKeyBlob; //保存密钥blob缓冲区指针 BYTE* pbSignature; DWORD dwSigLen; DWORD dwBlobLen; DWORD i; if(CryptAcquireContext(&hProv,"test",NULL,PROV_RSA_FULL,0)) printf("打开句柄成功\n"); else { if(!CryptAcquireContext(&hProv,"test",NULL,PROV_RSA_FULL,CRYPT_NEWKEYSET)) printf("创建失败。\n"); } if(CryptGetUserKey(hProv,AT_SIGNATURE,&hKey)) printf("获得签名密钥成功。\n"); else { printf("获取失败,现在创建新的RSA密钥对。\n"); if(!CryptAcquireContext(&hProv,"test",NULL,PROV_RSA_FULL,0)) printf("获取CSP句柄失败\n"); if(!CryptGenKey(hProv,2,CRYPT_EXPORTABLE | 0X04000000,&hKey)) printf("CryptGenKey error.\n"); } if(CryptExportKey(hKey,NULL,PUBLICKEYBLOB,0,NULL,&dwBlobLen)) printf("we get the length of the public key.\n"); else printf("CryptExportKey erro.\n"); if(pbKeyBlob = (BYTE*)malloc(dwBlobLen)) printf("we get the memory.\n"); else printf("malloc erro.\n"); if(CryptExportKey(hKey,NULL,PUBLICKEYBLOB,0,pbKeyBlob,&dwBlobLen)) printf("export the public key.\n"); else printf("CryptExportKeya error.\n"); if(CryptCreateHash(hProv,CALG_SHA1,0,0,&hHash)) printf("CreateHash succeed.\n"); else printf("CreatHash error.\n"); if(CryptHashData(hHash,puBuffer,dwBufferLen,0)) printf("HashData succeed.\n "); else printf("HashData error.\n"); dwSigLen = 0; if(CryptSignHash(hHash,AT_SIGNATURE,NULL,0,NULL,&dwSigLen)) printf("Get the length of signature.\n"); else printf("CryptSignHash error.\n"); if(pbSignature = (BYTE*) malloc(dwSigLen)) printf("get the memory.\n"); else printf("memory error.\n"); if(CryptSignHash(hHash,AT_SIGNATURE,NULL,0,pbSignature,&dwSigLen)) printf("signature succeed.\n"); else printf("Signature error.\n"); printf("Signature: \n"); for(i=0;i<dwSigLen;i++) { if((i==0) && (i!=0)) printf("\n"); printf("%2.2x",pbSignature[i]); } printf("\n"); printf("OK.\n"); if(hHash) CryptDestroyHash(hHash); if(CryptImportKey(hProv,pbKeyBlob,dwBlobLen,0,0,&hPubKey)) printf("Import the key.\n"); else printf("erro"); if(CryptCreateHash(hProv,CALG_SHA1,0,0,&hHash)) printf("创建哈希对象成功 \n"); else printf("调用CryptCreateHash失败"); if(CryptHashData(hHash,puBuffer,dwBufferLen,0)) printf("数据哈希完成.\n"); else printf("调用CryptHashData失败"); if(CryptVerifySignature(hHash,pbSignature,dwSigLen,hPubKey,NULL,0)) printf("验证签名成功。\n"); else printf("签名验证失败,签名无效"); if(pbSignature) free(pbSignature); if(hHash) CryptDestroyHash(hHash); if(hProv) CryptReleaseContext(hProv,0); system("pause"); }