奇葩需求

用户有个内部系统,提供基础数据,用户想在不改造改内部系统的前提下将数据文件(txt)内容进行加密,然后 copy 到我们系统

思路

思来想去只能搞一个代理服务器拦截用户的下载请求,解析内容后返回加密后文件

参考

www.cnblogs.com/yyds/p/7072…

具体实现代码

import logging;

logging.basicConfig(level=logging.INFO)
import socket, select
import _thread
from io import BytesIO
from Cryptodome.Cipher import AES

class Proxy(object):
def init(self, soc):
self.client, _ = soc.accept()
self.target = None
self.is_export = False
self.BUFSIZE = 1024
self.method = None
self.targetHost = None
self.s = None

<span class="hljs-comment"># 解析请求</span>
def getClientRequest(self):
    request = self.client.recv(self.BUFSIZE).decode()
    <span class="hljs-keyword">if</span> not request:
        <span class="hljs-built_in">return</span> None
    cn = request.find(<span class="hljs-string">'\n'</span>)
    firstLine = request[:cn]
    line = firstLine.split()
    self.method = line[0]
    self.targetHost = line[1]
    <span class="hljs-built_in">return</span> request

<span class="hljs-comment"># 拦截正常请求</span>
def commonMethod(self, request):
    tmp = self.targetHost.split(<span class="hljs-string">'/'</span>)
    logging.info(tmp)
    targetAddr = self.getTargetInfo(tmp[2])
    <span class="hljs-keyword">if</span> len(tmp) &gt; 5 and tmp[5].find(<span class="hljs-string">'export_delivery'</span>) &gt;= 0:
        self.is_export = True
    <span class="hljs-keyword">else</span>:
        self.is_export = False
    try:
        (fam, _, _, _, addr) = socket.getaddrinfo(targetAddr[0], targetAddr[1])[0]
    except Exception as e:
        <span class="hljs-built_in">print</span>(e)
        <span class="hljs-built_in">return</span>
    self.target = socket.socket(fam)
    self.target.connect(addr)
    self.target.send(request.encode())
    self.nonblocking()

def connectMethod(self, request):
    <span class="hljs-built_in">print</span>(<span class="hljs-string">'建立连接'</span>)
    pass

<span class="hljs-comment"># 启动方法</span>
def run(self):
    request = self.getClientRequest()
    <span class="hljs-keyword">if</span> request:
        <span class="hljs-keyword">if</span> self.method <span class="hljs-keyword">in</span> [<span class="hljs-string">'GET'</span>, <span class="hljs-string">'POST'</span>, <span class="hljs-string">'PUT'</span>, <span class="hljs-string">'DELETE'</span>, <span class="hljs-string">'HAVE'</span>]:
            self.commonMethod(request)
        <span class="hljs-keyword">elif</span> self.method == <span class="hljs-string">'CONNECT'</span>:
            self.connectMethod(request)

<span class="hljs-comment"># 分析数据</span>
def nonblocking(self):
    inputs = [self.client, self.target]
    break_flag = False
    <span class="hljs-keyword">if</span> (self.is_export == True):
        self.s = BytesIO()
    <span class="hljs-keyword">while</span> True:
        <span class="hljs-keyword">if</span> break_flag == True:
            <span class="hljs-built_in">break</span>
        readable, writeable, errs = select.select(inputs, [], inputs, 3)
        <span class="hljs-keyword">if</span> errs:
            <span class="hljs-built_in">print</span>(<span class="hljs-string">'nonblocking errs'</span>)
            <span class="hljs-built_in">break</span>
        <span class="hljs-keyword">for</span> soc <span class="hljs-keyword">in</span> readable:
            data = soc.recv(self.BUFSIZE)
            <span class="hljs-keyword">if</span> data:
                <span class="hljs-keyword">if</span> soc is self.client:
                    self.target.send(data)
                <span class="hljs-keyword">elif</span> soc is self.target:
                    <span class="hljs-keyword">if</span> (self.is_export == True):
                        self.s.write(data)
                    <span class="hljs-keyword">else</span>:
                        self.client.send(data)
            <span class="hljs-keyword">else</span>:
                break_flag = True
                <span class="hljs-built_in">break</span>
    <span class="hljs-keyword">if</span> (self.is_export == True):
        self.parseRequest()
    self.client.close()
    self.target.close()

<span class="hljs-comment"># 解析文件内容并加密</span>
def parseRequest(self):
    try:
        _res = self.s.getvalue().decode(<span class="hljs-string">"gb2312"</span>)
        tmp = _res.split(<span class="hljs-string">'octet-stream\r\n\r\n'</span>)
        _h = tmp[0] + <span class="hljs-string">'octet-stream\r\n\r\n'</span>
        _b = tmp[1]
        nb = BytesIO()
        nb.write(_h.encode(<span class="hljs-string">'utf8'</span>))
        secret_key = <span class="hljs-string">"ThisIs SecretKey"</span>
        iv_param = <span class="hljs-string">'This is an IV456'</span>
        aes1 = AES.new(secret_key.encode(<span class="hljs-string">"gb2312"</span>), AES.MODE_CFB, iv_param.encode(<span class="hljs-string">"gb2312"</span>))
        cipher_data = aes1.encrypt(_b.encode(<span class="hljs-string">"gb2312"</span>))
        nb.write(cipher_data)
        self.client.send(nb.getvalue())
    except Exception as e:
        <span class="hljs-built_in">print</span>(<span class="hljs-string">'Error:'</span>, e)
        self.client.send(self.s.getvalue())

def getTargetInfo(self, host):
    port = 0
    site = None
    <span class="hljs-keyword">if</span> <span class="hljs-string">':'</span> <span class="hljs-keyword">in</span> host:
        tmp = host.split(<span class="hljs-string">':'</span>)
        site = tmp[0]
        port = int(tmp[1])
    <span class="hljs-keyword">else</span>:
        site = host
        port = 80
    <span class="hljs-built_in">return</span> site, port

if name == main:
host = ‘127.0.0.1’
port = 8083
backlog = 5
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind((host, port))
server.listen(backlog)
while True:
# 多线程
# t = Process(target=Proxy(server).run)
# t.start()
# 单线程
_thread.start_new_thread(Proxy(server).run, ())

复制代码

  • python

    Python (发音:[ paiθ(ə)n; (US) paiθɔn ]n. 蟒蛇,巨蛇 ),是一种面向对象的解释性的计算机程序设计语言,也是一种功能强大而完善的通用型语言,已经具有十多年的发…

    7952 引用 • 22 回帖 • 2 关注
感谢    赞同    分享    收藏    关注    反对    举报    ...