在Windows平臺下。假設要解析一個X509證書文件,最直接的辦法是使用微軟的CryptoAPI。函數
但是在非Windows平臺下,就僅僅能使用強大的開源跨平臺庫OpenSSL了。一個X509證書經過OpenSSL解碼以後,獲得一個X509類型的結構體指針。加密
經過該結構體,咱們就可以獲取想要的證書項和屬性等。spa
X509證書文件,依據封裝的不一樣。主要有下面三種類型:.net
*.cer:單個X509證書文件,不私鑰,可以是二進制和Base64格式。該類型的證書最多見;指針
*.p7b:PKCS#7格式的證書鏈文件。包括一個或多個X509證書。不含私鑰。code
一般從CA中心申請RSA證書時。返回的簽名證書就是p7b格式的證書文件;對象
*.pfx:PKCS#12格式的證書文件,可以包括一個或者多個X509證書,含有私鑰,通常有password保護。一般從CA中心申請RSA證書時。加密證書和RSA加密私鑰就是一個pfx格式的文件返回。blog
如下,針對這三種類型的證書文件,使用OpenSSL進行解碼,獲得相應的X509結構體指針。需要注意的是,演示樣例代碼中的證書文件內容都是指二進制數據,假設證書文件自己使用的Base64格式。從文件讀取以後,需要將Base64格式的內容轉化爲二進制數據,才幹使用如下的解碼函數。內存
1、解碼CER證書文件get
CER格式的文件最簡單,僅僅需要調用API d2i_X509()就能夠。
演示樣例代碼例如如下(lpCertData爲二進制數據):
m_pX509 = d2i_X509(NULL, (unsigned char const **)&lpCertData, ulDataLen); if (m_pX509 == NULL) { return CERT_ERR_FAILED; }
2、解碼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爲止。
3、解碼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解析證書基本項