OpenSSL 解析P12格式证书文件

10 篇文章 0 订阅
1 解压openssl-0.9.8k_WIN32.zip 到 c:\根目录;解压文件夹如下;

2 打开控制台,并切换到OpenSSL可执行文件所在目录;

3 利用OpenSSL创建.p12测试文件(也就是证书制作过程);详细创建步骤如下;
3.1 生成ca私钥
[color=red]a) openssl dsaparam -out dsaparam 1024[/color]
[color=red]b) openssl gendsa -out dsakey dsaparam[/color]

3.2 生成ca待签名证书
[color=red]openssl req -new -out ca-req.csr -key dsakey -config ..\openssl.cnf[/color]


3.3用CA私钥进行自签名,得到自签名的CA根证书
[color=red]openssl x509 -req -in ca-req.csr -out ca-cert.cer -signkey dsakey -days 365[/color]

3.4至此,自签名CA根证书制作完毕。当前目录下将产生四个文件,分别是:
[color=red] ca-cert.cer
ca-req.csr
dsakey
dsaparam[/color]

3.5 利用OpenSSL把.cer转换为.p12格式;
[color=red]openssl pkcs12 -export -clcerts -in ca-cert.cer -inkey dsakey -out ca.p12[/color]


3.6 检查并确认.p12文件;


4 添加OpenSLL头文件和lib库文件;
[color=red]VS2008->Tools->Options->Projects and Solutions->VC++ Directories
[/color]

5创建一个”Win32 Console Application”空的工程,命名为”OpenSSLTester”, 然后添加main.cpp,把如下测试代码添加进去;并且把libeay32.dll,ssleay32.dll和ca.p12添加到此工程文件夹下;
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <openssl/pkcs12.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/pem.h>

#pragma comment(lib, "libeay32.lib")
#pragma comment(lib, "ssleay32.lib")

static const char *mon[12]=
{
"Jan","Feb","Mar","Apr","May","Jun",
"Jul","Aug","Sep","Oct","Nov","Dec"
};

/* 转换时间并存储到一个缓存区中*/
int UTCTIME_print(char buf[], ASN1_UTCTIME *tm)
{
char* v = NULL;
int gmt = 0;
int i = 0;
int y = 0, M = 0,d = 0,h = 0, m = 0, s = 0;

i = tm->length;
v = (char*)tm->data;

if (i < 10)
{
fprintf(stderr, "Bad time value\n");
}

if (v[i-1] == 'Z')
{
gmt=1;
}

for (i=0; i<10; i++)
{
if ((v[i] > '9') || (v[i] < '0'))
{
fprintf(stderr, "Bad time value\n");
}

y = (v[0]-'0')*10+(v[1]-'0');

if (y < 50)
{
y += 100;
}

M = (v[2]-'0')*10 + (v[3]-'0');

if ((M > 12) || (M < 1))
{
fprintf(stderr, "Bad time value\n");
}

d = (v[4]-'0')*10 + (v[5]-'0');
h = (v[6]-'0')*10 + (v[7]-'0');
m = (v[8]-'0')*10 + (v[9]-'0');

if ( i >= 12
&& (v[10] >= '0')
&& (v[10] <= '9')
&& (v[11] >= '0')
&& (v[11] <= '9'))
{
s = (v[10]-'0')*10 + (v[11]-'0');
}
}

sprintf(buf, "%s %2d %02d:%02d:%02d %d%s", mon[M-1], d, h, m, s, y+1900, (gmt)?" GMT":"");
return 0;
}

int main(void)
{
PKCS12 *p12 = NULL;
X509* usrCert = NULL;
EVP_PKEY* pkey = NULL;
STACK_OF(X509)* ca = NULL;
BIO*bio = NULL;
char pass[128] = "1234";
//int i;
char* p = NULL;
char buf[1024] = {0};

SSLeay_add_all_algorithms();
ERR_load_crypto_strings();

bio = BIO_new_file("ca.p12", "r");

//P12
p12 = d2i_PKCS12_bio(bio, NULL); //得到p12结构
BIO_free_all(bio);
PKCS12_parse(p12, pass, &pkey, &usrCert, &ca); //得到x509结构
PKCS12_free(p12);

// if (pkey)
// {
// fprintf(stdout, "***Private Key***\n");
// PEM_write_PrivateKey(stdout, pkey, NULL, NULL, 0, NULL, NULL);
// }

if (usrCert)
{
fprintf(stdout, "***User Certificate***\n");
//PEM_write_X509_AUX(stdout, usrCert);
fprintf(stdout, "Subject:");
p = X509_NAME_oneline(X509_get_subject_name(usrCert), NULL, 0);
fprintf(stdout, "%s\n", p);

fprintf(stdout, "Issuer:");
p = X509_NAME_oneline(X509_get_issuer_name(usrCert), NULL, 0);
fprintf(stdout, "%s\n", p);

fprintf(stdout, "Not Before:");
UTCTIME_print(buf, X509_get_notBefore(usrCert));
fprintf(stdout, "%s\n", buf);

fprintf(stdout, "Not After:");
UTCTIME_print(buf, X509_get_notAfter(usrCert));
fprintf(stdout, "%s\n", buf);
//X509_print_fp(stdout, usrCert); //add by slz token by openssl
}

//if (ca && sk_num(ca))
//{
// fprintf(stdout, "***Other Certificates***\n");
// for (i = 0; i < sk_X509_num(ca); i++)
// PEM_write_X509_AUX(stdout, sk_X509_value(ca, i));
//}

EVP_PKEY_free(pkey);
X509_free(usrCert);
sk_X509_free(ca);

return 0;
}


