📄 certcreateselfsigncertificate.cpp
字号:
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0400
#endif
#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
#define CERT_SUBJECT_NAME "TEST_SIGNER_NAME"
//函数申明
void HandleError(char *s);
HCRYPTPROV GetCryptProv();
void ByteToStr(
DWORD cb,
void* pv,
LPSTR sz);
void main(void)
{
//-------------------------------------------------------------------
// 变量申明与初始化
HCERTSTORE hCertStore = NULL;
HCRYPTPROV hCertProv = NULL;
HCRYPTKEY hKeySign = NULL;
PCCERT_CONTEXT pCertCtxSign = NULL;
BYTE *Encrypted = NULL;
DWORD EncryptedLen = 0;
BYTE *Decrypted= NULL;
DWORD DecryptedLen = 0;
CERT_NAME_BLOB certName = {0};
certName.cbData = 0;
certName.pbData = NULL;
DWORD cbNameEncoded;
BYTE* pbNameEncoded;
//给CERT_NAME_BLOB结构certName赋值
CERT_RDN_ATTR rgNameAttr[] = {
"2.5.4.3",
CERT_RDN_PRINTABLE_STRING,
strlen(CERT_SUBJECT_NAME),
(BYTE*)CERT_SUBJECT_NAME};
CERT_RDN rgRDN[] = {
1,
&rgNameAttr[0]};
CERT_NAME_INFO Name = {
1,
rgRDN};
//-------------------------------------------------------------------
// 编码CERT_NAME_INFO结构,确定编码后的数据长度
if(CryptEncodeObject(
MY_ENCODING_TYPE, // Encoding type
X509_NAME, // Structure type
&Name, // Address of CERT_NAME_INFO structure
NULL, // pbEncoded
&cbNameEncoded)) // pbEncoded size
{
printf("首次调用函数CryptEncodeObject成功. \n");
}
else
{
HandleError("首次调用函数CryptEncodeObject失败.\
\n公私密钥对不能从密钥容器中导出. \n");
}
//-------------------------------------------------------------------
// 分配内存
if(!(pbNameEncoded = (BYTE*)malloc(cbNameEncoded)))
HandleError("pbNamencoded malloc operation failed.\n");
//-------------------------------------------------------------------
// 编码结构体
if(CryptEncodeObject(
MY_ENCODING_TYPE, // Encoding type
X509_NAME, // Structure type
&Name, // Address of CERT_NAME_INFO structure
pbNameEncoded, // pbEncoded
&cbNameEncoded)) // pbEncoded size
{
printf("此结构体已被编码. \n");
}
else
{
free(pbNameEncoded);
HandleError("第二次调用函数CryptEncodeObject 失败.\n");
}
//给certName赋值
certName.cbData = cbNameEncoded;
certName.pbData = pbNameEncoded;
//获取CSP句柄
hCertProv = GetCryptProv() ;
//产生签名密钥对
if (CryptGenKey(hCertProv, AT_SIGNATURE, CRYPT_EXPORTABLE, &hKeySign))
{
printf("在服务证书容器中创建签名密钥成功!\n");
}
else
{
HandleError("Protection::Initialise -不能在服务证书容器中创建签名密钥- \n");
}
SYSTEMTIME cs;
GetSystemTime(&cs);
cs.wYear += 1;
//创建自签名证书
if(pCertCtxSign = CertCreateSelfSignCertificate(
hCertProv, //CSP句柄
&certName, //证书客体名称数据结构指针
0, //标志位。默认行为,创建私钥信息,创建签名
NULL, //密钥信息结构
NULL, //签名算法,null表示默认算法SHA1RSA
NULL, //有效期起始时间 ,null表示取当前系统时间
&cs, //有效期终止时间,null表示起始时间加1年
NULL)) //未设置扩展属性
{
printf("一个自签名证书已经被创建.\n");
}
else
{
HandleError("CertCreateSelfSignCertificate Error!");
}
free(certName.pbData);
//打开证书库
if ((hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL , CERT_SYSTEM_STORE_CURRENT_USER , L"My")))
{
printf("打开证书库成功.\n");
}
else
{
HandleError("调用函数CertOpenStore 失败.\n");
}
//把证书加入证书库
if(CertAddCertificateContextToStore(hCertStore,
pCertCtxSign,CERT_STORE_ADD_NEW,NULL))
{
printf("将自签名证书加入到系统证书库成功.\n");
}
else
{
printf("将自签名证书添加到系统证书库中失败.\n");
}
//释放空间
if (Encrypted)
free(Encrypted);
if (Decrypted)
free(Decrypted);
if (pCertCtxSign)
CertFreeCertificateContext(pCertCtxSign);
if (hKeySign)
CryptDestroyKey(hKeySign);
if (hCertStore)
CertCloseStore(hCertStore, 0);
if (hCertProv)
CryptReleaseContext(hCertProv, 0);
} // End of main
//获取加密提供者句柄
HCRYPTPROV GetCryptProv()
{
HCRYPTPROV hCryptProv; // 加密服务提供者句柄
//获取加密提供者句柄
if(CryptAcquireContext(
&hCryptProv, // 加密服务提供者句柄
"ruanou", // 密钥容器名
MS_ENHANCED_PROV, // 加密服务提供者
PROV_RSA_FULL, // 加密服务提供者类型,可以提供加密和签名等功能
0)) // 标志
{
printf("加密服务提供者句柄获取成功!\n");
}
else
{
//重新建立一个新的密钥集
if(!CryptAcquireContext(&hCryptProv, "ruanou", MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET))
{
HandleError("重新建立一个新的密钥集出错!");
}
}
return hCryptProv;
}
//--------------------------------------------------------------------
// ByteToStr: 转换BYTE类型数组为字符串
//参数:cb[in] 需要转换的BYTE数组的长度
// pv[in] 需要转换的BYTE数组指针
// sz[out] 字符串指针
void ByteToStr(
DWORD cb,
void* pv,
LPSTR sz)
{
BYTE* pb = (BYTE*) pv;
DWORD i;
int b;
for (i = 0; i<cb; i++)
{
//pb的前4位转换为字符
b = (*pb & 0xF0) >> 4;
*sz++ = (b <= 9) ? b + '0' : (b - 10) + 'A';
//pb的后4位转换为字符
b = *pb & 0x0F;
*sz++ = (b <= 9) ? b + '0' : (b - 10) + 'A';
pb++;
}
*sz++ = 0;
}
// HandleError:错误处理函数,打印错误信息,并退出程序
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 + -