17.3. ssl —ソケットオブジェクトのTLS / SSLラッパー—Pythonドキュメント

提供:Dev Guides
< PythonPython/docs/2.7/library/ssl
移動先:案内検索

17.3。 ssl —ソケットオブジェクトのTLS / SSLラッパー

バージョン2.6の新機能。


ソースコード: :source: `Lib / ssl.py`



このモジュールは、クライアント側とサーバー側の両方のネットワークソケットに対して、トランスポート層セキュリティ(「SecureSocketsLayer」と呼ばれることが多い)暗号化およびピア認証機能へのアクセスを提供します。 このモジュールはOpenSSLライブラリを使用します。 OpenSSLがそのプラットフォームにインストールされている限り、すべての最新のUnixシステム、Windows、Mac OS X、およびおそらく追加のプラットフォームで使用できます。

バージョン2.7.13で変更: OpenSSL1.1.0とのリンクをサポートするように更新


ノート

オペレーティングシステムのソケットAPIが呼び出されるため、一部の動作はプラットフォームに依存する場合があります。 インストールされているバージョンのOpenSSLでも、動作にばらつきが生じる可能性があります。 たとえば、TLSv1.1およびTLSv1.2にはopensslバージョン1.0.1が付属しています。


警告

セキュリティに関する考慮事項を読まずにこのモジュールを使用しないでください。 sslモジュールのデフォルト設定は必ずしもアプリケーションに適しているとは限らないため、これを行うと、誤った安心感につながる可能性があります。


このセクションでは、sslモジュールのオブジェクトと機能について説明します。 TLS、SSL、および証明書に関するより一般的な情報については、下部の「関連項目」セクションのドキュメントを参照してください。

このモジュールは、 socket.socket タイプから派生したクラスssl.SSLSocketを提供し、SSLを使用してソケットを通過するデータを暗号化および復号化するソケットのようなラッパーを提供します。 接続の反対側の証明書を取得するgetpeercert()や、安全な接続に使用されている暗号を取得するcipher()などの追加のメソッドをサポートします。

より高度なアプリケーションの場合、 ssl.SSLContext クラスは、設定と証明書の管理に役立ちます。これらは、 SSLContext.wrap_socket()メソッドで作成されたSSLソケットに継承できます。

17.3.1。 関数、定数、および例外

exception ssl.SSLError

基盤となるSSL実装(現在OpenSSLライブラリによって提供されている)からのエラーを通知するために発生します。 これは、基盤となるネットワーク接続に重ねられている高レベルの暗号化および認証レイヤーに問題があることを示しています。 このエラーは socket.error のサブタイプであり、IOErrorのサブタイプです。 SSLError インスタンスのエラーコードとメッセージは、OpenSSLライブラリによって提供されます。

library

SSLPEMX509など、エラーが発生したOpenSSLサブモジュールを指定する文字列ニーモニック。 可能な値の範囲は、OpenSSLのバージョンによって異なります。

バージョン2.7.9の新機能。

reason

このエラーが発生した理由を示す文字列ニーモニック(例:CERTIFICATE_VERIFY_FAILED)。 可能な値の範囲は、OpenSSLのバージョンによって異なります。

バージョン2.7.9の新機能。

exception ssl.SSLZeroReturnError

SSLError のサブクラスは、読み取りまたは書き込みを試みたときに発生し、SSL接続が正常に閉じられました。 これは、基盤となるトランスポート(TCPの読み取り)が閉じられたことを意味するものではないことに注意してください。

バージョン2.7.9の新機能。

exception ssl.SSLWantReadError

データの読み取りまたは書き込みを試みるときにノンブロッキングSSLソケットによって発生する SSLError のサブクラスですが、要求を満たす前に、基盤となるTCPトランスポートでより多くのデータを受信する必要があります。

バージョン2.7.9の新機能。

exception ssl.SSLWantWriteError

ノンブロッキングSSLソケットがデータの読み取りまたは書き込みを試みるときに発生する SSLError のサブクラスですが、要求を満たす前に、基になるTCPトランスポートでより多くのデータを送信する必要があります。

バージョン2.7.9の新機能。

exception ssl.SSLSyscallError

SSLError のサブクラスは、SSLソケットで操作を実行しようとしたときにシステムエラーが発生したときに発生しました。 残念ながら、元のerrno番号を調べる簡単な方法はありません。

バージョン2.7.9の新機能。

exception ssl.SSLEOFError

SSLError のサブクラスは、SSL接続が突然終了したときに発生します。 通常、このエラーが発生したときに、基になるトランスポートを再利用しようとしないでください。

バージョン2.7.9の新機能。

exception ssl.CertificateError
証明書のエラー(ホスト名の不一致など)を通知するために発生します。 ただし、OpenSSLによって検出された証明書エラーは、 SSLError を発生させます。

17.3.1.1。 ソケットの作成

次の関数を使用すると、スタンドアロンのソケットを作成できます。 Python 2.7.9以降では、代わりに SSLContext.wrap_socket()を使用する方が柔軟になります。

ssl.wrap_socket(sock, keyfile=None, certfile=None, server_side=False, cert_reqs=CERT_NONE, ssl_version={see docs}, ca_certs=None, do_handshake_on_connect=True, suppress_ragged_eofs=True, ciphers=None)

socket.socket のインスタンスsockを取得し、 socket.socket のサブタイプであるssl.SSLSocketのインスタンスを返します。これは、基になるソケットをラップします。 SSLコンテキストで。 sockSOCK_STREAM ソケットである必要があります。 他のソケットタイプはサポートされていません。

クライアント側のソケットの場合、コンテキストの構築は怠惰です。 基になるソケットがまだ接続されていない場合、コンテキストの構築は、ソケットでconnect()が呼び出された後に実行されます。 サーバー側ソケットの場合、ソケットにリモートピアがない場合、それはリスニングソケットであると見なされ、サーバー側SSLラッピングはaccept()メソッドを介して受け入れられたクライアント接続で自動的に実行されます。 wrap_socket()は、 SSLError を発生させる可能性があります。

keyfileおよびcertfileパラメーターは、接続のローカル側を識別するために使用される証明書を含むオプションのファイルを指定します。 証明書がcertfileに格納される方法の詳細については、証明書の説明を参照してください。

パラメータserver_sideは、このソケットからサーバー側またはクライアント側のどちらの動作が必要かを識別するブール値です。

パラメータcert_reqsは、接続の反対側から証明書が必要かどうか、および証明書が提供された場合に検証されるかどうかを指定します。 CERT_NONE (証明書は無視されます)、 CERT_OPTIONAL (必須ではありませんが、提供されている場合は検証されます)、または CERT_REQUIRED (必須および検証済み)の3つの値のいずれかである必要があります。 。 このパラメーターの値が CERT_NONE でない場合、ca_certsパラメーターはCA証明書のファイルを指している必要があります。

ca_certsファイルには、接続のもう一方の端から渡された証明書を検証するために使用される、連結された「認証局」証明書のセットが含まれています。 このファイルに証明書を配置する方法の詳細については、証明書の説明を参照してください。

パラメータssl_versionは、使用するSSLプロトコルのバージョンを指定します。 通常、サーバーは特定のプロトコルバージョンを選択し、クライアントはサーバーの選択に適応する必要があります。 ほとんどのバージョンは、他のバージョンと相互運用できません。 指定しない場合、デフォルトは PROTOCOL_SSLv23 です。 他のバージョンとの互換性が最も高くなります。

これは、クライアントのどのバージョン(下側)がサーバー内のどのバージョンに(上部に沿って)接続できるかを示す表です。

クライアント / サーバー

SSLv2

SSLv3

SSLv23

TLSv1

TLSv1.1

TLSv1.2

SSLv2

はい

番号

はい

番号

番号

番号

SSLv3

番号

はい

はい

番号

番号

番号

SSLv23 1

番号

はい

はい

はい

はい

はい

TLSv1

番号

番号

はい

はい

番号

番号

TLSv1.1

番号

番号

はい

番号

はい

番号

TLSv1.2

番号

番号

はい

番号

番号

はい


脚注

1

TLS 1.3プロトコルは、OpenSSL> = 1.1.1の PROTOCOL_SSLv23 で使用できます。 TLS1.3だけに専用のPROTOCOL定数はありません。

ノート

どの接続が成功するかは、OpenSSLのバージョンによって異なります。 たとえば、OpenSSL 1.0.0より前は、SSLv23クライアントは常にSSLv2接続を試行していました。

ciphers パラメーターは、このSSLオブジェクトで使用可能な暗号を設定します。 OpenSSL暗号リスト形式の文字列である必要があります。

パラメータdo_handshake_on_connectは、socket.connect()の実行後にSSLハンドシェイクを自動的に実行するか、またはアプリケーションプログラムが SSLSocket.do_handshake()を呼び出してSSLハンドシェイクを明示的に呼び出すかを指定します。方法。 SSLSocket.do_handshake()を呼び出すと、ハンドシェイクに関係するソケットI / Oのブロック動作をプログラムが明示的に制御できます。

