web-dev-qa-db-ja.com

PythonでSSLソケット接続を開く

私はPythonでセキュアソケット接続を確立しようとしていますが、そのSSLビットに苦労しています。 SSLとの接続を確立する方法のコード例をいくつか見つけましたが、それらはすべてキーファイルに関係しています。接続しようとしているサーバーは、キーや証明書を受け取る必要はありません。私の質問は、基本的にどのようにpythonソケット接続をSSLでラップしますか。使用する暗号はADH-AES256-SHA、およびプロトコルはTLSv1。これは私が試してきたことです:

import socket
import ssl

# SET VARIABLES
packet, reply = "<packet>SOME_DATA</packet>", ""
Host, PORT = 'XX.XX.XX.XX', 4434

# CREATE SOCKET
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(10)

# WRAP SOCKET ???
ssl.wrap_socket(sock, ssl_version="TLSv1", ciphers="ADH-AES256-SHA")

# CONNECT AND PRINT REPLY
sock.connect((Host, PORT))
sock.send(packet)
print sock.recv(1280)

# CLOSE SOCKET CONNECTION
sock.close()

このコードを実行すると、エラーは表示されませんが、空の応答が返されます。端末でpythonを入力し、コードを1行ずつ貼り付けて、コマンドラインでこのコードをデバッグしようとすると、sock.send(packet)を実行しているときにステータスコードであると推測します。私が得る整数応答は26。誰もがこれが何を意味するかを知っているか、とにかく助けることができるなら、それは大歓迎です。前もって感謝します!

30
Raffi

わかりました、私は何が間違っていたかを理解しました。それは私の愚かさのようなものでした。コードにtwo問題がありました。私の最初の間違いは、ssl_version私はTLSv1あるべき時ssl.PROTOCOL_TLSv1。 2番目の間違いは、ラップされたソケットを参照せず、代わりに作成した元のソケットを呼び出していたことです。以下のコードは私にとってはうまくいくようでした。

import socket
import ssl

# SET VARIABLES
packet, reply = "<packet>SOME_DATA</packet>", ""
Host, PORT = 'XX.XX.XX.XX', 4434

# CREATE SOCKET
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(10)

# WRAP SOCKET
wrappedSocket = ssl.wrap_socket(sock, ssl_version=ssl.PROTOCOL_TLSv1, ciphers="ADH-AES256-SHA")

# CONNECT AND PRINT REPLY
wrappedSocket.connect((Host, PORT))
wrappedSocket.send(packet)
print wrappedSocket.recv(1280)

# CLOSE SOCKET CONNECTION
wrappedSocket.close()

これが誰かを助けることを願っています!

71
Raffi

PROTOCOL_TLSv1(またはTLSv1)を設定しないでください。これにより、接続がTLS v1.0のみに制限されます。代わりに、ライブラリでサポートされているすべてのバージョンをサポートするPROTOCOL_TLS(または非推奨のPROTOCOL_SSLv23)が必要です。

なんらかの理由で証明書やキーは必要ないと思うため、匿名暗号を使用しています。これは、サーバーの認証がなく、中間者攻撃に対して脆弱であることを意味します。あなたが何をしているか本当に理解していない限り、匿名暗号(ADH-AES256-SHAなど)を使用しないことをお勧めします。

5
Kurt Roeckx

これらの問題を解決するのはとても楽しいことですが、私にとっては、python sslの基盤となるインフラストラクチャはopensslです。opensslで証明書を検証してみてください。 get python同じスタックを使用するには。

リーフ証明書を検証する前に、ルート証明書をopensslにインポートする必要がありました。

これは役に立ちました。
http://gagravarr.org/writing/openssl-certs/others.shtml#ca-openssl

別の興味深い点は、異なるホスト上のpythonの同じバージョンの2つの異なるビルドが異なるメソッドを使用したことです。1つはssl.get_default_verify_paths()を使用し、もう1つはまったく使用しませんでした。ここでの教訓は、python sslがopensslで構築されていることです。基礎となるライブラリが異なると、異なるpythonが得られます。

Python SSLはopenssl上に構築されているため、最初にopensslの証明書の問題を解決します。

0