卡住了编程https代理 - 接下来该怎么办?

时间:2014-06-20 10:39:22

标签: python sockets ssl

我目前正在制作一个位于浏览器和网络之间的代理。一切都有效,除了https。我很难理解它的一些段落,并且没有在网上找到很多资源。所以我被困住了。

我正在使用的代码是:

conn, addr = server.accept()
request = conn.recv(9999) #get a CONNECT request
conn.send(b'HTTP/1.1 200 Connection estabilished\n\n')
enc_req = conn.recv(9999) #this gets an encrypted request
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #plaintext client 
client.connect((host, 443)) #connect to chosen host 
client.send(enc_req)
resp1 = client.recv(9999) #this gets something unreadable (encrypted?)
#could it be the certificate?

#now what?

resp1我是否拿到了证书?那之后我还需要做什么? (或者,这是相同的,https接下来会发生什么?)

P.S。我知道这个问题有些普遍,但请不要过于严厉地评价我。我尝试过在网上进行研究,但我一直在寻找的是用于ssl的加密方法。我真的不知道该怎么办。

2 个答案:

答案 0 :(得分:2)

正如评论中所提到的,处理加密的端到端流量的代理只能传递它。

这是一个使用circuits编写的完全正常工作的代理,它已通过传递和代理SSH流量进行了全面测试,因此即使涉及SSL,它也应该与传递TCP代理一样工作:

#!/usr/bin/env python

from uuid import uuid4 as uuid

from circuits import Component
from circuits.net.events import close, connect, write
from circuits.net.sockets import TCPClient, TCPServer


class Client(Component):

    channel = "client"

    def init(self, sock, host, port, channel=channel):
        self.sock = sock
        self.host = host
        self.port = port

        TCPClient(channel=self.channel).register(self)

    def ready(self, *args):
        self.fire(connect(self.host, self.port))

    def disconnect(self, *args):
        self.fire(close(self.sock), self.parent.channel)

    def read(self, data):
        self.fire(write(self.sock, data), self.parent.channel)


class Proxy(Component):

    channel = "server"

    def init(self, bind, host, port):
        self.bind = bind
        self.host = host
        self.port = port

        self.clients = dict()

        TCPServer(self.bind).register(self)

    def connect(self, sock, host, port):
        channel = uuid()

        client = Client(
            sock, self.host, self.port, channel=channel
        ).register(self)

        self.clients[sock] = client

    def disconnect(self, sock):
        client = self.clients.get(sock)
        if client is not None:
            client.unregister()
            del self.clients[sock]

    def read(self, sock, data):
        client = self.clients[sock]
        self.fire(write(data), client.channel)


app = Proxy(("0.0.0.0", 3333), "127.0.0.1", 22)

from circuits import Debugger
Debugger().register(app)

app.run()

答案 1 :(得分:2)

我没有测试过这段代码(它主要是伪代码),但是这应该会让你知道你需要做什么。

conn, addr = server.accept()
request = conn.recv(9999) #get a CONNECT request
# Here, parse the CONNECT string and get the host and port (not sure if you were doing that already.

# Then, try to connect *before* you tell the client the connection was established (in case it fails)
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #plaintext client 
client.connect((host, 443)) #connect to chosen host 

conn.send(b'HTTP/1.1 200 Connection estabilished\n\n')

# Then loop until the connections are closed.
while True:
    # Read from the client, send the data to the server.
    enc_req = conn.recv(9999) #this gets an encrypted request
    client.send(enc_req)

    # Read from the server, send the data to the client.
    resp1 = client.recv(9999) #this gets something unreadable (encrypted?)
    #could it be the certificate?
    #now what?
    # The first time it's certainly the Client Hello message, not encrypted, but in a binary format indeed.
    # Just send everything you've just read to the server.
    conn.send(resp1)

这只是您需要编写的循环概念的快速概述。实际上,您可以并行处理两者。关闭连接时你也想要更加小心(允许它以任何顺序发生,同时仍然转发任何一方发送的最后一个数据)。