パラメータsuppress_ragged_eofsは、SSLSocket.read()メソッドが接続のもう一方の端から予期しないEOFを通知する方法を指定します。 True (デフォルト)として指定されている場合、基になるソケットから発生した予期しないEOFエラーに応答して、通常のEOF(空のバイトオブジェクト)を返します。 False の場合、例外が発生して呼び出し元に戻されます。

バージョン2.7で変更:新しいオプションの引数暗号


17.3.1.2。 コンテキストの作成

便利な関数は、一般的な目的で SSLContext オブジェクトを作成するのに役立ちます。

ssl.create_default_context(purpose=Purpose.SERVER_AUTH, cafile=None, capath=None, cadata=None)

指定された目的のデフォルト設定で新しい SSLContext オブジェクトを返します。 設定は ssl モジュールによって選択され、通常、 SSLContext コンストラクターを直接呼び出す場合よりも高いセキュリティレベルを表します。

cafilecapathcadata は、 SSLContext.load_verify_locations()のように、証明書の検証で信頼するオプションのCA証明書を表します。 3つすべてがなしの場合、この関数は、代わりにシステムのデフォルトのCA証明書を信頼することを選択できます。

設定は次のとおりです。 PROTOCOL_SSLv23OP_NO_SSLv2 、および OP_NO_SSLv3 、RC4なしおよび認証されていない暗号スイートなしの高暗号化暗号スイート。 SERVER_AUTHpurpose として渡すと、 verify_modeCERT_REQUIRED に設定され、CA証明書が読み込まれます( cafile の少なくとも1つが、 capath または cadata が指定されている)、または SSLContext.load_default_certs()を使用してデフォルトのCA証明書をロードします。

ノート

プロトコル、オプション、暗号、およびその他の設定は、事前の非推奨なしにいつでもより制限的な値に変更される可能性があります。 値は、互換性とセキュリティの間の公正なバランスを表しています。

アプリケーションに特定の設定が必要な場合は、 SSLContext を作成し、自分で設定を適用する必要があります。

ノート

特定の古いクライアントまたはサーバーがこの関数によって作成された SSLContext に接続しようとすると、「プロトコルまたは暗号スイートの不一致」というエラーが表示される場合は、SSL3.0のみをサポートしている可能性があります。この関数は、 OP_NO_SSLv3 の使用を除外します。 SSL3.0は完全に壊れていると広く考えられています。 この機能を引き続き使用したいが、SSL 3.0接続を許可したい場合は、以下を使用してそれらを再度有効にすることができます。

ctx = ssl.create_default_context(Purpose.CLIENT_AUTH)
ctx.options &= ~ssl.OP_NO_SSLv3

バージョン2.7.9の新機能。

バージョン2.7.10で変更: RC4はデフォルトの暗号文字列から削除されました。

バージョン2.7.13で変更: ChaCha20 / Poly1305がデフォルトの暗号文字列に追加されました。

3DESはデフォルトの暗号文字列から削除されました。

ssl._https_verify_certificates(enable=True)

特定のSSLコンテキストを指定せずに、クライアントHTTPS接続を作成するときにサーバー証明書を検証するかどうかを指定します。

Python 2.7.9以降、 httplib およびそれを使用するモジュール( urllib2xmlrpclib など)は、デフォルトで、クライアントHTTPS接続の確立時に受信したリモートサーバー証明書を検証します。 。 このデフォルトの検証では、証明書がシステムトラストストアの認証局によって署名されていること、および提示された証明書の共通名(またはサブジェクト代替名)が要求されたホストと一致することを確認します。

enableTrue に設定すると、このデフォルトの動作が有効になります。

enableFalse に設定すると、デフォルトのHTTPS証明書処理がPython 2.7.8以前のものに戻り、自己署名証明書を使用するサーバー、証明書機関によって署名された証明書を使用するサーバーへの接続が可能になります。システムトラストストアに存在せず、ホスト名が提示されたサーバー証明書と一致しないサーバー。

この関数の先頭の下線は、Python 3のどの実装にも意図的に存在せず、すべてのPython2.7実装に存在しない可能性があることを示しています。 必要に応じて証明書チェックまたはシステムトラストストアをバイパスするポータブルなアプローチは、ツールが、標準ライブラリクライアントモジュールのデフォルトの動作を元に戻すのではなく、適切に構成されたSSLコンテキストを明示的に渡すことによってケースバイケースでそれを有効にすることです。 。

バージョン2.7.12の新機能。

も参照してください

  • CVE-2014-9365 –デフォルト設定を使用したPythonクライアントに対するHTTPS中間者攻撃

  • PEP 476 –HTTPSの証明書検証をデフォルトで有効にする

  • PEP 493 – Python2.7用のHTTPS検証移行ツール



17.3.1.3。 ランダム生成

バージョン2.7.13以降の非推奨: OpenSSLはssl.RAND_pseudo_bytes()を非推奨にしました。代わりに、ssl.RAND_bytes()を使用してください。


ssl.RAND_status()
SSL疑似乱数ジェネレーターに「十分な」ランダム性がシードされている場合はTrueを返し、それ以外の場合はFalseを返します。 ssl.RAND_egd()および ssl.RAND_add()を使用して、疑似乱数ジェネレーターのランダム性を高めることができます。
ssl.RAND_egd(path)

どこかでエントロピー収集デーモン(EGD)を実行していて、 path がそれに対して開かれているソケット接続のパス名である場合、これはソケットから256バイトのランダム性を読み取り、SSLに追加します。生成された秘密鍵のセキュリティを強化するための疑似乱数ジェネレータ。 これは通常、ランダム性のより良いソースがないシステムでのみ必要です。

エントロピー収集デーモンのソースについては、 http://egd.sourceforge.net/または http://prngd.sourceforge.net/ を参照してください。

可用性:LibreSSLおよびOpenSSL> 1.1.0では使用できません

ssl.RAND_add(bytes, entropy)
指定されたバイトをSSL疑似乱数ジェネレーターに混合します。 パラメータ entropy (float)は、文字列に含まれるエントロピーの下限です(したがって、いつでも0.0を使用できます)。 エントロピーのソースの詳細については、 RFC 1750 を参照してください。


17.3.1.4。 証明書の処理

ssl.match_hostname(cert, hostname)

certSSLSocket.getpeercert()によって返されるデコードされた形式)が指定されたホスト名と一致することを確認します。 適用されるルールは、 RFC 2818 および RFC 6125 で概説されているHTTPSサーバーのIDをチェックするためのルールです。ただし、IPアドレスは次のとおりです。現在サポートされていません。 HTTPSに加えて、この機能は、FTPS、IMAPS、POPSなどのさまざまなSSLベースのプロトコルでサーバーのIDをチェックするのに適している必要があります。

CertificateError は失敗時に発生します。 成功すると、関数は何も返しません。

>>> cert = {'subject': ((('commonName', 'example.com'),),)}
>>> ssl.match_hostname(cert, "example.com")
>>> ssl.match_hostname(cert, "example.org")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/py3k/Lib/ssl.py", line 130, in match_hostname
ssl.CertificateError: hostname 'example.org' doesn't match 'example.com'

バージョン2.7.9の新機能。

ssl.cert_time_to_seconds(cert_time)

"%b %d %H:%M:%S %Y %Z" strptime形式(Cロケール)の証明書からの「notBefore」または「notAfter」日付を表すcert_time文字列を指定して、エポックからの時間を秒単位で返します。

次に例を示します。

>>> import ssl
>>> timestamp = ssl.cert_time_to_seconds("Jan  5 09:34:43 2018 GMT")
>>> timestamp
1515144883
>>> from datetime import datetime
>>> print(datetime.utcfromtimestamp(timestamp))
2018-01-05 09:34:43

「notBefore」または「notAfter」の日付はGMT( RFC 5280 )を使用する必要があります。

バージョン2.7.9で変更:入力文字列の「GMT」タイムゾーンで指定されたUTC単位の時刻として入力時刻を解釈します。 以前はローカルタイムゾーンが使用されていました。 整数を返します(入力形式で秒の小数部はありません)

ssl.get_server_certificate(addr, ssl_version=PROTOCOL_SSLv23, ca_certs=None)

SSLで保護されたサーバーのアドレスaddrを( hostnameport-number )ペアとして指定すると、サーバーの証明書をフェッチし、それをPEMとして返します。 -エンコードされた文字列。 ssl_versionが指定されている場合、そのバージョンのSSLプロトコルを使用してサーバーへの接続を試みます。 ca_certsを指定する場合は、 wrap_socket()の同じパラメーターに使用されるのと同じ形式のルート証明書のリストを含むファイルである必要があります。 呼び出しは、そのルート証明書のセットに対してサーバー証明書の検証を試み、検証の試みが失敗した場合は失敗します。

バージョン2.7.9で変更:この関数はIPv6互換になり、デフォルトの ssl_versionPROTOCOL_SSLv3 から PROTOCOL_SSLv23 に変更されました。最新のサーバーとの最大の互換性。

