我正在寫一個OpenSSL庫的小程序,該程序假設與SSLv3服務器建立連接。此服務器分配一個自簽名證書,導致握手失敗,並顯示以下消息:「sslv3警報握手失敗,證書鏈中的自簽名證書」。OpenSSL忽略自簽名證書錯誤
有沒有辦法強制連接進行?我已經打過電話SSL_CTX_set_verify像這樣:
SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
但它似乎並沒有改變任何東西。
有什麼建議嗎?
我正在寫一個OpenSSL庫的小程序,該程序假設與SSLv3服務器建立連接。此服務器分配一個自簽名證書,導致握手失敗,並顯示以下消息:「sslv3警報握手失敗,證書鏈中的自簽名證書」。OpenSSL忽略自簽名證書錯誤
有沒有辦法強制連接進行?我已經打過電話SSL_CTX_set_verify像這樣:
SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
但它似乎並沒有改變任何東西。
有什麼建議嗎?
默認情況下OpenSSL的走證書鏈,並嘗試來驗證每一個步驟,SSL_set_verify()
不改變這種狀況,看塔人頁。引用它:執行
實際驗證程序或者使用 內置驗證過程或使用另一應用程序提供 驗證函數SSL_CTX_set_cert_verify_callback(3)設置。
因此,解決方案是創建一個簡單的回調,並設置一個,這樣就覆蓋所有證書鏈行走:
static int always_true_callback(X509_STORE_CTX *ctx, void *arg)
{
return 1;
}
SSL_CTX_set_cert_verify_callback(CTX, always_true_callback);
只需引用文本下面幾段:'如果未指定verify_callback,則將使用默認回調。它的返回值與preverify_ok相同,因此,如果設置了SSL_VERIFY_PEER,則任何驗證失敗都將導致終止TLS/SSL握手併發出警報消息。「 您的答案不正確,將驗證模式設置爲SSL_VERIFY_NONE應該足夠了。 – Spidey 2015-01-15 15:24:10
@Spidey你看過這個問題嗎?它被認爲SSL_VERIFY_NONE *不夠*。你自己嘗試過嗎?僅供參考,您所引用的手冊適用於'SSL_CTX_set_verify()'。但即使* set_verify *回調總是成功,驗證失敗的方式還有很多,這就是爲什麼您必須使用'SSL_CTX_set_cert_verify_callback()'設置更通用的回調。 – jimis 2015-01-19 10:05:31
總是返回'1'完全禁用證書驗證。這與設置'SSL_VERIFY_NONE'相同。 (即@Spidey是對的。)你可能不想這樣做,因爲這會讓你容易受到MITM攻擊。正確的做法是將自簽名證書添加到可信證書列表中。 (請參閱SSL_CTX_load_verify_locations()。) – 2017-02-03 10:54:51
您是否嘗試過給你的應用程序服務器的CA證書,以便您的應用程序可以驗證證書鏈?
正確,但在此情況下,簽名證書,OP必須讓他的應用信任的不是CA證書,而是服務器的證書。 – 2017-02-03 11:02:11
我的不好,OP是錯的。服務器證書不是自簽名的。問題中包含的錯誤消息顯示錯誤是'X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN',這意味着所提到的自簽名證書不是服務器證書,而是根CA證書。 – 2017-02-03 11:11:06
您可以嘗試將自己的回調傳遞給SSL_set_verify()
,然後進行自己的驗證。這並不理想,因爲我認爲你需要完成所有的驗證,然後讓自簽名錯誤被忽略,但是你應該能夠計算出標準驗證代碼從OpenSSL源代碼所做的事情,然後簡單地將它拉出來到你自己的驗證回調,並允許特定的錯誤代碼......
如果您打算接受自簽名證書,那麼其餘的驗證步驟無論如何都毫無意義。 – caf 2010-03-02 08:43:10
caf - 可能,是... – 2010-03-02 16:09:02
檢查這些OpenSSL的例子:http://www.rtfm.com/openssl-examples/
的wclient.c連接到任何HTTPS網頁,例如:
wclient -h www.yahoo.com -p 443
如果你使用默認安裝運行它,你會得到一個證書錯誤(你可以使用-i標誌繞過證書檢查)。
驗證證書,你需要下載CA證書(威瑞信,Thawte的,Equifax公司等),因此谷歌這個文件cacert.pem,下載並重新命名爲root.pem和你將能夠連接到Web服務器並驗證其證書。
另外,如果要打印證書,請在check_cert(ssl,host)之後插入以下行(在wclient.c中):X509_print_fp(stdout,SSL_get_peer_certificate(ssl)); – 2010-02-18 20:08:24
正確,儘管在這種情況下服務器使用自簽名證書,但OP必須使其應用信任的內容不是CA證書,而是服務器的證書。 – 2017-02-03 11:02:05
我的不好,OP是錯的。服務器證書不是自簽名的。問題中包含的錯誤消息顯示錯誤是'X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN',這意味着所提到的自簽名證書不是服務器證書,而是根CA證書。 – 2017-02-03 11:10:52
我的示例客戶端代碼(link)可以正常使用自簽名服務器證書。我所以SSL_connect後,下面的代碼,並有超過自簽名的證書,接受的完全控制在我的客戶
SSL_CTX* ctx = SSL_CTX_new(SSLv3_method());
// TCP connection and SSL handshake ...
/* Check the certificate */
rc = SSL_get_verify_result(ssl);
if(rc != X509_V_OK) {
if (rc == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT || rc == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) {
fprintf(stderr, "self signed certificate\n");
}
else {
fprintf(stderr, "Certificate verification error: %ld\n", SSL_get_verify_result(ssl));
SSL_CTX_free(ctx);
return 0;
}
}
這會讓你容易受到MITM攻擊!如果你這樣做,任何自簽證書都會被接受。如果證書是可信的,則不會引發您忽略的錯誤。正確的做法是將自簽名證書添加到可信證書列表中。 (請參閱SSL_CTX_load_verify_locations()。) – 2017-02-03 10:59:30
'SSL_VERIFY_NONE'完全禁用證書驗證。你可能不想這樣做,因爲這會讓你容易受到MITM攻擊。正確的做法是將自簽名證書添加到可信證書列表中。 (請參閱SSL_CTX_load_verify_locations()。) – 2017-02-03 10:52:43
順便說一句,錯誤消息並不意味着服務器的證書是自簽名的。這意味着您不信任根CA的證書: ** X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN ** _證書鏈中存在自簽名證書。可以使用不受信任的證書構建證書鏈,但無法在本地找到根CA. 根CA證書始終是自簽名的。 – 2017-02-03 11:15:02