boost 實作雙向認證解決辦法
boost::asio::ssl::context
- 要與OpenSSL進行互相認證,必須在用戶端使用
在伺服器端使用SSL_VERIFY_PEER
。如果僅在伺服器端使用SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT
,則它将僅将證書請求發送給用戶端,但是如果用戶端未發回證書,則将靜默接受。SSL_VERIFY_PEER
- ctx.set_verify_mode(ssl::verify_peer); // client side
-
ctx.set_verify_mode(ssl::verify_peer|ssl::verify_fail_if_no_peer_cert); // server side
– 服務端證書的
得與Common Name
ip|域名
相同
– 服務端隻檢測用戶端證書的根ca
set_verify_mode(ssl::verify_peer | ssl::verify_fail_if_no_peer_cert) //配置啟用雙向認證
// 也能用ssl_socket調用 (typedef ssl::stream<tcp::socket> ssl_socket)
ssl_socket.set_verify_mode(ssl::verify_peer | ssl::verify_fail_if_no_peer_cert) //配置啟用雙向認證
ssl_socket.set_verify_callback(boost::asio::ssl::rfc2818_verification(url.server)); //驗證證書與host是否比對
load_verify_file(file) //加載信任的根證書 檔案
add_certificate_authority(buffer) //加載信任的根證書 内容
use_certificate_chain_file //加載自己的證書 檔案
use_private_key_file //加載自己的私鑰 檔案
openssl
openssl使用ECDSA對網絡浏覽器進行身份驗證
openssl s_client -connect wikipedia.org:443
openssl實作雙向認證解決辦法
雙向認證的關鍵點在以下幾個函數(服務端和用戶端都一樣)
SSL_CTX_set_verify ----配置啟用雙向認證
SSL_CTX_load_verify_locations ----加載信任的根證書
SSL_CTX_use_certificate_file ----加載自己的證書
SSL_CTX_use_PrivateKey_file ----加載自己的私鑰
SSL_get_verify_result ----真正進行驗證,一定要調用這個函數不然前面四個光配置而已并不會進行雙向驗證
以下是SSL握手的具體流程:
(1)客戶将自己的SSL版本号、加密參數、與SSL會話有關的資料及其他一些必要資訊發送到伺服器。
(2)伺服器将自己的SSL版本号、加密參數、與SSL會話有關的資料及其他一些必要資訊發送給客戶,同時發給客戶的還有伺服器的證書。如果伺服器需要驗證客戶身份,伺服器還會發出要求客戶提供安全證書的請求。
(3)用戶端驗證伺服器證書,如果驗證失敗,就提示不能建立SSL連接配接。如果成功,那麼繼續下一步驟。
(4)用戶端為本次SSL會話生成預備主密碼(pre-master secret),并将其用伺服器公鑰加密後發送給伺服器。
(5)如果伺服器要求驗證客戶身份,用戶端還要對另外一些資料簽名後,将其與用戶端證書一起發送給伺服器。
(6)如果伺服器要求驗證客戶身份,則檢查簽署客戶證書的CA(Certificate Authority,證書機構)是否可信。如果不在信任清單中,結束本次會話。如果檢查通過,伺服器用自己的私鑰解密收到的預備主密碼(pre-master secret),并用它通過某些算法生成本次會話的主密碼(master secret)。
(7)用戶端與伺服器端均使用此主密碼(master secret)生成此次會話的會話密鑰(對稱密鑰)。在雙方SSL握手結束後傳遞任何消息均使用此會話密鑰。這樣做的主要原因是對稱加密比非對稱加密的運算量要低一個數量級以上,能夠顯著提高雙方會話時的運算速度。
(8)用戶端通知伺服器此後發送的消息都使用這個會話密鑰進行加密,并通知伺服器用戶端已經完成本次SSL握手。
(9)伺服器通知用戶端此後發送的消息都使用這個會話密鑰進行加密,并通知用戶端伺服器已經完成本次SSL握手。
(10)本次握手過程結束,SSL會話已經建立。在接下來的會話過程中,雙方使用同一個會話密鑰分别對發送和接收的資訊進行加密和解密。