ssl.DER_cert_to_PEM_cert(DER_cert_bytes)
証明書をDERでエンコードされたバイトのブロブとして指定すると、同じ証明書のPEMでエンコードされた文字列バージョンが返されます。
ssl.PEM_cert_to_DER_cert(PEM_cert_string)
証明書をASCIIPEM文字列として指定すると、同じ証明書に対してDERでエンコードされたバイトシーケンスを返します。
ssl.get_default_verify_paths()

OpenSSLのデフォルトのcafileおよびcapathへのパスを持つ名前付きタプルを返します。 パスは、 SSLContext.set_default_verify_paths()で使用されるものと同じです。 戻り値は、名前付きタプル DefaultVerifyPathsです。

  • cafile -cafileへの解決済みパス、またはファイルが存在しない場合はNone

  • capath -capathへのパスを解決しました。ディレクトリが存在しない場合は、Noneを使用します。

  • openssl_cafile_env -cafileを指すOpenSSLの環境キー、

  • openssl_cafile -cafileへのハードコードされたパス、

  • openssl_capath_env -capathを指すOpenSSLの環境キー、

  • openssl_capath -capathディレクトリへのハードコードされたパス

可用性:LibreSSLは環境変数openssl_cafile_envおよびopenssl_capath_envを無視します

バージョン2.7.9の新機能。

ssl.enum_certificates(store_name)

Windowsのシステム証明書ストアから証明書を取得します。 store_name は、CAROOT、またはMYのいずれかです。 Windowsは、追加の証明書ストアも提供する場合があります。

この関数は、(cert_bytes、encoding_type、trust)タプルのリストを返します。 encoding_typeは、cert_bytesのエンコーディングを指定します。 X.509ASN.1データの場合はx509_asn、PKCS#7ASN.1データの場合はpkcs_7_asnのいずれかです。 信頼は、証明書の目的をOIDのセットとして指定するか、証明書がすべての目的で信頼できる場合は正確にTrueを指定します。

例:

>>> ssl.enum_certificates("CA")
[(b'data...', 'x509_asn', {'1.3.6.1.5.5.7.3.1', '1.3.6.1.5.5.7.3.2'}),
 (b'data...', 'x509_asn', True)]

可用性:Windows。

バージョン2.7.9の新機能。

ssl.enum_crls(store_name)

Windowsのシステム証明書ストアからCRLを取得します。 store_name は、CAROOT、またはMYのいずれかです。 Windowsは、追加の証明書ストアも提供する場合があります。

この関数は、(cert_bytes、encoding_type、trust)タプルのリストを返します。 encoding_typeは、cert_bytesのエンコーディングを指定します。 X.509ASN.1データの場合はx509_asn、PKCS#7ASN.1データの場合はpkcs_7_asnのいずれかです。

可用性:Windows。

バージョン2.7.9の新機能。


17.3.1.5。 定数

ssl.CERT_NONE

SSLContext.verify_mode の可能な値、または wrap_socket()へのcert_reqsパラメーター。 このモード(デフォルト)では、ソケット接続の反対側からの証明書は必要ありません。 証明書がもう一方の端から受信された場合、それを検証する試みは行われません。

以下のセキュリティに関する考慮事項の説明を参照してください。

ssl.CERT_OPTIONAL

SSLContext.verify_mode の可能な値、または wrap_socket()へのcert_reqsパラメーター。 このモードでは、ソケット接続の反対側からの証明書は必要ありません。 ただし、それらが提供されている場合、検証が試行され、失敗すると SSLError が発生します。

この設定を使用するには、有効なCA証明書のセットを SSLContext.load_verify_locations()に渡すか、ca_certsパラメーターの値として wrap_socket()に渡す必要があります。 ]。

ssl.CERT_REQUIRED

SSLContext.verify_mode の可能な値、または wrap_socket()へのcert_reqsパラメーター。 このモードでは、ソケット接続の反対側から証明書が必要です。 SSLError は、証明書が提供されていない場合、またはその検証が失敗した場合に発生します。

この設定を使用するには、有効なCA証明書のセットを SSLContext.load_verify_locations()に渡すか、ca_certsパラメーターの値として wrap_socket()に渡す必要があります。 ]。

ssl.VERIFY_DEFAULT

SSLContext.verify_flags の可能な値。 このモードでは、証明書失効リスト(CRL)はチェックされません。 デフォルトでは、OpenSSLはCRLを必要とせず検証もしません。

バージョン2.7.9の新機能。

ssl.VERIFY_CRL_CHECK_LEAF

SSLContext.verify_flags の可能な値。 このモードでは、ピア証明書のみがチェックされ、中間CA証明書はチェックされません。 このモードには、ピア証明書の発行者(その直接の祖先CA)によって署名された有効なCRLが必要です。 適切なものがロードされていない場合 SSLContext.load_verify_locations 、検証は失敗します。

バージョン2.7.9の新機能。

ssl.VERIFY_CRL_CHECK_CHAIN

SSLContext.verify_flags の可能な値。 このモードでは、ピア証明書チェーン内のすべての証明書のCRLがチェックされます。

バージョン2.7.9の新機能。

ssl.VERIFY_X509_STRICT

SSLContext.verify_flags の可能な値は、壊れたX.509証明書の回避策を無効にします。

バージョン2.7.9の新機能。

ssl.VERIFY_X509_TRUSTED_FIRST

SSLContext.verify_flags の可能な値。 証明書を検証するための信頼チェーンを構築するときに、信頼できる証明書を優先するようにOpenSSLに指示します。 このフラグはデフォルトで有効になっています。

バージョン2.7.10の新機能。

ssl.PROTOCOL_TLS

クライアントとサーバーの両方がサポートする最高のプロトコルバージョンを選択します。 名前にもかかわらず、このオプションは「TLS」プロトコルと「SSL」を選択できます。

バージョン2.7.13の新機能。

ssl.PROTOCOL_SSLv23

PROTOCOL_TLSのエイリアス。

バージョン2.7.13以降非推奨:代わりにPROTOCOL_TLSを使用してください。

ssl.PROTOCOL_SSLv2

チャネル暗号化プロトコルとしてSSLバージョン2を選択します。

OpenSSLがOPENSSL_NO_SSL2フラグを使用してコンパイルされている場合、このプロトコルは使用できません。

警告

SSLバージョン2は安全ではありません。 その使用は強くお勧めしません。

バージョン2.7.13以降非推奨: OpenSSLはSSLv2のサポートを削除しました。

ssl.PROTOCOL_SSLv3

チャネル暗号化プロトコルとしてSSLバージョン3を選択します。

OpenSSLがOPENSSL_NO_SSLv3フラグを使用してコンパイルされている場合、このプロトコルは使用できません。

警告

SSLバージョン3は安全ではありません。 その使用は強くお勧めしません。

バージョン2.7.13以降非推奨: OpenSSLはすべてのバージョン固有のプロトコルを非推奨にしました。 代わりに、OP_NO_SSLv3のようなフラグを持つデフォルトのプロトコルを使用してください。

ssl.PROTOCOL_TLSv1

チャネル暗号化プロトコルとしてTLSバージョン1.0を選択します。

バージョン2.7.13以降非推奨: OpenSSLはすべてのバージョン固有のプロトコルを非推奨にしました。 代わりに、OP_NO_SSLv3のようなフラグを持つデフォルトのプロトコルを使用してください。

ssl.PROTOCOL_TLSv1_1

チャネル暗号化プロトコルとしてTLSバージョン1.1を選択します。 opensslバージョン1.0.1以降でのみ使用できます。

バージョン2.7.9の新機能。

バージョン2.7.13以降非推奨: OpenSSLはすべてのバージョン固有のプロトコルを非推奨にしました。 代わりに、OP_NO_SSLv3のようなフラグを持つデフォルトのプロトコルを使用してください。

ssl.PROTOCOL_TLSv1_2

チャネル暗号化プロトコルとしてTLSバージョン1.2を選択します。 これは最新バージョンであり、双方がそれを話すことができれば、おそらく最大限の保護のための最良の選択です。 opensslバージョン1.0.1以降でのみ使用できます。

バージョン2.7.9の新機能。

バージョン2.7.13以降非推奨: OpenSSLはすべてのバージョン固有のプロトコルを非推奨にしました。 代わりに、OP_NO_SSLv3のようなフラグを持つデフォルトのプロトコルを使用してください。

ssl.OP_ALL

他のSSL実装に存在するさまざまなバグの回避策を有効にします。 このオプションはデフォルトで設定されています。 OpenSSLのSSL_OP_ALL定数と同じフラグを設定する必要はありません。

バージョン2.7.9の新機能。

ssl.OP_NO_SSLv2

SSLv2接続を防止します。 このオプションは、 PROTOCOL_SSLv23 と組み合わせた場合にのみ適用できます。 これにより、ピアがプロトコルバージョンとしてSSLv2を選択できなくなります。

バージョン2.7.9の新機能。

ssl.OP_NO_SSLv3

SSLv3接続を防止します。 このオプションは、 PROTOCOL_SSLv23 と組み合わせた場合にのみ適用できます。 これにより、ピアがプロトコルバージョンとしてSSLv3を選択できなくなります。

バージョン2.7.9の新機能。

ssl.OP_NO_TLSv1

