Python 3.4では、証明書がVERIFY_CRL_CHECK_LEAF
またはVERIFY_CRL_CHECK_CHAIN
に設定されているかどうかを確認するために使用できるverify_flags
です。PythonがSSL/TLS接続のCRLを確認できませんでした
私はテストのための簡単なプログラムを書いた。しかし、私のシステムでは、このスクリプトは完全に有効であってもANY接続を検証することができませんでした。
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をチェックすることはできませんが、2パスのプロセスが必要です:CRLを取得するための接続を確立し、通信するための別の接続を作成します...とにかく、適切な暗号化が無視された時代... –
@実際には、基礎となるopensslライブラリの設計です。それとは別に、通常、失効を確認するために巨大なCRLファイルを頻繁に読み込むことは望ましくありません。行く方法は代わりにOCSPです。しかし、Pythonは、他のさまざまなプログラミング言語と同様に、OCSPチェックを行う簡単な方法をサポートしていないようです。 –