📄 inituser.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 + -