TLSv1接続を防止します。 このオプションは、 PROTOCOL_SSLv23 と組み合わせた場合にのみ適用できます。 これにより、ピアがプロトコルバージョンとしてTLSv1を選択できなくなります。

バージョン2.7.9の新機能。

ssl.OP_NO_TLSv1_1

TLSv1.1接続を防止します。 このオプションは、 PROTOCOL_SSLv23 と組み合わせた場合にのみ適用できます。 これにより、ピアがプロトコルバージョンとしてTLSv1.1を選択できなくなります。 opensslバージョン1.0.1以降でのみ使用できます。

バージョン2.7.9の新機能。

ssl.OP_NO_TLSv1_2

TLSv1.2接続を防止します。 このオプションは、 PROTOCOL_SSLv23 と組み合わせた場合にのみ適用できます。 これにより、ピアがプロトコルバージョンとしてTLSv1.2を選択できなくなります。 opensslバージョン1.0.1以降でのみ使用できます。

バージョン2.7.9の新機能。

ssl.OP_NO_TLSv1_3

TLSv1.3接続を防止します。 このオプションは、 PROTOCOL_TLS と組み合わせた場合にのみ適用できます。 これにより、ピアがプロトコルバージョンとしてTLSv1.3を選択できなくなります。 TLS 1.3は、OpenSSL1.1.1以降で使用できます。 Pythonが古いバージョンのOpenSSLに対してコンパイルされている場合、フラグはデフォルトで 0 になります。

バージョン2.7.15の新機能。

ssl.OP_CIPHER_SERVER_PREFERENCE

クライアントではなく、サーバーの暗号順序設定を使用します。 このオプションは、クライアントソケットとSSLv2サーバーソケットには影響しません。

バージョン2.7.9の新機能。

ssl.OP_SINGLE_DH_USE

個別のSSLセッションで同じDHキーを再利用できないようにします。 これにより、Forward Secrecyが向上しますが、より多くの計算リソースが必要になります。 このオプションは、サーバーソケットにのみ適用されます。

バージョン2.7.9の新機能。

ssl.OP_SINGLE_ECDH_USE

個別のSSLセッションで同じECDHキーを再利用できないようにします。 これにより、Forward Secrecyが向上しますが、より多くの計算リソースが必要になります。 このオプションは、サーバーソケットにのみ適用されます。

バージョン2.7.9の新機能。

ssl.OP_ENABLE_MIDDLEBOX_COMPAT

TLS1.3ハンドシェイクでダミーのChangeCipher Spec(CCS)メッセージを送信して、TLS1.3接続をTLS1.2接続のように見せます。

このオプションは、OpenSSL1.1.1以降でのみ使用できます。

バージョン2.7.16の新機能。

ssl.OP_NO_COMPRESSION

SSLチャネルの圧縮を無効にします。 これは、アプリケーションプロトコルが独自の圧縮スキームをサポートしている場合に役立ちます。

このオプションは、OpenSSL1.0.0以降でのみ使用できます。

バージョン2.7.9の新機能。

ssl.HAS_ALPN

RFC 7301 で説明されているように、OpenSSLライブラリに Application-Layer Protocol Negotiation TLS拡張のサポートが組み込まれているかどうか。

バージョン2.7.10の新機能。

ssl.HAS_ECDH

OpenSSLライブラリに、楕円曲線ベースのDiffie-Hellman鍵交換のサポートが組み込まれているかどうか。 これは、ディストリビューターによって機能が明示的に無効にされていない限り、当てはまるはずです。

バージョン2.7.9の新機能。

ssl.HAS_SNI

OpenSSLライブラリに Server Name Indication 拡張機能( RFC 4366 で定義されている)のサポートが組み込まれているかどうか。

バージョン2.7.9の新機能。

ssl.HAS_NPN

NPNドラフト仕様で説明されているように、OpenSSLライブラリに Next Protocol Negotiation のサポートが組み込まれているかどうか。 trueの場合、 SSLContext.set_npn_protocols()メソッドを使用して、サポートするプロトコルをアドバタイズできます。

バージョン2.7.9の新機能。

ssl.HAS_TLSv1_3

OpenSSLライブラリにTLS1.3プロトコルのサポートが組み込まれているかどうか。

バージョン2.7.15の新機能。

ssl.CHANNEL_BINDING_TYPES

サポートされているTLSチャネルバインディングタイプのリスト。 このリストの文字列は、 SSLSocket.get_channel_binding()への引数として使用できます。

バージョン2.7.9の新機能。

ssl.OPENSSL_VERSION

インタプリタによってロードされたOpenSSLライブラリのバージョン文字列:

>>> ssl.OPENSSL_VERSION
'OpenSSL 0.9.8k 25 Mar 2009'

バージョン2.7の新機能。

ssl.OPENSSL_VERSION_INFO

OpenSSLライブラリに関するバージョン情報を表す5つの整数のタプル:

>>> ssl.OPENSSL_VERSION_INFO
(0, 9, 8, 11, 15)

バージョン2.7の新機能。

ssl.OPENSSL_VERSION_NUMBER

単一の整数としてのOpenSSLライブラリの生のバージョン番号:

>>> ssl.OPENSSL_VERSION_NUMBER
9470143L
>>> hex(ssl.OPENSSL_VERSION_NUMBER)
'0x9080bfL'

バージョン2.7の新機能。

ssl.ALERT_DESCRIPTION_HANDSHAKE_FAILURE
ssl.ALERT_DESCRIPTION_INTERNAL_ERROR
ALERT_DESCRIPTION_*

RFC 5246 などからのアラートの説明。 IANA TLS Alert Registry には、このリストと、その意味が定義されているRFCへの参照が含まれています。

SSLContext.set_servername_callback()のコールバック関数の戻り値として使用されます。

バージョン2.7.9の新機能。

Purpose.SERVER_AUTH

create_default_context()および SSLContext.load_default_certs()のオプション。 この値は、コンテキストを使用してWebサーバーを認証できることを示します(したがって、コンテキストはクライアント側のソケットを作成するために使用されます)。

バージョン2.7.9の新機能。

Purpose.CLIENT_AUTH

create_default_context()および SSLContext.load_default_certs()のオプション。 この値は、コンテキストを使用してWebクライアントを認証できることを示します(したがって、サーバー側のソケットを作成するために使用されます)。

バージョン2.7.9の新機能。


17.3.2。 SSLソケット

SSLソケットは、 Socket Objects の次のメソッドを提供します。

ただし、SSL(およびTLS)プロトコルにはTCPの上に独自のフレーミングがあるため、SSLソケットの抽象化は、特定の点で、通常のOSレベルのソケットの仕様とは異なる可能性があります。 特に非ブロッキングソケットに関する注記を参照してください。

SSLソケットには、次の追加のメソッドと属性もあります。

SSLSocket.do_handshake()

SSLセットアップハンドシェイクを実行します。

バージョン2.7.9で変更:ハンドシェイクメソッドは、ソケットの contextcheck_hostname 属性がtrueの場合、 match_hostname()も実行します。

SSLSocket.getpeercert(binary_form=False)

接続のもう一方の端にピアの証明書がない場合は、Noneを返します。 SSLハンドシェイクがまだ行われていない場合は、ValueErrorを上げます。

binary_formパラメーターが False であり、証明書がピアから受信された場合、このメソッドは dict インスタンスを返します。 証明書が検証されなかった場合、dictは空です。 証明書が検証された場合、subject(証明書が発行されたプリンシパル)とissuer(証明書を発行したプリンシパル)など、いくつかのキーを含むdictが返されます。 証明書に Subject Alternative Name 拡張子のインスタンスが含まれている場合( RFC 3280 を参照)、subjectAltNameキーもあります。辞書。

subjectフィールドとissuerフィールドは、それぞれのフィールドの証明書のデータ構造で指定された相対識別名(RDN)のシーケンスを含むタプルであり、各RDNは名前と値のペアのシーケンスです。 これが実際の例です:

{'issuer': ((('countryName', 'IL'),),
            (('organizationName', 'StartCom Ltd.'),),
            (('organizationalUnitName',
              'Secure Digital Certificate Signing'),),
            (('commonName',
              'StartCom Class 2 Primary Intermediate Server CA'),)),
 'notAfter': 'Nov 22 08:15:19 2013 GMT',
 'notBefore': 'Nov 21 03:09:52 2011 GMT',
 'serialNumber': '95F0',
 'subject': ((('description', '571208-SLe257oHY9fVQ07Z'),),
             (('countryName', 'US'),),
             (('stateOrProvinceName', 'California'),),
             (('localityName', 'San Francisco'),),
             (('organizationName', 'Electronic Frontier Foundation, Inc.'),),
             (('commonName', '*.eff.org'),),
             (('emailAddress', '[email protected]'),)),
 'subjectAltName': (('DNS', '*.eff.org'), ('DNS', 'eff.org')),
 'version': 3}

ノート

特定のサービスの証明書を検証するには、 match_hostname()関数を使用できます。

