一般情況下ssl加密連線都只是單向認證,是客戶端驗證服務端的證書。例如常見的web服務,是客戶端驗證服務端的證書,防止遇到假冒的**,正規的**都有權威機構簽名的證書,瀏覽器會幫助使用者校驗服務端的證書,如果證書是可信的,說明**是可信的可如果證書不可信,瀏覽器會有提示,提示一般在位址列前面有個鎖形符號。
服務端在傳送完server hello後將自己的證書傳送給客戶端,客戶端此時可選的驗證服務端的證書。客戶端雖然是可選驗證,但是連線仍然是加密連線,只是沒有驗證連線對端的身份。客戶端用服務端證書的公鑰加密乙個預主金鑰傳送給服務端,以供雙方後續產生加密金鑰。
雙向認證是在建立乙個加密連線時,雙方互相驗證對方的身份,此時在上述一般情況下ssl加密連線的基礎上,客戶端也要提供自己的證書以供服務端驗證,如果證書不正確,服務端會斷開連線。雙向認證時雙方可以使用金鑰協商演算法協商出乙個預主金鑰,供後續產生加密金鑰。
服務端的**如下:
int loadcertfile(ssl_ctx* ctx, const
char* certfile, const
char* keyfile, const
char* cafile)
// load cert
if(certfile && ssl_ctx_use_certificate_file(ctx, certfile, ssl_filetype_pem) <= 0)
// load private key
if(keyfile && ssl_ctx_use_privatekey_file(ctx,keyfile, ssl_filetype_pem) <= 0)
// check private key
if(certfile && keyfile && !ssl_ctx_check_private_key(ctx))
// load ca file
if(cafile && !ssl_ctx_load_verify_locations(ctx, cafile, 0))
return sec_ok;
}// client
int openconnection(const
char* ipaddr, int port)
if(connect(sd, (struct sockaddr*)&addr, sizeof(addr)) != 0)
return sd;
}
int rv = 0;
ssl_ctx* ctx;
ssl *ssl;
int listenfd, connfd;
struct sockaddr_in clientaddr;
ssl_library_init();
ctx = initserversslctx();
rv = loadcertfile(ctx, pszservercert, pszserverkey, pszserverca);
if(rv)
ssl_ctx_set_verify(ctx,ssl_verify_peer,null); // 設定驗證對方的證書
listenfd = openlistener(atoi(nport)); // 開啟監聽埠
connfd = accept(listenfd, (struct sockaddr*)&clientaddr, &len); //接受連線
ssl = ssl_new(ctx);
ssl_set_accept_state(ssl);
ssl_set_fd(ssl, connfd);
rv = ssl_accept(ssl);
if(rv != 1)
建立ssl連線後就可以使用ssl_write和ssl_read進行讀寫操作了。
客戶端的**如下:
nt openconnection(const
char* ipaddr, int port)
if(connect(sd, (struct sockaddr*)&addr, sizeof(addr)) != 0)
return sd;
}ssl_ctx* initclisslctx(void)
return ctx;
}ssl* getclissl(void*phsession, int sockfd)
ssl_ctx_set_verify(ssl_ctx,ssl_verify_peer,null);
rv = loadcertfile(ssl_ctx, pszclientcert, pszclientkey, pszclientca);
if(rv)
ssl = ssl_new(ssl_ctx); // create new ssl connection state
if(!ssl)
ssl_set_connect_state(ssl);
ssl_set_fd(ssl, sockfd); // attache socet descriptor
if(ssl_connect(ssl) != 1) // perform the connection
ssl_read(ssl, recvline, 0);
ssl_ctx_free(ssl_ctx);
return ssl;
}int sockfd;
ssl* ssl;
sockfd = openconnection(ipaddr, atoi(port));
ssl = getclissl(phsession, sockfd);
建立ssl連線後就可以使用ssl_write和ssl_read進行讀寫操作了。
具體工程**可參考github倉庫:
ssl雙向驗證
按照提示安裝,比較簡單,安裝完畢以後,在瀏覽器中輸入apache的ip位址或者網域名稱,如果能夠出現 it works!這是apache預設的乙個網頁 htdocs index.html 說明安裝apache已經成功,這時已經可以提供預設為80埠的http服務了 生成 伺服器公鑰檔案server.k...
SSL單雙向驗證原理
為了便於更好的認識和理解 ssl 協議,這裡著重介紹 ssl 協議的握手協議。ssl 協議既用到了公鑰加密技術又用到了對稱加密技術,對稱加密技術雖然比公鑰加密技術的速度快,可是公鑰加密技術提供了更好的身份認證技術。ssl 的握手協議非常有效的讓客戶和伺服器之間完成相互之間的身份認證,其主要過程如下 ...
ssl雙向認證
ssl雙向認證 ca.key 根證書的私鑰 ca.crt 根證書的簽名證書 server.key,server.crt client.key,client.crt 1 openssl ca.key,ca.crt 2 openssl server.key server.csrserver.crt 3 ...