ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

调用函数去安装根证书

2021-03-16 18:02:25  阅读:156  来源: 互联网

标签:证书 调用函数 CERT pCertContext ret NULL 安装 hRootCertStore


前言

​ 使用程序去安装根证书的目的是:使用自签的证书给软件进行签名,安装根证书之后,电脑就会信任该自签名软件,不会进行拦截。当然可以的话,掏钱买证书比较好。我见过有些软件会安装根证书,但都是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会弹出对话框让用户确认:

在这里插入图片描述

结尾

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

标签:证书,调用函数,CERT,pCertContext,ret,NULL,安装,hRootCertStore
来源: https://blog.csdn.net/q893332169/article/details/114891220

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有