binary_formパラメーターが True であり、証明書が提供された場合、このメソッドは、証明書全体のDERエンコード形式をバイトシーケンスとして返すか、 None を返します。ピアが証明書を提供しなかった場合。 ピアが証明書を提供するかどうかは、SSLソケットの役割によって異なります。

  • クライアントSSLソケットの場合、検証が必要かどうかに関係なく、サーバーは常に証明書を提供します。

  • サーバーSSLソケットの場合、クライアントはサーバーから要求された場合にのみ証明書を提供します。 したがって、 CERT_OPTIONAL または CERT_REQUIRED ではなく CERT_NONE を使用した場合、 getpeercert()None を返します。

バージョン2.7.9で変更:返される辞書には、issuernotBeforeなどの追加アイテムが含まれています。 さらに、ハンドシェイクが行われない場合、ValueErrorが発生します。 返されるディクショナリには、crlDistributionPointscaIssuersOCSP URIなどの追加のX509v3拡張アイテムが含まれています。

SSLSocket.cipher()
使用されている暗号の名前、その使用を定義するSSLプロトコルのバージョン、および使用されている秘密ビットの数を含む3つの値のタプルを返します。 接続が確立されていない場合は、Noneを返します。
SSLSocket.compression()

文字列として使用されている圧縮アルゴリズムを返します。接続が圧縮されていない場合はNoneを返します。

高レベルのプロトコルが独自の圧縮メカニズムをサポートしている場合は、 OP_NO_COMPRESSION を使用してSSLレベルの圧縮を無効にすることができます。

バージョン2.7.9の新機能。

SSLSocket.get_channel_binding(cb_type='tls-unique')

現在の接続のチャネルバインディングデータをbytesオブジェクトとして取得します。 接続されていない場合、またはハンドシェイクが完了していない場合は、Noneを返します。

cb_type パラメーターを使用すると、目的のチャネルバインディングタイプを選択できます。 有効なチャネルバインディングタイプは、 CHANNEL_BINDING_TYPES リストにリストされています。 現在、 RFC 5929 で定義されている「tls-unique」チャネルバインディングのみがサポートされています。 ValueErrorは、サポートされていないチャネルバインディングタイプが要求された場合に発生します。

バージョン2.7.9の新機能。

SSLSocket.selected_alpn_protocol()

TLSハンドシェイク中に選択されたプロトコルを返します。 SSLContext.set_alpn_protocols()が呼び出されなかった場合、相手がALPNをサポートしていない場合、このソケットがクライアントの提案されたプロトコルのいずれもサポートしていない場合、またはハンドシェイクがまだ発生していない場合、Noneが返されます。

バージョン2.7.10の新機能。

SSLSocket.selected_npn_protocol()

TLS / SSLハンドシェイク中に選択された高レベルのプロトコルを返します。 SSLContext.set_npn_protocols()が呼び出されなかった場合、相手がNPNをサポートしていない場合、またはハンドシェイクがまだ発生していない場合は、Noneが返されます。

バージョン2.7.9の新機能。

SSLSocket.unwrap()
SSLシャットダウンハンドシェイクを実行します。これにより、基になるソケットからTLSレイヤーが削除され、基になるソケットオブジェクトが返されます。 これは、接続を介した暗号化された操作から暗号化されていない操作に移行するために使用できます。 返されたソケットは、元のソケットではなく、接続の反対側とのさらなる通信に常に使用する必要があります。
SSLSocket.version()

接続によってネゴシエートされた実際のSSLプロトコルバージョンを文字列として返すか、Noneは安全な接続が確立されていません。 この記事の執筆時点で、可能な戻り値には、"SSLv2""SSLv3""TLSv1""TLSv1.1"、および"TLSv1.2"が含まれます。 最近のOpenSSLバージョンでは、より多くの戻り値が定義される場合があります。

バージョン2.7.9の新機能。

SSLSocket.context

このSSLソケットが関連付けられている SSLContext オブジェクト。 SSLソケットが( SSLContext.wrap_socket()ではなく)トップレベルの wrap_socket()関数を使用して作成された場合、これはこのSSLソケット用に作成されたカスタムコンテキストオブジェクトです。

バージョン2.7.9の新機能。


17.3.3。 SSLコンテキスト

バージョン2.7.9の新機能。


SSLコンテキストは、SSL構成オプション、証明書、秘密鍵など、単一のSSL接続よりも長寿命のさまざまなデータを保持します。 また、同じクライアントからの繰り返し接続を高速化するために、サーバー側ソケットのSSLセッションのキャッシュを管理します。

class ssl.SSLContext(protocol)

新しいSSLコンテキストを作成します。 プロトコルを渡す必要があります。これは、このモジュールで定義されているPROTOCOL_*定数の1つである必要があります。 PROTOCOL_SSLv23 は現在、相互運用性を最大化するために推奨されています。

も参照してください

create_default_context()を使用すると、 ssl モジュールで特定の目的のセキュリティ設定を選択できます。

バージョン2.7.16で変更:コンテキストは安全なデフォルト値で作成されます。 オプション OP_NO_COMPRESSIONOP_CIPHER_SERVER_PREFERENCEOP_SINGLE_DH_USEOP_SINGLE_ECDH_USE 、 OP_X167Xv2 ])、および OP_NO_SSLv3PROTOCOL_SSLv3 を除く)がデフォルトで設定されています。 最初の暗号スイートリストには、HIGH暗号のみが含まれ、NULL暗号は含まれず、MD5暗号は含まれません( PROTOCOL_SSLv2 を除く)。

SSLContext オブジェクトには、次のメソッドと属性があります。

SSLContext.cert_store_stats()

ロードされたX.509証明書の数、CA証明書としてフラグが立てられたX.509証明書の数、および辞書としての証明書失効リストに関する統計を取得します。

1つのCA証明書と1つの他の証明書を持つコンテキストの例:

>>> context.cert_store_stats()
{'crl': 0, 'x509_ca': 1, 'x509': 2}
SSLContext.load_cert_chain(certfile, keyfile=None, password=None)

秘密鍵と対応する証明書をロードします。 certfile 文字列は、証明書と、証明書の信頼性を確立するために必要な任意の数のCA証明書を含むPEM形式の単一ファイルへのパスである必要があります。 keyfile 文字列は、存在する場合、の秘密鍵を含むファイルを指している必要があります。 それ以外の場合、秘密鍵は certfile からも取得されます。 証明書が証明書ファイルに格納される方法の詳細については、証明書の説明を参照してください。

password 引数は、秘密鍵を復号化するためのパスワードを取得するために呼び出す関数である可能性があります。 秘密鍵が暗号化されており、パスワードが必要な場合にのみ呼び出されます。 引数なしで呼び出され、文字列、バイト、またはバイト配列を返す必要があります。 戻り値が文字列の場合、キーを復号化するために使用する前に、UTF-8としてエンコードされます。 または、文字列、バイト、またはバイト配列の値を password 引数として直接指定することもできます。 秘密鍵が暗号化されておらず、パスワードが不要な場合は無視されます。

password 引数が指定されておらず、パスワードが必要な場合は、OpenSSLの組み込みのパスワードプロンプトメカニズムを使用して、ユーザーにパスワードの入力をインタラクティブに要求します。

秘密鍵が証明書と一致しない場合、 SSLError が発生します。

SSLContext.load_default_certs(purpose=Purpose.SERVER_AUTH)

デフォルトの場所からデフォルトの「証明機関」(CA)証明書のセットをロードします。 Windowsでは、CAおよびROOTシステムストアからCA証明書をロードします。 他のシステムでは、 SSLContext.set_default_verify_paths()を呼び出します。 将来的には、このメソッドは他の場所からもCA証明書をロードする可能性があります。

purpose フラグは、ロードされるCA証明書の種類を指定します。 デフォルト設定 Purpose.SERVER_AUTH は、TLS Webサーバー認証(クライアント側ソケット)に対してフラグが付けられ、信頼されている証明書をロードします。 Purpose.CLIENT_AUTH は、サーバー側でクライアント証明書を検証するためにCA証明書をロードします。

SSLContext.load_verify_locations(cafile=None, capath=None, cadata=None)

verify_modeCERT_NONE 以外の場合に、他のピアの証明書を検証するために使用される「認証局」(CA)証明書のセットをロードします。 cafile または capath の少なくとも1つを指定する必要があります。

このメソッドは、PEMまたはDER形式の証明書失効リスト(CRL)をロードすることもできます。 CRLを使用するには、 SSLContext.verify_flags を適切に構成する必要があります。

cafile 文字列は、存在する場合、PEM形式で連結されたCA証明書のファイルへのパスです。 このファイルに証明書を配置する方法の詳細については、証明書の説明を参照してください。

capath 文字列は、存在する場合、 OpenSSL固有のレイアウトに従って、PEM形式の複数のCA証明書を含むディレクトリへのパスです。

cadata オブジェクトは、存在する場合、1つ以上のPEMエンコードされた証明書のASCII文字列、またはDERエンコードされた証明書のバイトのようなオブジェクトのいずれかです。 capath と同様に、PEMでエンコードされた証明書の周りの余分な行は無視されますが、少なくとも1つの証明書が存在する必要があります。

SSLContext.get_ca_certs(binary_form=False)

ロードされた「証明機関」(CA)証明書のリストを取得します。 binary_formパラメーターが False の場合、各リストエントリは SSLSocket.getpeercert()の出力のようなdictです。 それ以外の場合、メソッドはDERでエンコードされた証明書のリストを返します。 返されるリストには、SSL接続によって証明書が要求およびロードされない限り、 capath からの証明書は含まれていません。

ノート

capathディレクトリ内の証明書は、少なくとも1回使用されていない限り、ロードされません。

SSLContext.set_default_verify_paths()
OpenSSLライブラリの構築時に定義されたファイルシステムパスから、デフォルトの「認証局」(CA)証明書のセットをロードします。 残念ながら、このメソッドが成功したかどうかを知る簡単な方法はありません。証明書が見つからない場合でもエラーは返されません。 ただし、OpenSSLライブラリがオペレーティングシステムの一部として提供されている場合は、適切に構成されている可能性があります。
SSLContext.set_ciphers(ciphers)

このコンテキストで作成されたソケットに使用可能な暗号を設定します。 OpenSSL暗号リスト形式の文字列である必要があります。 暗号を選択できない場合(コンパイル時オプションまたは他の構成で指定されたすべての暗号の使用が禁止されているため)、 SSLError が発生します。

ノート

接続すると、SSLソケットの SSLSocket.cipher()メソッドが現在選択されている暗号を提供します。

OpenSSL 1.1.1では、TLS1.3暗号スイートがデフォルトで有効になっています。 スイートは set_ciphers()で無効にすることはできません。

SSLContext.set_alpn_protocols(protocols)

SSL / TLSハンドシェイク中にソケットがアドバタイズするプロトコルを指定します。 ['http/1.1', 'spdy/2']のように、優先順に並べられたASCII文字列のリストである必要があります。 プロトコルの選択はハンドシェイク中に行われ、 RFC 7301 に従って実行されます。 ハンドシェイクが成功すると、 SSLSocket.selected_alpn_protocol()メソッドは合意されたプロトコルを返します。

HAS_ALPN がFalseの場合、このメソッドはNotImplementedErrorを発生させます。

OpenSSL 1.1.0から1.1.0eは、双方がALPNをサポートしているがプロトコルについて合意できない場合、ハンドシェイクを中止し、 SSLError を発生させます。 1.1.0f +は1.0.2のように動作し、 SSLSocket.selected_alpn_protocol()はNoneを返します。

バージョン2.7.10の新機能。

SSLContext.set_npn_protocols(protocols)

SSL / TLSハンドシェイク中にソケットがアドバタイズするプロトコルを指定します。 ['http/1.1', 'spdy/2']のように、優先順に並べられた文字列のリストである必要があります。 プロトコルの選択はハンドシェイク中に行われ、 NPNドラフト仕様に従って実行されます。 ハンドシェイクが成功すると、 SSLSocket.selected_npn_protocol()メソッドは合意されたプロトコルを返します。

HAS_NPN がFalseの場合、このメソッドはNotImplementedErrorを発生させます。

SSLContext.set_servername_callback(server_name_callback)

TLSクライアントがサーバー名の指示を指定したときにSSL / TLSサーバーがTLSクライアントHelloハンドシェイクメッセージを受信した後に呼び出されるコールバック関数を登録します。 サーバー名表示メカニズムは、 RFC 6066 セクション3-サーバー名表示で指定されています。

SSLContextごとに設定できるコールバックは1つだけです。 server_name_callbackNoneの場合、コールバックは無効になります。 後でこの関数を呼び出すと、以前に登録されたコールバックが無効になります。

コールバック関数 server_name_callback は、3つの引数で呼び出されます。 1つ目はssl.SSLSocketで、2つ目はクライアントが通信しようとしているサーバー名を表す文字列です(TLS Client Helloにサーバー名が含まれていない場合は None )。 3番目の引数は、元の SSLContext です。 サーバー名引数は、IDNAでデコードされたサーバー名です。

このコールバックの一般的な使用法は、ssl.SSLSocketSSLSocket.context 属性を、サーバー名と一致する証明書チェーンを表すタイプ SSLContext の新しいオブジェクトに変更することです。 。

TLS接続の初期のネゴシエーションフェーズのため、 SSLSocket.selected_alpn_protocol()SSLSocket.context のように限られたメソッドと属性のみが使用可能です。 SSLSocket.getpeercert()SSLSocket.getpeercert()SSLSocket.cipher()およびSSLSocket.compress()メソッドでは、TLS接続が進行している必要がありますTLSクライアントHelloを超えているため、意味のある戻り値が含まれず、安全に呼び出すこともできません。

server_name_callback 関数は、TLSネゴシエーションを続行できるように、Noneを返す必要があります。 TLS障害が必要な場合は、定数 ALERT_DESCRIPTION _ * を返すことができます。 他の戻り値は、 ALERT_DESCRIPTION_INTERNAL_ERROR でTLS致命的なエラーになります。

サーバー名にIDNAデコードエラーがある場合、TLS接続は、クライアントへの ALERT_DESCRIPTION_INTERNAL_ERROR 致命的なTLSアラートメッセージで終了します。

server_name_callback 関数から例外が発生した場合、TLS接続は致命的なTLSアラートメッセージ ALERT_DESCRIPTION_HANDSHAKE_FAILURE で終了します。

このメソッドは、OpenSSLライブラリの構築時にOPENSSL_NO_TLSEXTが定義されている場合、NotImplementedErrorを発生させます。

SSLContext.load_dh_params(dhfile)

Diffie-Helman(DH)鍵交換の鍵生成パラメーターをロードします。 DH鍵交換を使用すると、計算リソース(サーバーとクライアントの両方)を犠牲にして前方秘書が改善されます。 dhfile パラメーターは、PEM形式のDHパラメーターを含むファイルへのパスである必要があります。

この設定は、クライアントソケットには適用されません。 OP_SINGLE_DH_USE オプションを使用して、セキュリティをさらに向上させることもできます。

SSLContext.set_ecdh_curve(curve_name)

楕円曲線ベースのDiffie-Hellman(ECDH)鍵交換の曲線名を設定します。 ECDHは、通常のDHよりも大幅に高速ですが、ほぼ間違いなく安全です。 curve_name パラメーターは、よく知られている楕円曲線を表す文字列である必要があります。たとえば、広くサポートされている曲線の場合はprime256v1です。

この設定は、クライアントソケットには適用されません。 OP_SINGLE_ECDH_USE オプションを使用して、セキュリティをさらに向上させることもできます。

HAS_ECDHFalseの場合、このメソッドは使用できません。

も参照してください

SSL / TLSとPerfectForward Secrecy

ヴィンセントベルナト。


SSLContext.wrap_socket(sock, server_side=False, do_handshake_on_connect=True, suppress_ragged_eofs=True, server_hostname=None)

既存のPythonソケット sock をラップし、SSLSocketオブジェクトを返します。 sockSOCK_STREAM ソケットである必要があります。 他のソケットタイプはサポートされていません。

返されるSSLソケットは、コンテキスト、その設定、および証明書に関連付けられています。 パラメータ server_sidedo_handshake_on_connect 、および suppress_ragged_eofs は、トップレベルの wrap_socket()関数と同じ意味を持ちます。

クライアント接続では、オプションのパラメーター server_hostname は、接続先のサービスのホスト名を指定します。 これにより、HTTP仮想ホストとまったく同じように、単一のサーバーで複数のSSLベースのサービスを個別の証明書でホストできます。 server_hostname を指定すると、 server_side がtrueの場合、ValueErrorが発生します。

バージョン2.7.9で変更: OpenSSLにSNIがない場合でも、常にserver_hostnameの受け渡しを許可します。

SSLContext.session_stats()

このコンテキストによって作成または管理されたSSLセッションに関する統計を取得します。 各情報の名前をそれらの数値にマップする辞書が返されます。 たとえば、コンテキストが作成されてからのセッションキャッシュでのヒットとミスの総数は次のとおりです。

>>> stats = context.session_stats()
>>> stats['hits'], stats['misses']
(0, 0)
SSLContext.check_hostname

ピア証明書のホスト名を SSLSocket.do_handshake()match_hostname()と一致させるかどうか。 コンテキストの verify_modeCERT_OPTIONAL または CERT_REQUIRED に設定し、 server_hostnamewrap_socket()に渡す必要があります。ホスト名と一致させるため。

例:

import socket, ssl

context = ssl.SSLContext(ssl.PROTOCOL_TLS)
context.verify_mode = ssl.CERT_REQUIRED
context.check_hostname = True
context.load_default_certs()

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ssl_sock = context.wrap_socket(s, server_hostname='www.verisign.com')
ssl_sock.connect(('www.verisign.com', 443))

ノート

この機能には、OpenSSL0.9.8f以降が必要です。

SSLContext.options

このコンテキストで有効になっているSSLオプションのセットを表す整数。 デフォルト値は OP_ALL ですが、 OP_NO_SSLv2 などの他のオプションをORで指定することもできます。

ノート

0.9.8mより古いバージョンのOpenSSLでは、オプションを設定することのみが可能であり、それらをクリアすることはできません。 (対応するビットをリセットして)オプションをクリアしようとすると、ValueErrorが発生します。

