0

サーバー間でデータを交換できる汎用サーバー クライアント アプリケーションを作成しようとしています。私はかなりの数の OpenSSL ドキュメントを読み、テスト目的で自分の CA を正常にセットアップし、証明書 (および秘密鍵) を作成しました。

Python 2.3 に固執しているため、標準の「ssl」ライブラリを使用できません。代わりに、私は PyOpenSSL に固執しています。これは悪くないように見えますが、それに関するドキュメントはあまりありません。

私の質問は、それを機能させることではありません。証明書と、それらがどこに行く必要があるかについて、私はもっと混乱しています。

動作する私の2つのプログラムは次のとおりです。

サーバ:

#!/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からこの情報を見つけましたこれには、いくつかのサンプル スクリプトが含まれています。

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

どちらかのボックスで pkey または cert を交互に削除しようとしましたが、どちらを削除しても次のエラーが発生します。

OpenSSL.SSL.Error: [('SSL ルーチン'、'SSL3_READ_BYTES'、'sslv3 アラート ハンドシェイクの失敗')、('SSL ルーチン'、'SSL3_WRITE_BYTES'、'ssl ハンドシェイクの失敗')]

これがSSLの予想される動作であるかどうかを誰かが説明できますか. 秘密鍵と公開証明書をすべてのクライアントに本当に配布する必要がありますか? 私は大きなセキュリティ上の問題を回避しようとしていますが、秘密鍵の漏洩は大きな問題になる傾向があります...

助けてくれてありがとう!

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

問題の解決を手伝ってくれた caf に感謝します。彼の推奨に基づいて、spaceman と dmgr という 2 つの新しい証明書ペアを作成しました。次に、両方の「spaceman」部分 (キー、証明書) をクライアント プログラムに配置し、「dmgr」キーについても同じようにします。

基本的には、Clientの次の 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')

修正版:

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

1 に答える 1

4

SSL トランザクションでは、それぞれの側が証明書を提示して、その ID を相手側に確認できます。これを行うには、その証明書に対応する秘密鍵が必要です。これらは 2 つの異なる証明書であることを意図しているため、各側には 2 つの異なる秘密鍵があります。

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

ピア証明書を確認するときは、次を確認する必要があります。

  • 証明書が有効であること (つまり、このアプリケーションに対して信頼する CA によって署名されていること、有効期限が切れていないこと、取り消されていないこと)。と
  • 接続していると思われるピアに対応します(つまり、証明書はピアが主張する ID と一致します)。この ID は証明書のフィールド内に格納され、SubjectNameこれをピア ID (ユーザー ログイン名、DNS 名など) にマップする方法はアプリケーション固有です。
于 2011-01-06T04:51:04.690 に答える