这样.p12格式的信息就全部被解析出来了。

change:
添加输出Key详细信息功能
void RSA_Printer(const RSA* rsa)
{
int i = 0, line = 0;
//modulus
//
line = 1;
for(i=rsa->n->dmax-1; i>=0; i--, line++)
{
if(i == rsa->n->dmax-1)
{
printf("n (modulus):\n");
}
printf("%.8X ",(unsigned long)*(rsa->n->d+i));
if ( (line!=0)
&& (line%8==0) )
{
printf("\n");
}
}
printf("\n\n");

//publicExponent
//
line = 1;
for(i=rsa->e->dmax-1; i>=0; i--,line++)
{
if(i==rsa->e->dmax-1)
{
printf("e (publicExponent):\n");
}
printf("%.4X ",(unsigned long)*(rsa->e->d+i));
if ( (line!=0)
&& (line%8==0) )
{
printf("\n");
}
}
printf("\n\n");

//privateExponent
//
line = 1;
for(i=rsa->d->dmax-1; i>=0; i--,line++)
{
if(i==rsa->d->dmax-1)
{
printf("d (privateExponent):\n");
}
printf("%.8X ",(unsigned long)*(rsa->d->d+i));
if ( (line!=0)
&& (line%8==0) )
{
printf("\n");
}
}
printf("\n\n");

//prime1
//
line = 1;
for(i=rsa->p->dmax-1; i>=0; i--,line++)
{
if(i==rsa->p->dmax-1)
{
printf("p (prime1):\n");
}
printf("%.8X ",(unsigned long)*(rsa->p->d+i));
if ( (line!=0)
&& (line%8==0) )
{
printf("\n");
}
}
printf("\n\n");

//prime2
//
line = 1;
for(i=rsa->q->dmax-1; i>=0; i--,line++)
{
if(i==rsa->q->dmax-1)
{
printf("q (prime2):\n");
}
printf("%.8X ",(unsigned long)*(rsa->q->d+i));
if ( (line!=0)
&& (line%8==0) )
{
printf("\n");
}
}
printf("\n\n");

//exponent1
//
line = 1;
for(i=rsa->dmp1->dmax-1; i>=0; i--,line++)
{
if(i==rsa->dmp1->dmax-1)
{
printf("dmp1 (exponent1):\n");
}
printf("%.8X ",(unsigned long)*(rsa->dmp1->d+i));
if ( (line!=0)
&& (line%8==0) )
{
printf("\n");
}
}
printf("\n\n");

//exponent2
//
line = 1;
for(i=rsa->dmq1->dmax-1; i>=0; i--,line++)
{
if(i==rsa->dmq1->dmax-1)
{
printf("dmq1 (exponent2):\n");
}
printf("%.8X ",(unsigned long)*(rsa->dmq1->d+i));
if ( (line!=0)
&& (line%8==0) )
{
printf("\n");
}
}
printf("\n\n");

//coefficient
//
line = 1;
for(i=rsa->iqmp->dmax-1; i>=0; i--,line++)
{
if(i==rsa->iqmp->dmax-1)
{
printf("iqmp (coefficient):\n");
}
printf("%.8X ",(unsigned long)*(rsa->iqmp->d+i));
if ( (line!=0)
&& (line%8==0) )
{
printf("\n");
}
}
printf("\n\n");
}

int main()
{
...
//P12
p12 = d2i_PKCS12_bio(bio, NULL); //得到p12结构
PKCS12_parse(p12, pass, &pkey, &usrCert, &ca); //得到x509结构

RSA *rsa;
int ret = 0;
rsa = pkey->pkey.rsa;

//Case 1
//
RSA_Printer(rsa);//自己写的RSA解析函数

//Case 2
//
BIO* bioOpt;
bioOpt = BIO_new_file("0000_MA2_20120207_0001_Private.key","w");//RSA key写到文件中
RSA_print(bioOpt, rsa, 0);
BIO_free(bioOpt);
...
}

参考:
1 OpenSSL证书制作过程.pdf
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值