⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 inituser.c

📁 C++编程实践与技巧一书各章节的源码
💻 C
字号:
//signver.c 签名和验证签名程序演示
#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void HandleError(char *s);

void main(void)
{
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;
LPTSTR szDescription = "Test Data Description";

//获取默认CSP
if(CryptAcquireContext(
   &hProv, 
   NULL, 
   NULL, 
   PROV_RSA_FULL, 
   0)) 
{
     printf("已获取CSP上下文\n");
}
else
{
     HandleError("调用CryptAcquireContext函数出错");
}
//--------------------------------------------------------------------
// 获取签名密钥的公钥,该公钥将被哈希值接收者利用验证签名。
//一般公钥都通过证书获取,后面的章节中会有介绍。
if(CryptGetUserKey(   
   hProv,    
   AT_SIGNATURE,    
   &hKey)) 
{
    printf("已获取签名密钥\n");
}
else
{
    HandleError("调用CryptGetUserKey函数获取签名密钥出错");
}
//输出公钥。此处公钥输出给PUBLICKEYBOLB密钥块,以便签名哈希的接收者可以验证签名。
//该密钥块可被写到文件或直接发送给接收者。

if(CryptExportKey(   
   hKey,    
   NULL,    
   PUBLICKEYBLOB,
   0,    
   NULL, 
   &dwBlobLen)) 
{
     printf("已经获得公钥密钥块大小\n");
}
else
{
     HandleError("获取密钥块大小失败");
}
//为pbKeyBlob分配内存

if(pbKeyBlob = (BYTE*)malloc(dwBlobLen)) 
{
    printf("已为密钥块分配内存\n");
}
else
{
    HandleError("内存溢出\n");
}
//输出密钥块

if(CryptExportKey(   
   hKey, 
   NULL,    
   PUBLICKEYBLOB,    
   0,    
   pbKeyBlob,    
   &dwBlobLen))
{
     printf("密钥已经写到密钥块\n");
}
else
{
    HandleError("调用CryptExportKey函数失败");
}
//--------------------------------------------------------------------
//产生哈希对象

if(CryptCreateHash(
   hProv, 
   CALG_MD5, 
   0, 
   0, 
   &hHash)) 
{
     printf("哈希对象已经产生\n");
}
else
{
    HandleError("调用CryptCreateHash函数失败");
}
//--------------------------------------------------------------------
//计算哈希值

if(CryptHashData(
   hHash, 
   pbBuffer, 
   dwBufferLen, 
   0)) 
{
     printf("缓存哈希值已经计算\n");
}
else
{
     HandleError("调用CryptHashData函数失败");
}
//判断签名大小并分配内存

dwSigLen= 0;
if(CryptSignHash(
   hHash, 
   AT_SIGNATURE, 
   szDescription, 
   0, 
   NULL, 
   &dwSigLen)) 
{
     printf("签名长度为%d\n",dwSigLen);
}
else
{
     HandleError("调用CryptSignHash失败");
}
//为签名分配内存

if(pbSignature = (BYTE *)malloc(dwSigLen))
{
     printf("已经为签名分配了内存\n");
}
else
{
     HandleError("内存溢出");
}
//--------------------------------------------------------------------
//签名哈希对象

if(CryptSignHash(
   hHash, 
   AT_SIGNATURE, 
   szDescription, 
   0, 
   pbSignature, 
   &dwSigLen)) 
{
     printf("pbSignature为哈希签名\n");
}
else
{
     HandleError("调用CryptSignHash失败");
}
//--------------------------------------------------------------------
//销毁哈希对象

if(hHash) 
  CryptDestroyHash(hHash);

printf("哈希对象已经销毁!\n");
printf("签名过程完成\n\n");

//--------------------------------------------------------------------
//下面将验证哈希签名,下面可以为一个独立程序,因为可能有另外一个用户来验证签名。
//哈希值,签名和PUBLICKEYBLOB可以通过多种方式获得,如文件等。
// 获取创建数字签名者的公钥,并利用CryptImportKey函数导入到CSP中,
//在hPubKey参数中返回公钥句柄。.

if(CryptImportKey(
   hProv,
   pbKeyBlob,
   dwBlobLen,
   0,
   0,
   &hPubKey))
{
     printf("公钥已经导入\n");
}
else
{
     HandleError("公钥导入失败");
}
//--------------------------------------------------------------------
//创建新的哈希对象
if(CryptCreateHash(
   hProv, 
   CALG_MD5, 
   0, 
   0, 
   &hHash)) 
{
     printf("哈希对象已经重新创建\n");
}
else
{
     HandleError("调用CryptCreateHash函数失败");
}
//计算缓存哈希值

if(CryptHashData(
   hHash, 
   pbBuffer, 
   dwBufferLen, 
   0)) 
{
     printf("新哈希值已经计算\n");
}
else
{
     HandleError("调用CryptHashData失败");
}
//--------------------------------------------------------------------
//验证数字签名

if(CryptVerifySignature(
   hHash, 
   pbSignature, 
   dwSigLen, 
   hPubKey,
   szDescription, 
   0)) 
{
     printf("签名已经被验证\n");
}
else
{
     printf("签名无效,不能验证\n");
}
//--------------------------------------------------------------------
//释放存放签名的缓存
if(pbSignature)
  free(pbSignature);

//--------------------------------------------------------------------
//销毁哈希对象
if(hHash) 
  CryptDestroyHash(hHash);

//释放CSP

if(hProv) 
   CryptReleaseContext(hProv, 0);
} //  End of main

//--------------------------------------------------------------------
//错误处理函数
void HandleError(char *s)
{
    printf("在运行程序时出现错误\n");
    printf("%s\n",s);
    printf("错误代号 %x\n.",GetLastError());
    printf("程序终止运行\n");
    exit(1);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -