在Python 3.4中,可用於檢查證書是否被撤銷對CRL的一個verify_flags
,設置爲VERIFY_CRL_CHECK_LEAF
或VERIFY_CRL_CHECK_CHAIN
。Python無法驗證用於SSL/TLS連接的任何CRL
我寫了一個簡單的測試程序。但是在我的系統中,即使這個腳本完全有效,該腳本也無法驗證任何連接。
import ssl
import socket
def tlscheck(domain, port):
addr = domain
ctx = ssl.create_default_context()
ctx.options &= ssl.CERT_REQUIRED
ctx.verify_flags = ssl.VERIFY_CRL_CHECK_LEAF
ctx.check_hostname = True
#ctx.load_default_certs()
#ctx.set_default_verify_paths()
#ctx.load_verify_locations(cafile="/etc/ssl/certs/ca-certificates.crt")
sock = ctx.wrap_socket(socket.socket(), server_hostname=addr)
sock.connect((addr, port))
import pprint
print("TLS Ceritificate:")
pprint.pprint(sock.getpeercert())
print("TLS Version:", sock.version())
print("TLS Cipher:", sock.cipher()[0])
exit()
tlscheck("stackoverflow.com", 443)
我的密碼總是以ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:645)
退出。
首先我懷疑證書數據庫沒有正確加載。但是在我試過load_default_certs()
,set_default_verify_paths()
,load_verify_locations(cafile="/etc/ssl/certs/ca-certificates.crt")
之後,他們都沒有工作。
此外,ctx.options &= ssl.CERT_REQUIRED
按預期工作,它可以告訴證書鏈是否信任。但不適用於CRL ......這也表明我的CA是正確的。
我知道「/etc/ssl/certs/ca-certificates.crt」包含有效的CA.問題是什麼?
由於'load_verify_locations()'接受一個名爲'cadata'的參數,其中一個二進制字符串可以以DER或PEM格式傳遞,因此不需要手動轉換文件。 –
非常感謝。無論如何,Python中的'ssl'模塊有一個糟糕的設計,它不提供任何API來允許檢查一個已知的證書是否被撤銷!這意味着在創建連接之後,我無法檢查CRL **,但需要一個兩遍過程:建立連接以獲取CRL,並建立另一個連接以進行通信......無論如何,它都是寫入一個適當的加密被忽略的時代... –
@比爾蓋子:這實際上是底層openssl庫的設計。除此之外,您通常不希望加載經常大型的CRL文件來檢查撤銷。要走的路是OCSP。但它看起來像python不支持一種簡單的方法來執行OCSP檢查,類似於其他各種編程語言。 –