如何在asyncore中使用TLS?

4 投票
2 回答
3204 浏览
提问于 2025-04-15 12:42

一个基于asyncore的XMPP客户端会和XMPP服务器建立一个普通的TCP连接。服务器会告诉客户端,它需要一个加密的连接。接下来,客户端就需要开始一个TLS握手,这样后续的请求才能被加密。

tlslite可以和asyncore一起使用,但示例代码是给服务器用的,我不太明白它在做什么。

我用的是Python 2.5。我该如何让TLS正常工作呢?


以下是我最终成功的做法:

from tlslite.api import *

def handshakeTls(self):
    """
    Encrypt the socket using the tlslite module
    """
    self.logger.info("activating TLS encrpytion")
    self.socket = TLSConnection(self.socket)
    self.socket.handshakeClientCert()

2 个回答

4

一定要看看 twisted 和 wokkel。这两个工具让我在制作很多 xmpp 机器人和组件时,感觉简直太棒了。

2

我按照我认为的tlslite文档中的所有步骤,想让一个asyncore客户端工作——但实际上我没法让它正常运行,因为我手头唯一可以调整的asyncore客户端就是Python文档中的示例,它是一个HTTP 1.0客户端。我觉得正因为这样,我在尝试建立HTTPS连接时做得很不成熟。而且我没有asyncore的XMPP客户端,也没有任何请求TLS的XMPP服务器,所以离你的情况还远着呢。不过,我还是决定分享我的工作成果,因为(即使可能缺少某些步骤)看起来比你之前的情况要好一些——我认为我在__init__中展示了所有需要的步骤。顺便说一下,我是从tlslite/test目录复制了pem文件。

import asyncore, socket
from tlslite.api import *

s = open("./clientX509Cert.pem").read()
x509 = X509()
x509.parse(s)
certChain = X509CertChain([x509])

s = open("./clientX509Key.pem").read()
privateKey = parsePEMKey(s, private=True)


class http_client(TLSAsyncDispatcherMixIn, asyncore.dispatcher):
    ac_in_buffer_size = 16384

    def __init__(self, host, path):
        asyncore.dispatcher.__init__(self)
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.connect( (host, 80) )

        TLSAsyncDispatcherMixIn.__init__(self, self.socket)
        self.tlsConnection.ignoreAbruptClose = True
        handshaker = self.tlsConnection.handshakeClientCert(
            certChain=certChain,
            privateKey=privateKey,
            async=True)
        self.setHandshakeOp(handshaker)

        self.buffer = 'GET %s HTTP/1.0\r\n\r\n' % path

    def handle_connect(self):
        pass

    def handle_close(self):
        self.close()

    def handle_read(self):
        print self.recv(8192)

    def writable(self):
        return (len(self.buffer) > 0)

    def handle_write(self):
        sent = self.send(self.buffer)
        self.buffer = self.buffer[sent:]

c = http_client('www.readyhosting.com', '/')

asyncore.loop()

这段代码是结合了Python文档中的asyncore示例HTTP客户端,加上我从tlslite文档中学到的东西,以及从他们的源代码中反向工程得到的。希望这段代码(尽管不完整/不工作)至少能在你的探索中有所帮助……

如果我是你,我会考虑从asyncore切换到twisted——asyncore已经很老旧了,而Twisted已经集成了很多有用的功能(我给的链接是文档中已经为你集成了TLS和XMPP的部分……)。

撰写回答