這篇文章主要介紹pki公鑰體系中非常核心元素——數字證書的程式設計解析。在ssl,set等安全協議通訊時,數字證書用於通訊雙方進行身份認證,並且依靠數字證書和非對稱加密演算法加密傳輸資料,或者根據數字證書協商通訊雙方的共享金鑰。所以,使用者想要開發自己的應用,實現身份認證,必須對數字證書進行解析。根據解析結果,符合一定條件的終端使用者,才可以接入。
1、證書格式介紹
現有的數字證書大都採用了x.509規範,主要由一下資訊組成:版本號,證書序列號,有效期(證書生效時間和失效時間),使用者資訊(姓名、單位、組織、城市、國家等),頒發者資訊,其他擴充套件資訊,擁有者的公鑰,ca對證書整體的簽名.
openssl開發包中實現了對x.509證書解析的所有操作,如獲得證書的版本、公鑰、擁有者資訊、頒發者資訊、有效期等,下面就向大家介紹如何通過程式設計,解析出我們需要的證書資訊。
2、證書解析程式設計實現
2.1 資料結構介紹
x.509證書在openssl中定了專門的資料結構,方便使用者對其操作,其結構如下所示:
struct x509_st
;該結構表示了乙個完整的數字證書。各項意義如下:
cert_info:證書主體資訊;
sig_alg:簽名演算法;
signature:簽名值,存放ca對該證書簽名的結果;
valid:是否是合法證書,1為合法,0為未知;
references:引用次數,被引用一次則加一;
name:證書持有者資訊;
ex_data:擴充套件資料結構,用於存放使用者自定義的資訊;
ex_pathlen:證書路徑長度;
ex_kusage:金鑰用法;
ex_xkusage:擴充套件金鑰用法;
ex_nscert:netscape證書型別;
skid:主體金鑰標識;
akid:頒發者金鑰標識;
policy_cache:各種策略快取;
sha1_hash:存放證書的sha1摘要值;
aux:輔助資訊;
其中,證書主體資訊—x509_cinf結構體定義如下:
typedef struct x509_cinf_st
x509_cinf;
2.2 函式介紹
根據上述結構體可知,我們可以通過程式設計,讀取結構體中的證書資訊,下面介紹一下幾個常用的函式。
(1)編碼轉換函式
數字證書分為der編碼和pem編碼,所以對應的操作是不一樣的。對於der編碼的證書,我們可以通過函式:x509 * d2i_x509(x509 **cert , unsigned char **d , int len),返回乙個x.509的結構體指標。而對於pem編碼的證書,我沒找到乙個函式來實現編碼轉換,但可以通過openssl提供的bio函式,實現這一功能:先呼叫bio_new_file() 返回乙個bio結構體,然後通過 pem_read_bio_x509() 返回乙個x.509結構體。
(2)獲得證書資訊
其實獲得證書資訊的操作,僅僅是解析x509和x509_cinf結構體的操作,可以得到如:證書版本,頒發者資訊,證書擁有者資訊,有效期,證書公鑰等資訊,主要函式如下:
x509_get_version(); //獲得證書版本;
x509_get_issuer_name(); //獲得證書頒發者資訊
x509_get_subjiect_name(); //獲得證書擁有者資訊
x509_get_notbefore(); //獲得證書起始日期
x509_get_notafter(); //獲得證書終止日期
x509_get_pubkey(); //獲得證書公鑰
其中,函式具體的引數和使用,結合下面程式設計**向大家介紹。
2.3程式設計實現
通過上述的函式和結構體的介紹,下面程式設計實現解析乙個數字證書就非常簡單了。在此,我編寫了乙個解析證書的軟體,實現關鍵**如下:
fp=fopen(filename.getbuffer(0),"rb");
if(fp==null)
certlen=fread(cert,1,4096,fp);
fclose(fp);
//判斷是否為der編碼的使用者證書,並轉化為x509結構體
ptmp=cert;
usrcert = d2i_x509(null,(const unsigned char ** )&ptmp,certlen);
if(usrcert==null)
}//解析證書
x509_name *issuer = null;//x509_name結構體,儲存證書頒發者資訊
x509_name *subject = null;//x509_name結構體,儲存證書擁有者資訊
//獲取證書版本
version = x509_get_version(usrcert);
//獲取證書頒發者資訊,x509_name結構體儲存了多項資訊,包括國家、組織、部門、通用名、mail等。
issuer = x509_get_issuer_name(usrcert);
//獲取x509_name條目個數
entriesnum = sk_x509_name_entry_num(issuer->entries);
//迴圈讀取各條目資訊
for(i=0;ientries,i);
//獲取物件id
nid = obj_obj2nid(name_entry->object);
//判斷條目編碼的型別
if(name_entry->value->type==v_asn1_utf8string)
//把utf8編碼資料轉化成可見字元
else
//根據nid列印出資訊
switch(nid)
//end switch
}//獲取證書主題資訊,與前面類似,在此省略
subject = x509_get_subject_name(usrcert);
………//獲取證書生效日期
time = x509_get_notbefore(usrcert);
tmp.format("cert notbefore:%s\n",time->data);
m_list.insertstring(-1,tmp);
tmp.empty();
//獲取證書過期日期
time = x509_get_notafter(usrcert);
tmp.format("cert notafter:%s\n",time->data);
m_list.insertstring(-1,tmp);
tmp.empty();
//獲取證書公鑰
pubkey = x509_get_pubkey(usrcert);
ptmp=derpubkey;
//把證書公鑰轉為der編碼的資料
derpubkeylen=i2d_publickey(pubkey,&ptmp);
printf("publickey is: \n");
for(i = 0; i < derpubkeylen; i++)
m_list.insertstring(-1,tmp);
//釋放結構體內存
x509_free(usrcert);
3、結束語
通過上述介紹,相信大家對數字證書又有了更進一步的了解。在開發網路通訊軟體,需要加入身份認證功能時,大家可以根據解析出來的證書資訊,與自己的訪問策略相對比,實現訪問控制。
數字證書在資訊保安中處於重要地位,隨著密碼學的發展,數字證書的應用也會越來越廣。
OpenSSL 與 SSL 數字證書概念貼
ssl tls 介紹見文章 ssl tls原理詳解。如果你想快速自建ca然後簽發數字證書,請移步 基於openssl自建ca和頒發ssl證書 首先簡單區分一下https ssl openssl三者的關係 ssl是在客戶端和伺服器之間建立一條ssl安全通道的安全協議,而openssl是tls ssl協...
SSL,HTTPS,數字證書
ssl https secure hypertext transfer protocol 安全超文字傳輸協議 它是由netscape開發並內置於其瀏覽器中,用於對資料進行壓縮和解壓操作,並返回網路上傳送回的結果。https實際上應用了netscape的完全套接字層 ssl 作為http應用層的子層。...
SSL 數字證書
secure 可靠的.安全的 socket 座 layer 層 ssl 協議 ssl 是乙個安全協議,它提供使用 tcp ip 的通訊應用程式間的隱私與完整性。網際網路的 超文字傳輸協議 http 使用 ssl 來實現安全的通訊。由於ssl技術已建立到所有主要的瀏覽器和web伺服器程式中,因此,伺服...