SSL证书(cer key ca文件)转换成pfx格式--VC实现

openssl使用版本:
http://slproweb.com/products/Win32OpenSSL.html
Win32OpenSSL-1_1_0L.exe

参考文档:

https://www.openssl.org/docs/man1.1.1/man3/
https://www.cnblogs.com/findumars/p/5436169.html

 

安装openssl到D盘(D:\OpenSSL-Win32,其实我们需要的就是解压出里面的lib、dll以及头文件)

编译工具 VS2010

编译方式:

1、在静态库中使用MFC 

2、运行库使用多线程(/MT) 

3、附加包含目录:D:\OpenSSL-Win32\include;

4、附加库目录:D:\OpenSSL-Win32\lib;

运行库的选择要根据下载的openssl版本的编译工具的版本来定 否则dll、lib由MTD 或 MD等其他方式编译的就会用不了,

附加依赖项:User32.lib;Advapi32.lib;Gdi32.lib;Ws2_32.lib;Crypt32.lib;

主要代码:

#include "stdafx.h"
#include "sslconvert.h"
#include "sslconvertDlg.h"
#include <openssl/pkcs12.h>
#include <openssl/pem.h>
#include <openssl/x509v3.h>
#include <openssl/x509.h>
#include <openssl/safestack.h>
#include <openssl/asn1t.h>
#include <stdio.h>
//#include <wchar.h>
#include <afxtempl.h>
#include <shlwapi.h>
#pragma comment(lib, "shlwapi.lib")
extern "C"
{
#include <openssl/applink.c>
}
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#pragma comment(lib, "libssl.lib")
#pragma comment(lib, "libcrypto.lib")


void CsslconvertDlg::OnBnClickedButton1()
{
	// TODO: 在此添加控件通知处理程序代码
	errno_t err = 0;
	FILE *fp = NULL;
	X509 *cert = NULL;
	X509 *cacert = NULL;
	EVP_PKEY *pkey = NULL;
	STACK_OF(X509) *pca = NULL;
	PKCS12 *p12 = NULL;
	CString str=_T("");
	const char *szpwd = (LPCTSTR)m_Pwd;//生成的pfx证书密码
	const char *szkeypwd = (LPCTSTR)m_keyPwd;//key文件密码
	const char *szcer = (LPCTSTR)m_Pathcer;//cer文件
	const char *szkey = (LPCTSTR)m_Pathkey;//key文件
	const char *szca = (LPCTSTR)m_Pathca;//ca文件
	//
	UpdateData();
	//fopen_s
	err = fopen_s(&fp,szkey,_T("rb"));
	if(err!=0)
	{
		AfxMessageBox(_T("fopen_s key fail"));
		goto FREE_TAG;
	}
	pkey = PEM_read_PrivateKey(fp,NULL,NULL, (void*)szkeypwd);
	if(pkey==NULL)
	{
		AfxMessageBox(_T("PEM_read_PrivateKey"));
		goto FREE_TAG;
	}
	fclose(fp);
	//int X509_check_ca(X509 *cert);
	err = fopen_s(&fp,szcer,_T("rb"));
	if(err!=0)
	{
		AfxMessageBox(_T("fopen_s cer fail"));
		goto FREE_TAG;
	}
	cert = PEM_read_X509_AUX(fp, NULL, NULL, NULL);
	if(cert==NULL)
	{
		AfxMessageBox(_T("PEM_read_X509_AUX"));
		goto FREE_TAG;
	}
	fclose(fp);
	//
	X509_NAME *subj = X509_get_subject_name(cert);
	//char *subject_name   = X509_NAME_oneline(subj, NULL, 0);
	/*for (int i = 0; i < X509_NAME_entry_count(subj); i++) {
		X509_NAME_ENTRY *e = X509_NAME_get_entry(subj, i);
		ASN1_STRING *d = X509_NAME_ENTRY_get_data(e);
		unsigned char *szd = ASN1_STRING_data(d);
		CString str;
		str.Format(_T("%s"),subject_name);
		AfxMessageBox(str);
	}*/
	X509_NAME_ENTRY *e = X509_NAME_get_entry(subj, 0);//只取第一项
	ASN1_STRING *d = X509_NAME_ENTRY_get_data(e);
	unsigned char *szd = ASN1_STRING_data(d);
	m_Certname.Format(_T("%s"),szd);
	//
	fp = NULL;
	err = fopen_s(&fp,szca,_T("rb"));
	if(err!=0)
	{
		//str.Format("err:%d",err);
		//AfxMessageBox(str);
		if(err==ENOENT||err== EINVAL)//ca文件不存在
		{
			int ret =  AfxMessageBox(_T("ca 文件不存在,是否继续?"),MB_YESNO | MB_ICONQUESTION);
			if(ret==IDNO)
			{
				goto FREE_TAG;
			}
		}
		else
		{
			AfxMessageBox(_T("fopen_s ca fail"));
			goto FREE_TAG;
		}
	}
	if(fp!=NULL)
	{
		cacert = PEM_read_X509_AUX(fp, NULL, NULL, NULL);
		if(cacert==NULL)
		{
			AfxMessageBox(_T("PEM_read_X509_AUX ca.pem"));
			goto FREE_TAG;
		}
		fclose(fp);
		//
		if(cacert!=NULL)
		{
			pca = sk_X509_new_null();
			if (pca == NULL)
			{
				AfxMessageBox("creating STACK_OF(X509) structure fail");
				goto FREE_TAG;
			}
			sk_X509_push(pca, cacert);
		}
	}
	//
	p12 = PKCS12_create("",(char*)szd,pkey,cert, pca,0, 0, 0, 0,0);
	if(p12==NULL)
	{
		AfxMessageBox(_T("PKCS12_create fail"));
		goto FREE_TAG;
	}
	//
	char szfile[256]={0};
	sprintf(szfile,"%s/%s.pfx",GetCurPath(),szd);
	AfxMessageBox(szfile);
	err = fopen_s(&fp,szfile, _T("w+"));
    if (err !=0) 
	{
		AfxMessageBox(_T("fopen  pfx fail"));
	}
	else
	{
		int ret = i2d_PKCS12_fp(fp, p12);
		if(ret!=1)
		{
			AfxMessageBox(_T("i2d_PKCS12_fp fail"));
			DeleteFile(szfile);
		}
	
		fclose(fp);
	}

FREE_TAG:
	EVP_PKEY_free(pkey);
	X509_free(cert);
	X509_free(cacert);
	sk_X509_free(pca);
	PKCS12_free(p12);
	//
	UpdateData(FALSE);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值