6

サーバ:

#!/usr/bin/env python

import SocketServer
import json
from OpenSSL import SSL
import os
import socket

TERMINATION_STRING = "Done"

CERTIFICATE_PATH = os.getcwd() + '/CA/certs/01.pem'
KEY_PATH = os.getcwd() + '/CA/private/key.pem'
CA_PATH = os.getcwd() + '/CA/cacert.pem'
print CA_PATH

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

class SSLThreadingTCPServer(SocketServer.ThreadingTCPServer):
    def __init__(self, address, handler):
        SocketServer.ThreadingTCPServer.__init__(self, address, handler)

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

        ctx.use_privatekey_file(KEY_PATH)
        ctx.use_certificate_file(CERTIFICATE_PATH)
        ctx.load_verify_locations(CA_PATH)

        self.socket = SSL.Connection(ctx, socket.socket(self.address_family, self.socket_type))
        self.socket.set_accept_state()

        self.server_bind()
        self.server_activate()

        print "Serving:", address[0], "on port:", address[1]



class MemberUpdateHandler(SocketServer.StreamRequestHandler):
    def setup(self):
        self.connection = self.request
        self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
        self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)

        print self.client_address, "connected"

    def handle(self):
        data = ""
        while True:
            data += self.request.recv(1024).encode('utf-8').strip
            if data[-4:] == "Done":
                print "Done"
                break

            dataStrings = data.split(' ')
            for item in dataStrings:
                print item

if __name__ == "__main__":
    ADDRESS = 'localhost'
    PORT = 42424
    HOST = (ADDRESS, PORT)

    s = SSLThreadingTCPServer(HOST, MemberUpdateHandler)
    s.serve_forever()

クライアント:

#!/usr/bin/env python

from OpenSSL import SSL
import socket
import os

HOST = 'localhost'
PORT = 42424
ADDRESS = (HOST, PORT)

CERTIFICATE_FILE = os.getcwd() + '/CA/certs/02.pem'
KEY_PATH = os.getcwd() + '/CA/clientKey.pem'
CA_PATH = os.getcwd() + '/CA/cacert.pem'

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

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

ctx = SSL.Context(SSL.SSLv23_METHOD)
ctx.set_verify(SSL.VERIFY_PEER, verify_cb)
ctx.use_certificate_file(CERTIFICATE_FILE)
ctx.use_privatekey_file(KEY_PATH)
ctx.load_verify_locations(CA_PATH)

sslSock = SSL.Connection(ctx, sock)
sslSock.connect(ADDRESS)

items = "this is a test Done"

sslSock.sendall(items)

sslSock.close()

サーバー側のエラー:

Error: [('SSL routines', 'SSL3_GET_CLIENT_HELLO', 'no shared cipher')]

クライアント側のエラー:

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

何か簡単なものが欠けているような気がしますが、それを特定することができませんでした。いろいろな場所で私のような質問をいくつか見つけましたが、答えはありません。私はネットワークプログラミングに不慣れで、助けていただければ幸いです。

Ubuntu10.04とPython2.6を使用する

4

2 に答える 2

2

順序を次のように変更してみてください。

...
ctx.use_certificate_file(CERTIFICATE_PATH)
ctx.use_privatekey_file(KEY_PATH)
...

コードでこの順序を使用すると、サーバーの起動時に(クライアント接続ではなく)意味のある完全なエラーメッセージが表示されます。

Traceback (most recent call last):
  File "src/server_main.py", line 230, in <module>
    s = SSLClientsAuthServer()
  File "src/server_main.py", line 134, in __init__
    ctx.use_privatekey_file (self.config.value['SERVER_KEY'])
OpenSSL.SSL.Error: [('x509 certificate routines', 'X509_check_private_key', 'key values mismatch')]

これは、webserver.crtに対応しないwebserver.keyを実際に使用したためです。

$ openssl x509 -text -in certs/webserver.crt
Certificate:
Data:
    Version: 3 (0x2)
...
            Modulus:
                00:a1:b6:e3:ce:53:3d:c9:96:a6:06:1d:3e:ae:34:
....


$ openssl rsa -text -in keys/webserver.key
Private-Key: (2048 bit)
modulus:
    00:b7:34:61:d7:c7:0d:2b:5c:57:26:d0:8d:7a:04:
....

同じRSAキーを使用していることを確認してください。

于 2013-05-21T10:17:52.067 に答える
1

1つのエラーは次のとおりです。

data += self.request.recv(1024).encode('utf-8').strip

それは私を

TypeError: cannot concatenate 'str' and 'builtin_function_or_method' objects

そのはず:

data += self.request.recv(1024).encode('utf-8').strip()

その例は私のために働きます。

Got cert: <X509Name object '/C=IT/ST=XXX/L=YYY/O=ZZZ/OU=NNN/CN=CA'>
Got cert: <X509Name object '/C=IT/ST=XXX/L=YYY/O=ZZZ/OU=NNN/CN=Server'>

Stock10.04Ubuntuサーバーとapt-getからインストールされたパッケージでテストされています。

python-openssl                    0.10-1
openssl                           0.9.8k-7ubuntu8
python                            2.6.5-0ubuntu1

証明書/CAを確認するか、使用可能な暗号をリストする簡単なスクリプトを使用してサーバーをテストする必要があります:https ://superuser.com/questions/109213/is-there-a-tool-that-c​​an-test-what-ssl -tls-cipher-suites-a-particular-website-of

アップデート2:

証明書に関するいくつかの問題を除外するために、 http://acs.lbl.gov/~boverhof/openssl_certs.htmlのようにいくつかのCAおよびサーバー/クライアント証明書を生成できます。

于 2012-09-18T14:43:49.357 に答える