带有HTTPServer的python3中的SSL

Ant*_*nin 9 ssl https python-3.x

我在这里找到了一个(显然)工作的HTTPS服务器for python 2:http://code.activestate.com/recipes/442473-simple-http-server-supporting-ssl-secure-communica/?c = 15536

我试图在python3中移植它,但我没有好结果.这是我的代码:

from socketserver import BaseServer
import string,cgi,time
from os import curdir, sep
from http.server import SimpleHTTPRequestHandler, HTTPServer
import ssl
import os # os. path
import socket

class SecureHTTPServer(HTTPServer):
    def __init__(self, server_address, HandlerClass):
        BaseServer.__init__(self, server_address, HandlerClass)
        ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
        #server.pem's location (containing the server private key and
        #the server certificate).
        fpem = 'certificate1.pem'
        ctx.load_verify_locations(fpem)
        self.socket = ctx.wrap_socket(socket.socket(self.address_family,
                                                        self.socket_type))
        self.server_bind()
        self.server_activate()


class SecureHTTPRequestHandler(SimpleHTTPRequestHandler):
    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)
    def do_GET(self):
        print('get recieved!');
        self.send_error(404,'File Not Found: %s' % self.path)

def test(HandlerClass = SecureHTTPRequestHandler,
         ServerClass = SecureHTTPServer):
    server_address = ('', 1443) # (address, port)
    httpd = ServerClass(server_address, HandlerClass)
    sa = httpd.socket.getsockname()
    print ("Serving HTTPS on", sa[0], "port", sa[1], "...")
    httpd.serve_forever()


if __name__ == '__main__':
    test()
Run Code Online (Sandbox Code Playgroud)

当我运行它时,我没有错误,但当我连接到localhost:1443(使用https)时,我没有得到任何响应,并且没有被print('get recieved!');触发.

Ant*_*nin 15

我在这里找到了另一个(更简单的)解决方案:http://www.piware.de/2011/01/creating-an-https-server-in-python/

这是我的工作移植到python3:

from http.server import HTTPServer,SimpleHTTPRequestHandler
from socketserver import BaseServer
import ssl

httpd = HTTPServer(('localhost', 1443), SimpleHTTPRequestHandler)
httpd.socket = ssl.wrap_socket (httpd.socket, certfile='certificate.pem', server_side=True)
httpd.serve_forever()
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,这主要适用于我,但我必须在wrap_socket调用中为我的私钥(keyfile ='private.pem')添加参数. (3认同)

Kei*_*ack 13

由于 Python 3.7 ssl.wrap_socket 已弃用,请改用 SSLContext.wrap_socket:

检查:https://docs.python.org/3.7/library/ssl.html#ssl.wrap_socket

从版本 3.10 开始:不推荐使用不带协议参数的 SSLContext。

检查:https ://docs.python.org/3.10/library/ssl.html#ssl.SSLContext

from http.server import HTTPServer,SimpleHTTPRequestHandler
import ssl

httpd = HTTPServer(('localhost', 1443), SimpleHTTPRequestHandler)
# Since version 3.10: SSLContext without protocol argument is deprecated. 
# sslctx = ssl.SSLContext()
sslctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
sslctx.check_hostname = False # If set to True, only the hostname that matches the certificate will be accepted
sslctx.load_cert_chain(certfile='certificate.pem', keyfile="private.pem")
httpd.socket = sslctx.wrap_socket(httpd.socket, server_side=True)
httpd.serve_forever()
Run Code Online (Sandbox Code Playgroud)