SSLContext.protocol
コンテキストを構築するときに選択されたプロトコルバージョン。 この属性は読み取り専用です。
SSLContext.verify_flags
証明書検証操作のフラグ。 VERIFY_CRL_CHECK_LEAF のようなフラグは、それらをORで結合することによって設定できます。 デフォルトでは、OpenSSLは証明書失効リスト(CRL)を要求も検証もしません。 opensslバージョン0.9.8以降でのみ使用できます。
SSLContext.verify_mode
他のピアの証明書を検証するかどうか、および検証が失敗した場合の動作方法。 この属性は、 CERT_NONECERT_OPTIONAL 、または CERT_REQUIRED のいずれかである必要があります。

17.3.4。 証明書

一般に、証明書は公開鍵/秘密鍵システムの一部です。 このシステムでは、各プリンシパル(マシン、個人、または組織の場合があります)には、一意の2つの部分からなる暗号化キーが割り当てられます。 キーの一部は公開されており、公開キーと呼ばれます。 他の部分は秘密にされ、秘密鍵と呼ばれます。 2つの部分は関連しており、一方の部分でメッセージを暗号化すると、もう一方の部分でメッセージを復号化でき、もう一方の部分でのみを復号化できます。

証明書には、2つのプリンシパルに関する情報が含まれています。 サブジェクトの名前とサブジェクトの公開鍵が含まれています。 また、2番目のプリンシパルである発行者による、サブジェクトは彼らが主張する人物であり、これは実際にサブジェクトの公開鍵であるというステートメントも含まれています。 発行者のステートメントは、発行者だけが知っている発行者の秘密鍵で署名されています。 ただし、発行者の公開鍵を見つけ、それを使用してステートメントを復号化し、証明書内の他の情報と比較することで、誰でも発行者のステートメントを検証できます。 証明書には、有効期間に関する情報も含まれています。 これは、「notBefore」と「notAfter」という2つのフィールドとして表されます。

Pythonでの証明書の使用では、クライアントまたはサーバーは証明書を使用して自分が誰であるかを証明できます。 ネットワーク接続の反対側も証明書を生成する必要があり、その証明書は、そのような検証を必要とするクライアントまたはサーバーが満足するように検証できます。 検証が失敗した場合に例外を発生させるように接続試行を設定できます。 検証は、基盤となるOpenSSLフレームワークによって自動的に行われます。 アプリケーションは、そのメカニズムに関係する必要はありません。 ただし、アプリケーションは通常、このプロセスを実行できるようにするために証明書のセットを提供する必要があります。

Pythonは、ファイルを使用して証明書を格納します。 これらは「PEM」( RFC 1422 を参照)としてフォーマットする必要があります。これは、ヘッダー行とフッター行でラップされたbase-64エンコード形式です。

-----BEGIN CERTIFICATE-----
... (certificate in base64 PEM encoding) ...
-----END CERTIFICATE-----

17.3.4.1。 証明書チェーン

証明書を含むPythonファイルには、証明書チェーンと呼ばれることもある一連の証明書を含めることができます。 このチェーンは、クライアントまたはサーバーであるプリンシパルの特定の証明書、その証明書の発行者の証明書、その証明書の発行者の証明書などで開始する必要があります。 自己署名である証明書、つまり、同じサブジェクトと発行者を持つ証明書(ルート証明書と呼ばれることもあります)に到達するまで、チェーンを上っていきます。 証明書は、証明書ファイルで連結する必要があります。 たとえば、サーバー証明書から、サーバー証明書に署名した認証局の証明書、認証局の証明書を発行した機関のルート証明書まで、3つの証明書チェーンがあるとします。

