`

OpenSSL 解析P12格式证书文件

 
阅读更多
1 解压openssl-0.9.8k_WIN32.zip 到 c:\根目录;解压文件夹如下;

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

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

  3.2 生成ca待签名证书
  openssl req -new -out ca-req.csr -key dsakey -config ..\openssl.cnf


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

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


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


  3.6 检查并确认.p12文件;

 
4 添加OpenSLL头文件和lib库文件;
VS2008->Tools->Options->Projects and Solutions->VC++ Directories


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
分享到:
评论

相关推荐

    Win64OpenSSL工具和p12秘钥解析方式

    本文将详细讲解Windows环境下64位版本的OpenSSL工具的安装及使用,以及p12(也称为PFX)文件的密钥解析方法。 首先,让我们来了解如何在Windows上安装Win64OpenSSL。`Win64OpenSSL_Light-1_1_0h.exe`是一个轻量级的...

    openssl 解析证书

    3. **导出私钥**:有时你需要从证书中提取私钥,这可以通过`openssl pkcs12`命令实现,比如`openssl pkcs12 -in cert.p12 -out key.pem -nodes`,这将把PKCS12格式的文件转换成.pem格式,其中包含私钥。 4. **生成...

    openssl工具

    **三、密钥文件格式** OpenSSL生成的密钥文件默认采用PEM(Privacy Enhanced Mail)格式,这是一种Base64编码的ASCII文本格式,可以被人类阅读。在某些情况下,可能需要转换成DER或PKCS#8等其他格式,这些转换可以...

    cer 转成p12方法

    - **合成P12证书**:利用生成的私钥和获得的X.509 DER证书,使用OpenSSL或其他支持的工具将它们合并成一个P12文件。 #### 四、转换实践指南 为了完成从X.509 DER到P12的转换,以下是一些具体的实践步骤和注意事项...

    国密 二代支付 p7 p10 基于openssl 0.9.8

    基于openssl 0.9.8,新增算法 SM2,...1、 解析PFX(p12)证书文件 2、 从证书生成P7报文 3、 创建P10请求文件. 4、 将公私钥转换成OpenSSL 结构 5. 解析PKCS7报文 6. SM2 加解密 7. gen pkcs7 8. 解析PKCS7报文 0、 退出

    CryptoAPI实现的Pfx,Cer证书生成程序C++

    3. **Pfx(P12)证书**:Pfx文件是一种包含了私钥和公钥的二进制格式,用于存储用户证书和相关密钥对。这种格式常用于导出和导入用户的完整身份认证信息,便于在不同系统间迁移或备份。Pfx文件通常用密码保护,防止...

    p12_decr.rar_Called

    3. **解析P12结构**:解码P12文件内的ASN.1编码数据,这包括证书链、私钥和其他相关信息。 4. **提取内容**:根据需要,从解析的数据中提取特定的证书或私钥。 5. **解密私钥**:如果私钥是加密的,使用密码解密它。...

    Tomcat SSL 认证设置及证书自己生成

    1. 将生成的服务器证书(server.crt)和私钥(server.key)整合成一个PKCS12格式的文件,便于导入Tomcat。 - `openssl pkcs12 -export -inkey server.key -in server.crt -out server.p12 -name tomcat -passout ...

    证书配置概要文件

    同时,还需要生成证书文件`.p12`,它包含了应用发行商的身份验证信息,确保应用的来源可信。 开发者授权系统分为开发(Development)和发布(Distribution)两个阶段。开发阶段的证书和配置文件适用于调试和内部测试,...

    p12_key.rar_p12

    PKCS#12文件通常以.p12或.pfx为扩展名,它是一个二进制格式,可以包含一个或多个密钥对以及相关的证书链。这些文件在互联网安全领域扮演着重要角色,因为它们允许用户安全地存储和传输个人身份信息。文件“p12_key.c...

    net推送证书脚本.docx

    - **`.p12`文件**:即PKCS#12文件,是一种包含了私钥及证书链的文件格式,支持多种加密算法。 ##### 2. 脚本操作详解 根据文档内容,我们可以将整个过程分为两个部分:开发者证书的处理与生产证书的处理。下面是...

    openssl配置

    这一步生成了一个PKCS#12格式的文件`client.p12`,可以用于导入到浏览器或其他应用中。 ### openssl.cnf 配置文件 接下来是对`openssl.cnf`配置文件的解析: ```plaintext # OpenSSL example configuration file....

    通过RSA证书提取XML/PEM公钥私钥

    "RSASecretKeyExtractor"这个文件可能是一个程序或脚本,其功能是读取PFX证书文件,然后将其中的RSA公钥和私钥转换成XML或PEM格式。这在需要在不同系统间交换密钥或者适应不同加密库时非常有用。以下是一些关于如何...

    php客服端证书

    4. **导出P12文件**:最后,可以使用openssl_pkcs12_export()函数将客户端证书、客户端私钥和CA证书打包成一个P12文件,这样客户端就可以用它来证明自己的身份。 ### 使用客户端证书 在PHP中,一旦你有了客户端...

Global site tag (gtag.js) - Google Analytics