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);
}