-----BEGIN CERTIFICATE-----
... (certificate for your server)...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
... (the certificate for the CA)...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
... (the root certificate for the CA's issuer)...
-----END CERTIFICATE-----

17.3.4.2。 CA証明書

接続の証明書の反対側の検証が必要な場合は、信頼できる各発行者の証明書チェーンが入った「CA証明書」ファイルを提供する必要があります。 繰り返しますが、このファイルには、これらのチェーンが連結されたものが含まれています。 検証のために、Pythonはファイル内で見つかった最初のチェーンを使用して一致します。 プラットフォームの証明書ファイルは、 SSLContext.load_default_certs()を呼び出すことで使用できます。これは、 create_default_context()で自動的に行われます。


17.3.4.3。 キーと証明書の組み合わせ

多くの場合、秘密鍵は証明書と同じファイルに保存されます。 この場合、 SSLContext.load_cert_chain()および wrap_socket()へのcertfileパラメーターのみを渡す必要があります。 秘密鍵が証明書とともに保存されている場合は、証明書チェーンの最初の証明書の前にある必要があります。

-----BEGIN RSA PRIVATE KEY-----
... (private key in base64 encoding) ...
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
... (certificate in base64 PEM encoding) ...
-----END CERTIFICATE-----

17.3.4.4。 自己署名証明書

SSL暗号化接続サービスを提供するサーバーを作成する場合は、そのサービスの証明書を取得する必要があります。 認証局から証明書を購入するなど、適切な証明書を取得する方法はたくさんあります。 もう1つの一般的な方法は、自己署名証明書を生成することです。 これを行う最も簡単な方法は、次のようなものを使用して、OpenSSLパッケージを使用することです。

% openssl req -new -x509 -days 365 -nodes -out cert.pem -keyout cert.pem
Generating a 1024 bit RSA private key
.......++++++
.............................++++++
writing new private key to 'cert.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:MyState
Locality Name (eg, city) []:Some City
Organization Name (eg, company) [Internet Widgits Pty Ltd]:My Organization, Inc.
Organizational Unit Name (eg, section) []:My Group
Common Name (eg, YOUR name) []:myserver.mygroup.myorganization.com
Email Address []:[email protected]
%

自己署名証明書の欠点は、それが独自のルート証明書であり、既知の(および信頼できる)ルート証明書のキャッシュに他の誰もそれを持たないことです。


17.3.5。 例

17.3.5.1。 SSLサポートのテスト

PythonインストールでSSLサポートが存在するかどうかをテストするには、ユーザーコードで次のイディオムを使用する必要があります。

try:
    import ssl
except ImportError:
    pass
else:
    ...  # do something that requires SSL support

17.3.5.2。 クライアント側の操作

この例では、自動証明書検証など、クライアントソケットに推奨されるセキュリティ設定を使用してSSLコンテキストを作成します。

>>> context = ssl.create_default_context()

セキュリティ設定を自分で調整したい場合は、コンテキストを最初から作成することもできます(ただし、設定が正しく行われない可能性があることに注意してください)。

>>> context = ssl.SSLContext(ssl.PROTOCOL_TLS)
>>> context.verify_mode = ssl.CERT_REQUIRED
>>> context.check_hostname = True
>>> context.load_verify_locations("/etc/ssl/certs/ca-bundle.crt")

(このスニペットは、オペレーティングシステムがすべてのCA証明書のバンドルを/etc/ssl/certs/ca-bundle.crtに配置することを前提としています。そうでない場合、エラーが発生し、場所を調整する必要があります)

コンテキストを使用してサーバーに接続すると、 CERT_REQUIRED はサーバー証明書を検証します。サーバー証明書がCA証明書のいずれかで署名されていることを確認し、署名が正しいかどうかを確認します。

>>> conn = context.wrap_socket(socket.socket(socket.AF_INET),
...                            server_hostname="www.python.org")
>>> conn.connect(("www.python.org", 443))

次に、証明書を取得できます。

>>> cert = conn.getpeercert()

目視検査は、証明書が目的のサービス(つまり、HTTPSホストwww.python.org)を識別していることを示しています。

>>> pprint.pprint(cert)
{'OCSP': ('http://ocsp.digicert.com',),
 'caIssuers': ('http://cacerts.digicert.com/DigiCertSHA2ExtendedValidationServerCA.crt',),
 'crlDistributionPoints': ('http://crl3.digicert.com/sha2-ev-server-g1.crl',
                           'http://crl4.digicert.com/sha2-ev-server-g1.crl'),
 'issuer': ((('countryName', 'US'),),
            (('organizationName', 'DigiCert Inc'),),
            (('organizationalUnitName', 'www.digicert.com'),),
            (('commonName', 'DigiCert SHA2 Extended Validation Server CA'),)),
 'notAfter': 'Sep  9 12:00:00 2016 GMT',
 'notBefore': 'Sep  5 00:00:00 2014 GMT',
 'serialNumber': '01BB6F00122B177F36CAB49CEA8B6B26',
 'subject': ((('businessCategory', 'Private Organization'),),
             (('1.3.6.1.4.1.311.60.2.1.3', 'US'),),
             (('1.3.6.1.4.1.311.60.2.1.2', 'Delaware'),),
             (('serialNumber', '3359300'),),
             (('streetAddress', '16 Allen Rd'),),
             (('postalCode', '03894-4801'),),
             (('countryName', 'US'),),
             (('stateOrProvinceName', 'NH'),),
             (('localityName', 'Wolfeboro,'),),
             (('organizationName', 'Python Software Foundation'),),
             (('commonName', 'www.python.org'),)),
 'subjectAltName': (('DNS', 'www.python.org'),
                    ('DNS', 'python.org'),
                    ('DNS', 'pypi.org'),
                    ('DNS', 'docs.python.org'),
                    ('DNS', 'testpypi.python.org'),
                    ('DNS', 'bugs.python.org'),
                    ('DNS', 'wiki.python.org'),
                    ('DNS', 'hg.python.org'),
                    ('DNS', 'mail.python.org'),
                    ('DNS', 'packaging.python.org'),
                    ('DNS', 'pythonhosted.org'),
                    ('DNS', 'www.pythonhosted.org'),
                    ('DNS', 'test.pythonhosted.org'),
                    ('DNS', 'us.pycon.org'),
                    ('DNS', 'id.python.org')),
 'version': 3}

これでSSLチャネルが確立され、証明書が検証されたので、サーバーとの通信に進むことができます。

>>> conn.sendall(b"HEAD / HTTP/1.0\r\nHost: linuxfr.org\r\n\r\n")
>>> pprint.pprint(conn.recv(1024).split(b"\r\n"))
[b'HTTP/1.1 200 OK',
 b'Date: Sat, 18 Oct 2014 18:27:20 GMT',
 b'Server: nginx',
 b'Content-Type: text/html; charset=utf-8',
 b'X-Frame-Options: SAMEORIGIN',
 b'Content-Length: 45679',
 b'Accept-Ranges: bytes',
 b'Via: 1.1 varnish',
 b'Age: 2188',
 b'X-Served-By: cache-lcy1134-LCY',
 b'X-Cache: HIT',
 b'X-Cache-Hits: 11',
 b'Vary: Cookie',
 b'Strict-Transport-Security: max-age=63072000; includeSubDomains',
 b'Connection: close',
 b'',
 b'']

以下のセキュリティに関する考慮事項の説明を参照してください。


17.3.5.3。 サーバー側の操作

サーバーの操作では、通常、サーバー証明書と秘密鍵がそれぞれファイルに含まれている必要があります。 最初に、キーと証明書を保持するコンテキストを作成して、クライアントがあなたの信頼性を確認できるようにします。 次に、ソケットを開き、それをポートにバインドし、そのソケットでlisten()を呼び出し、クライアントが接続するのを待ち始めます。

import socket, ssl

context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
context.load_cert_chain(certfile="mycertfile", keyfile="mykeyfile")

bindsocket = socket.socket()
bindsocket.bind(('myaddr.mydomain.com', 10023))
bindsocket.listen(5)

クライアントが接続するときに、ソケットでaccept()を呼び出して、もう一方の端から新しいソケットを取得し、コンテキストの SSLContext.wrap_socket()メソッドを使用してサーバー側を作成します。接続用のSSLソケット:

while True:
    newsocket, fromaddr = bindsocket.accept()
    connstream = context.wrap_socket(newsocket, server_side=True)
    try:
        deal_with_client(connstream)
    finally:
        connstream.shutdown(socket.SHUT_RDWR)
        connstream.close()

次に、connstreamからデータを読み取り、クライアントで終了するまで(または、クライアントで終了するまで)、それを使用して何かを実行します。

def deal_with_client(connstream):
    data = connstream.read()
    # null data means the client is finished with us
    while data:
        if not do_something(connstream, data):
            # we'll assume do_something returns False
            # when we're finished with client
            break
        data = connstream.read()
    # finished with client

そして、新しいクライアント接続のリッスンに戻ります(もちろん、実サーバーは各クライアント接続を別々のスレッドで処理するか、ソケットを非ブロッキングモードにしてイベントループを使用します)。


17.3.6。 ノンブロッキングソケットに関する注意事項

非ブロッキングソケットを使用する場合は、次の点に注意する必要があります。

  • select()を呼び出すと、OSレベルのソケットを読み取り(または書き込み)できることがわかりますが、SSLの上位層に十分なデータがあることを意味するわけではありません。 たとえば、SSLフレームの一部のみが到着した可能性があります。 したがって、SSLSocket.recv()およびSSLSocket.send()の障害を処理する準備ができており、 select()をもう一度呼び出してから再試行する必要があります。

  • 逆に、SSLレイヤーには独自のフレーミングがあるため、SSLソケットには、 select()が認識していなくても読み取り可能なデータが残っている可能性があります。 したがって、最初にSSLSocket.recv()を呼び出して、利用可能な可能性のあるデータをすべて排出してから、必要な場合にのみ select()呼び出しをブロックする必要があります。

    (もちろん、 poll()selectorsモジュールのプリミティブなどの他のプリミティブを使用する場合も同様の規定が適用されます)

  • SSLハンドシェイク自体は非ブロッキングになります。 SSLSocket.do_handshake()メソッドは、正常に戻るまで再試行する必要があります。 select()を使用してソケットの準備が整うのを待つ概要は次のとおりです。

    while True:
        try:
            sock.do_handshake()
            break
        except ssl.SSLWantReadError:
            select.select([sock], [], [])
        except ssl.SSLWantWriteError:
            select.select([], [sock], [])


17.3.7。 セキュリティに関する考慮事項

17.3.7.1。 最良のデフォルト

クライアント使用の場合、セキュリティポリシーに特別な要件がない場合は、 create_default_context()関数を使用してSSLコンテキストを作成することを強くお勧めします。 システムの信頼できるCA証明書をロードし、証明書の検証とホスト名のチェックを有効にして、適度に安全なプロトコルと暗号の設定を選択しようとします。

接続にクライアント証明書が必要な場合は、 SSLContext.load_cert_chain()で追加できます。

対照的に、 SSLContext コンストラクターを自分で呼び出してSSLコンテキストを作成する場合、デフォルトでは証明書の検証もホスト名のチェックも有効になりません。 その場合は、以下の段落を読んで、適切なセキュリティレベルを達成してください。


17.3.7.2。 手動設定

17.3.7.2.1。 証明書の検証

SSLContext コンストラクターを直接呼び出す場合、 CERT_NONE がデフォルトです。 他のピアを認証しないため、特にクライアントモードでは安全でない可能性があります。クライアントモードでは、ほとんどの場合、通信しているサーバーの信頼性を確保する必要があります。 したがって、クライアントモードの場合は、 CERT_REQUIRED を使用することを強くお勧めします。 ただし、それ自体では十分ではありません。 また、 SSLSocket.getpeercert()を呼び出して取得できるサーバー証明書が目的のサービスと一致することを確認する必要があります。 多くのプロトコルとアプリケーションでは、サービスはホスト名で識別できます。 この場合、 match_hostname()関数を使用できます。 この一般的なチェックは、 SSLContext.check_hostname が有効になっている場合に自動的に実行されます。

サーバーモードで、(高レベルの認証メカニズムを使用するのではなく)SSLレイヤーを使用してクライアントを認証する場合は、 CERT_REQUIRED も指定し、同様にクライアント証明書を確認する必要があります。

ノート

クライアントモードでは、匿名暗号が有効になっていない限り、 CERT_OPTIONALCERT_REQUIRED は同等です(デフォルトでは無効になっています)。


17.3.7.2.2。 プロトコルバージョン

SSLバージョン2および3は安全でないと見なされるため、使用するのは危険です。 クライアントとサーバー間の互換性を最大限に高めたい場合は、プロトコルバージョンとして PROTOCOL_SSLv23 を使用し、 SSLContext.options 属性を使用してSSLv2とSSLv3を明示的に無効にすることをお勧めします。

context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
context.options |= ssl.OP_NO_SSLv2
context.options |= ssl.OP_NO_SSLv3

上で作成されたSSLコンテキストは、TLSv1以降(システムでサポートされている場合)の接続のみを許可します。


17.3.7.2.3。 暗号の選択

高度なセキュリティ要件がある場合は、 SSLContext.set_ciphers()メソッドを使用して、SSLセッションのネゴシエーション時に有効になっている暗号を微調整できます。 Python 2.7.9以降、sslモジュールはデフォルトで特定の弱い暗号を無効にしますが、暗号の選択をさらに制限したい場合があります。 暗号リスト形式に関するOpenSSLのドキュメントを必ずお読みください。 特定の暗号リストで有効になっている暗号を確認する場合は、システムでopenssl ciphersコマンドを使用してください。


17.3.7.3。 マルチプロセッシング

このモジュールをマルチプロセスアプリケーションの一部として使用する場合(たとえば、マルチプロセッシングまたはconcurrent.futuresモジュールを使用)、OpenSSLの内部乱数ジェネレーターがフォークされたプロセスを適切に処理しないことに注意してください。 アプリケーションが os.fork()でSSL機能を使用する場合、アプリケーションは親プロセスのPRNG状態を変更する必要があります。 RAND_add()RAND_bytes()、またはRAND_pseudo_bytes()の呼び出しが成功すれば十分です。


17.3.8。 LibreSSLのサポート

LibreSSLは、OpenSSL1.0.1のフォークです。 sslモジュールはLibreSSLのサポートが制限されています。 sslモジュールがLibreSSLでコンパイルされている場合、一部の機能は使用できません。