2011-01-05 5 views
0

私は、サーバ間でデータを交換することができるようになります一般的なサーバ・クライアントアプリケーションを作成しようとしています。 私はかなりの数のOpenSSLのドキュメント上読んだ、と私は正常にセットアップ自分のCAを持っており、テスト目的のために証明書(と秘密鍵)を作成しました。PythonのSSLソケット接続に(鍵、証明書)を配布するには何が必要ですか?

私は、Python 2.3とこだわっているので、私は、標準の「SSL」のライブラリを使用することはできません。代わりに、私はPyOpenSSLに悩まされています。これは悪くはないようですが、そこには多くの文書がありません。

私の質問は実際にそれを動作させることについてではありません。私は証明書とどこに行く必要があるかについて、より混乱しています。

サーバー:

#!/bin/env python 

from OpenSSL import SSL 
import socket 
import pickle 

def verify_cb(conn, cert, errnum, depth, ok): 
    print('Got cert: %s' % cert.get_subject()) 
    return ok 


ctx = SSL.Context(SSL.TLSv1_METHOD) 
ctx.set_verify(SSL.VERIFY_PEER|SSL.VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb) 

# ?????? 
ctx.use_privatekey_file('./Dmgr-key.pem') 
ctx.use_certificate_file('Dmgr-cert.pem') 
# ?????? 
ctx.load_verify_locations('./CAcert.pem') 

server = SSL.Connection(ctx, socket.socket(socket.AF_INET, socket.SOCK_STREAM)) 

server.bind(('', 50000)) 
server.listen(3) 

a, b = server.accept() 

c = a.recv(1024) 
print(c) 

はクライアント:

from OpenSSL import SSL 
import socket 
import pickle 


def verify_cb(conn, cert, errnum, depth, ok): 
    print('Got cert: %s' % cert.get_subject()) 
    return ok 

ctx = SSL.Context(SSL.TLSv1_METHOD) 
ctx.set_verify(SSL.VERIFY_PEER, verify_cb) 

# ?????????? 
ctx.use_privatekey_file('/home/justin/code/work/CA/private/Dmgr-key.pem') 
ctx.use_certificate_file('/home/justin/code/work/CA/Dmgr-cert.pem') 
# ????????? 
ctx.load_verify_locations('/home/justin/code/work/CA/CAcert.pem') 

sock = SSL.Connection(ctx, socket.socket(socket.AF_INET, socket.SOCK_STREAM)) 
sock.connect(('10.0.0.3', 50000)) 

a = Tester(2, 2) 
b = pickle.dumps(a) 
sock.send("Hello, world") 

sock.flush() 
sock.send(b) 
sock.shutdown() 
sock.close() 

私はいくつかが含まれているftp://ftp.pbone.net/mirror/ftp.pld-linux.org/dists/2.0/PLD/i586/PLD/RPMS/python-pyOpenSSL-examples-0.6-2.i586.rpmからこの情報を見つけました。ここ

は仕事を私の二つのプログラムですサンプルスクリプトs。

あなたが集まるかもしれませんが、私は完全に間のセクション理解していない「#を????????。」クライアントとサーバーの両方で証明書と秘密鍵が必要な理由がわかりません。私はどこに行かなければならないのか分かりませんが、鍵の一部(おそらく公開部分)だけを配布する必要はありませんか?各サーバに両方とも必要な場合は、非対称キーを使用するという目的を損なうでしょうか?

私はどちらかのボックスにPKEYまたは証明書のどちらかを削除交互に試みたが、私は関係なく、私が削除され、次のエラーを取得していない:

OpenSSL.SSL.Error: [('SSL routines', 'SSL3_READ_BYTES', 'sslv3 alert handshake failure'), ('SSL routines', 'SSL3_WRITE_BYTES', 'ssl handshake failure')]

これは、SSLのために予想される動作であれば、誰かが説明してもらえます。本当にプライベートキーと公開証明書をすべてのクライアントに配布する必要がありますか? 私は大きなセキュリティ上の問題を避けようとしています。私有鍵を漏らしてしまうと、大きな鍵になる傾向があります...

ありがとうございました!

============================================== ====================

おかげで、私は問題を把握助けるためCAFします。彼の推薦に基づいて、私はspacemanとdmgrの2つの新しい証明書ペアを作成しました。次に、クライアントプログラムに「spaceman」パーツ(キー、証明書)の両方を入れ、「dmgr」キーも同じようにします。

基本的には、クライアントの次の2行だけが変更されましたが、側にはopensslでうまく動作しました。

ctx.use_privatekey_file('/home/justin/code/work/CA/private/Dmgr-key.pem') 
ctx.use_certificate_file('/home/justin/code/work/CA/Dmgr-cert.pem') 

修正されたバージョン:SSLトランザクションに

ctx.use_privatekey_file('/home/justin/code/work/CA/private/spaceman-key.pem') 
ctx.use_certificate_file('/home/justin/code/work/CA/spacemancert.pem') 
+0

同じ(sslハンドシェイク失敗)の問題が発生しています。あなたはそれぞれのpemファイルが何であるか正確に教えてください。私はこれを持っています:1)client.keyはクライアントのちょうど秘密鍵を含んでいます。 (これは私がuse_privatekey_fileで使用しています)2)ca.crtには、=== BEGIN CERTIFICATE ===で始まり、=== ENDで終わるブロックにcaの証明書があります。クライアントの共通名、状態情報などの証明書全体...とランダムな文字の別のブロック –

答えて

4

、それぞれの側は他方の側に、その識別情報を検証するための証明書を提示することができます。これを行うには、その証明書に対応する秘密鍵が必要です。これらは2つのの異なる証明書を意図しているので、それぞれの側は2つの異なる秘密鍵を持ちます。

この証明書/秘密鍵のペアは、use_privatekey_file()use_certificate_file()を使用して設定するものです。これは、と異なる証明書/鍵ペアがサーバーとクライアント上に存在する必要があります。

ピアの証明書を検証する際に、あなたがチェックする必要があります。

  • 証明書が有効であること(つまり、あなたは、このアプリケーションのために信頼CAによって署名され、期限が切れていない、失効していません) ;
  • と思うピアに対応します。と接続しています(つまり、証明書はピアが要求するアイデンティティと一致します)。このIDは証明書のSubjectNameフィールドに格納されており、これをピアID(ユーザーのログイン名、DNS名など)にどのようにマッピングするかはアプリケーションによって異なります。
+0

ありがとうたくさんのカフェ。私はSSHキーのようなSSLを考えていました。私は、SSLの考え方全体が鍵の事前配信を必要としないことを忘れていました。ルートCAだけでした。自分の公開鍵または秘密鍵を別のサーバにコピーする必要はありませんでした。私のプログラムが以前に働いていた理由は、コンピュータ間でキーをマッチングすることとは関係なく、2つの "ベリファイ"機能でキー(パブリック、プライベート)を一致させることでした。上記の修正されたコードを参照してください。 – fandingo

関連する問題