解析p12格式的程序(提取公钥和私钥)

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>
 
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;
    int gmt=0;
    int i;
    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;
    char pass[128]="";
    //int i;
    char *p;
    char buf[1024];
 
    SSLeay_add_all_algorithms();
    ERR_load_crypto_strings();
    bio = BIO_new_file("client1.p12", "rb");
    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;
}
gcc -g -Wall b.c -o b -lcrypto -ldl
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mounter625

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值