zoukankan      html  css  js  c++  java
  • 通过OpenSSL解码X509证书文件

            在Windows平台下。假设要解析一个X509证书文件,最直接的办法是使用微软的CryptoAPI。

    可是在非Windows平台下,就仅仅能使用强大的开源跨平台库OpenSSL了。一个X509证书通过OpenSSL解码之后,得到一个X509类型的结构体指针。

    通过该结构体,我们就能够获取想要的证书项和属性等。

            X509证书文件,依据封装的不同。主要有下面三种类型:

    *.cer:单个X509证书文件,不私钥,能够是二进制和Base64格式。该类型的证书最常见;

    *.p7b:PKCS#7格式的证书链文件。包括一个或多个X509证书。不含私钥。

    通常从CA中心申请RSA证书时。返回的签名证书就是p7b格式的证书文件;

    *.pfx:PKCS#12格式的证书文件,能够包括一个或者多个X509证书,含有私钥,一般有password保护。通常从CA中心申请RSA证书时。加密证书和RSA加密私钥就是一个pfx格式的文件返回。

            以下,针对这三种类型的证书文件,使用OpenSSL进行解码,得到相应的X509结构体指针。须要注意的是,演示样例代码中的证书文件内容都是指二进制数据,假设证书文件本身使用的Base64格式。从文件读取之后,须要将Base64格式的内容转化为二进制数据,才干使用以下的解码函数。

    一、解码CER证书文件

            CER格式的文件最简单,仅仅须要调用API d2i_X509()就可以。

    演示样例代码例如以下(lpCertData为二进制数据):

    m_pX509 = d2i_X509(NULL, (unsigned char const **)&lpCertData, ulDataLen);
    if (m_pX509 == NULL) 
    {
    	return CERT_ERR_FAILED;
    }

    二、解码P7B证书文件

            因为P7B是个证书链文件,理论上能够包括多个X509证书。可是实际应用中,往往仅仅包括一个文件。所以我们仅仅处理第一个证书。

    演示样例代码例如以下:

    int rv = 0;
    int nid = 0;
    PKCS7* p7 = NULL;
    STACK_OF(X509) *certs = NULL;
    BIO* bio = BIO_new(BIO_s_mem());
    // 解码p7b内容
    rv = BIO_write(bio, lpCertData, ulDataLen);
    p7 = d2i_PKCS7_bio(bio, NULL);
    BIO_free(bio);
    // 获取P7的详细格式
    nid = OBJ_obj2nid(p7->type);
    if(nid == NID_pkcs7_signed) 
    {
        certs = p7->d.sign->cert;
    } 
    else if(nid == NID_pkcs7_signedAndEnveloped) 
    {
        certs = p7->d.signed_and_enveloped->cert;
    }
    // 仅仅支持单证书的p7b
    m_pX509 = sk_X509_value(certs, 0);
    if (m_pX509 == NULL) 
    {
        return CERT_ERR_FAILED;
    }
            如在特殊的情况下。须要处理整个证书链中的全部证书。则仅仅须要循环调用sk_X509_value()知道返回为NULL为止。

    三、解码PFX证书文件

            解码PFX证书时,实际上是获取X509证书、私钥数据和CA证书链一系列对象,同一时候须要校验PFX的password。演示样例代码例如以下:

    int rv = 0;
    PKCS12 *p12 = NULL;
    EVP_PKEY *pkey = NULL;
    STACK_OF(X509) *ca = NULL;
    BIO *bio; 
    // 解码P12内容
    bio = BIO_new(BIO_s_mem());
    rv = BIO_write(bio, lpCertData, ulDataLen);
    p12 = d2i_PKCS12_bio(bio, NULL);
    BIO_free_all(bio); 
    // 获取证书对象
    rv = PKCS12_parse(p12, lpscPassword, &pkey, &m_pX509, &ca);
    if (!rv || !m_pX509)
    {
    	rv = CERT_ERR_FAILED;
    	goto FREE_MEMORY;
    }
    // 释放内存
    FREE_MEMORY:
    PKCS12_free(p12);
    EVP_PKEY_free(pkey);
    sk_X509_free(ca);

            至此。三种常见证书文件的解码以完毕,通过解码得到的证书上下文结构体指针m_pX509。通过该指针就能够解析证书的项和扩展属性了。

    详细的解析方法,将在兴许的Blog中逐一介绍。

    相关博文:通过OpenSSL解析证书基本项

  • 相关阅读:
    poj 1579(动态规划初探之记忆化搜索)
    hdu 1133(卡特兰数变形)
    CodeForces 625A Guest From the Past
    CodeForces 625D Finals in arithmetic
    CDOJ 1268 Open the lightings
    HDU 4008 Parent and son
    HDU 4044 GeoDefense
    HDU 4169 UVALive 5741 Wealthy Family
    HDU 3452 Bonsai
    HDU 3586 Information Disturbing
  • 原文地址:https://www.cnblogs.com/blfshiye/p/5074965.html
Copyright © 2011-2022 走看看