相关文章推荐
痴情的啄木鸟  ·  electron ...·  1 年前    · 

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

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

PROV_RSA_FULL, NULL) (2)        获取USBKey内密钥句柄,这时要注意锁内密钥的类型是签名密钥(AT_SIGNATURE)或者交换密钥(AT_KEYEXCHANGE)。
验证文件数字签名是否有效可以使用函数 WinVerifyTrust 取得文件数字签名证书信息需要使用函数 CryptQueryObject。// FileSign.cpp : 定义控制台应用程序的入口点。 #include "stdafx.h" #include #include #include #include #include #pragma comment(lib, "