调用函数去安装根证书

前言

​ 使用程序去安装根证书的目的是:使用自签的证书给软件进行签名,安装根证书之后,电脑就会信任该自签名软件,不会进行拦截。当然可以的话,掏钱买证书比较好。我见过有些软件会安装根证书,但都是key驱动或者CA厂家。安装根证书需要用户手动点击确定按钮,就好比你是否同意我们的协议。

​ 以下的证书都是cer证书,base64内容。其他格式可以转成cer格式

证书的安装

​ 证书安装需要几个步骤,

1. 读取证书内容
2. 解析证书内容,并得到证书上下文
3. 添加或删除以及判断证书是否安装
读取证书内容
char* readFile(int* len)
{
	int length = 0;
	ifstream file("localhost.cer");
	if (!file.is_open())
	{
		std::cout << "open file fail" << endl;
	}
	file.seekg(0, std::ios::end);    // go to the end  
	length = file.tellg();           // report location (this is the length)  
	file.seekg(0, std::ios::beg);    // go back to the beginning  
	char* buffer = new char[length];    // allocate memory for a buffer of appropriate dimension  
	file.read(buffer, length);       // read the whole file into the buffer  
	file.close();

	*len = length;
	return buffer;
}
解析证书并得到证书上下文
///解码证书
PCCERT_CONTEXT DecodeCert(LPBYTE lpCertData, ULONG ulDataLen)
{
	PCCERT_CONTEXT  pCertContext = NULL;

	ULONG ulFlag = CRYPT_FIRST;
	ULONG ulContainerNameLen = 512;
	CHAR csContainerName[512] = { 0 };
	BOOL bFoundContainer = FALSE;

	if (!lpCertData || ulDataLen == 0)
	{
		return pCertContext;
	}

	// 由证书链创建一个证书库
	HCERTSTORE hCertStore = NULL;
	
	CRYPT_DATA_BLOB dataBlob = { ulDataLen, lpCertData };
	DWORD pdwContentType = CERT_QUERY_CONTENT_CERT;
	//尝试使用所有格式去解析证书
	CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &dataBlob, CERT_QUERY_CONTENT_FLAG_ALL, CERT_QUERY_FORMAT_FLAG_ALL,
		NULL, &pdwContentType, NULL, NULL, &hCertStore, NULL, (const void**)&pCertContext);
	
	if (NULL == hCertStore)
	{
		return NULL;
	}
	// 得到第一个证书内容
	if (pCertContext == NULL)
	{
		pCertContext = CertEnumCertificatesInStore(hCertStore, pCertContext);
	}
	
	//释放证书库
	if (hCertStore)
	{
		CertCloseStore(hCertStore, 0);
		hCertStore = NULL;
	}

	return pCertContext;
}
添加证书
bool SaveCert(BYTE* cert, int length)
{
	bool ret = false;
	PCCERT_CONTEXT  pCertContext = NULL;
	//得到证书的上下文
	pCertContext = DecodeCert(cert, length);
	HCERTSTORE hRootCertStore = CertOpenSystemStore(NULL, L"ROOT");
	if (hRootCertStore != NULL && pCertContext != NULL)
	{
		//往证书存储区中添加证书
		ret = CertAddCertificateContextToStore(hRootCertStore, pCertContext, CERT_STORE_ADD_REPLACE_EXISTING,NULL);
		//释放证书库
		CertCloseStore(hRootCertStore, 0);
		//释放证书上下文
		CertFreeCertificateContext(pCertContext);
	}
	return ret;
}

需要注意,Windows会弹出对话框,类似于以下图:

在这里插入图片描述

判断是否有证书
bool HasCert(BYTE* cert, int length)
{

	bool ret = false;
	PCCERT_CONTEXT  pCertContext = NULL;
	
	pCertContext = DecodeCert(cert,length);
	
	
	if (pCertContext != NULL)
	{

		HCERTSTORE hRootCertStore = CertOpenSystemStore(NULL, L"ROOT");

		if (hRootCertStore != NULL)
		{

			PCCERT_CONTEXT certcontext = CertFindCertificateInStore(hRootCertStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_EXISTING, pCertContext, NULL);

			if (certcontext != NULL)
			{

				ret = true;
				CertFreeCertificateContext(certcontext);

			}

		}

		CertFreeCertificateContext(pCertContext);

	}

	return ret;

}
删除根证书
bool DeleteCert(BYTE* cert, int length)
{
	bool ret = true;
	PCCERT_CONTEXT  pCertContext = NULL;

	pCertContext = DecodeCert(cert, length);
	if (pCertContext != NULL)
	{

		HCERTSTORE hRootCertStore = CertOpenSystemStore(NULL, L"ROOT");
		if (hRootCertStore != NULL)
		{
			PCCERT_CONTEXT certcontext = CertFindCertificateInStore(hRootCertStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_EXISTING, pCertContext, NULL);
			if (certcontext != NULL)
			{
				ret = CertDeleteCertificateFromStore(certcontext);
				int error = GetLastError();
				std::cout << error << endl;
			}
		}	

		CertFreeCertificateContext(pCertContext);
	}
	return ret;
}

同安装证书一样,Windows会弹出对话框让用户确认:

在这里插入图片描述

结尾

​ 好久之前写的代码了,以前因为项目需要给用户电脑安装根证书,但是后来发现不需要了,公司有现成的付费代码签名证书。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值