我目前正在阅读Python网络编程的基础,并看到了以下示例,演示如何使用Python的ssl模块:
清单6-3:在Python3.4或更高版本中为客户端和服务器保护一个套接字
#!/usr/bin/env python3
# Foundations of Python Network Programming, Third Edition
# https://github.com/brandon-rhodes/fopnp/blob/m/py3/chapter06/safe_tls.py
# Simple TLS client and server using safe configuration defaults
import argparse, socket, ssl
def client(host, port, cafile=None):
purpose = ssl.Purpose.SERVER_AUTH
context = ssl.create_default_context(purpose, cafile=cafile)
raw_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
raw_sock.connect((host, port))
print('Connected to host {!r} and port {}'.format(host, port))
ssl_sock = context.wrap_socket(raw_sock, server_hostname=host)
while True:
data = ssl_sock.recv(1024)
if not data:
break
print(repr(data))
def server(host, port, certfile, cafile=None):
purpose = ssl.Purpose.CLIENT_AUTH
context = ssl.create_default_context(purpose, cafile=cafile)
context.load_cert_chain(certfile)
listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
listener.bind((host, port))
listener.listen(1)
print('Listening at interface {!r} and port {}'.format(host, port))
raw_sock, address = listener.accept()
print('Connection from host {!r} and port {}'.format(*address))
ssl_sock = context.wrap_socket(raw_sock, server_side=True)
ssl_sock.sendall('Simple is better than complex.'.encode('ascii'))
ssl_sock.close()
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Safe TLS client and server')
parser.add_argument('host', help='hostname or IP address')
parser.add_argument('port', type=int, help='TCP port number')
parser.add_argument('-a', metavar='cafile', default=None,
help='authority: path to CA certificate PEM file')
parser.add_argument('-s', metavar='certfile', default=None,
help='run as server: path to server PEM file')
args = parser.parse_args()
if args.s:
server(args.host, args.port, args.s, args.a)
else:
client(args.host, args.port, args.a)书中说要下载以下两个文件,即主机名“localhost”的自签名CA和第二个CA (由自签名CA签名):
因此,代码应该按以下方式运行:
但是,每当我一起运行服务器和客户端时,都会得到以下错误:
我已经尝试为主机名"localhost“生成自己的自签名CA和辅助CA (由自签名CA签名),但在运行客户机和服务器时仍然会出现相同的错误。
有人能告诉我我做错了什么吗?
谢谢。
P.S. I在Ubuntu18.04LTS上运行Python3.6.5,以防万一.
更新
我能够让上面的代码在没有二级证书的情况下工作,但是可以使用我生成的单个自签名证书,如下所示:
$ openssl req -x509 -nodes -newkey rsa:4096 -keyout localhost.key -new -out localhost.crt
$ cat localhost.crt localhost.key > localhost.pem然后,我按照上面描述的方式运行了safe_tls.py程序,除了使用localhost.crt而不是ca.crt。
尽管如此,我仍然希望能够与另一个CA签署,然后使用次要CA,正如我最初试图。任何帮助找出如何做这将是非常感谢!
发布于 2018-06-19 06:16:51
好的,所以我最终找到了我自己问题的答案,所以我会在这里发布。
我不知道在Python编程基础的公共回购中提供的ca.crt和localhost.pem文件有什么问题;但是,我成功地生成并签署了自己的CA,使它按照我最初的要求工作。
下面是我必须输入的命令:
$ # I don't know what these files are, but OpenSSL complains if they do not exist...
$ mkdir demoCA
$ touch demoCA/index.txt demoCA/index.txt.attr
$ echo '01' > demoCA/serial
$ # Create a self-signed certificate and private key.
$ openssl req -x509 -nodes -newkey rsa:4096 -keyout ca.key -new -out ca.crt
$ # Create a certificate signing request for server, "localhost", and a private key.
$ openssl req -nodes -newkey rsa:4096 -keyout localhost.key -new -out localhost.csr
$ # Sign the certificate request.
$ openssl ca -keyfile ca.key -cert ca.crt -in localhost.csr -outdir . -out localhost.crt
$ cat localhost.crt localhost.key > localhost.pem注:
对于上面执行的每个openssl req ...命令,我必须在命令行中填写一些信息(因为我没有创建配置文件)。除主机名和电子邮件外,所有信息必须在两个证书之间相同,否则最后一个命令(我们在证书请求中签名)将失败。
现在可以成功地运行服务器和客户端,如最初所示:
https://stackoverflow.com/questions/50920710
复制相似问题